Merge upstream version
Related-PROD: PROD-28199
Change-Id: I5d9dbde1c3ac577fb30fa5d6b1ff18bcee28a0d7
diff --git a/templates/common_scripts.j2 b/templates/common_scripts.j2
new file mode 100644
index 0000000..2ea3614
--- /dev/null
+++ b/templates/common_scripts.j2
@@ -0,0 +1,56 @@
+<script language="JavaScript">
+ function toggleClassByID(pkg) {
+ var element = document.getElementById(pkg);
+ //var button = document.getElementById(pkg+"_button");
+
+ if( element.className && element.className.indexOf("in") > -1 ) {
+ element.classList.remove("in");
+ //button.innerHTML = "↑"
+ }
+ else {
+ element.classList.add("in");
+ //button.innerHTML = "↓"
+ }
+ }
+ </script>
+ <script language="JavaScript">
+ function init() {
+ // Declare all variables
+ var i, content, items;
+
+ // Get all elements with class="barcontent" and hide them
+ content = document.getElementsByClassName("barcontent");
+ for (i = 1; i < content.length; i++) {
+ content[i].style.display = "none";
+ }
+ content[0].style.display = "block";
+
+ // Get all elements with class="bar-item" and remove the class "active"
+ items = document.getElementsByClassName("bar-item");
+ for (i = 1; i < items.length; i++) {
+ items[i].className = items[i].className.replace(" active", "");
+ }
+ items[0].className += " active";
+
+ }
+ function openBar(evt, barName) {
+ // Declare all variables
+ var i, barcontent, baritems;
+
+ // Get all elements with class="barcontent" and hide them
+ barcontent = document.getElementsByClassName("barcontent");
+ for (i = 0; i < barcontent.length; i++) {
+ barcontent[i].style.display = "none";
+ }
+
+ // Get all elements with class="bar-item" and remove the class "active"
+ baritems = document.getElementsByClassName("bar-item");
+ for (i = 0; i < baritems.length; i++) {
+ baritems[i].className = baritems[i].className.replace(" active", "");
+ }
+
+ // Show the current tab, and add an "active" class to the link that opened the tab
+ document.getElementById(barName).style.display = "block";
+ evt.currentTarget.className += " active";
+ }
+ </script>
diff --git a/templates/common_styles.j2 b/templates/common_styles.j2
new file mode 100644
index 0000000..604564b
--- /dev/null
+++ b/templates/common_styles.j2
@@ -0,0 +1,95 @@
+<style>
+ body {
+ font-family: "Open Sans", Arial, Helvetica, sans-serif;
+ font-size: 90% !important;
+ }
+ h5 {padding-left: 1em; margin: 0.6em}
+ .note {font-style: italic; font-weight: normal; padding-left: 1em; margin: 0.2em; font-size: 0.7em; color: gray;}
+ /* Common */
+ .header {
+ display:block;
+ }
+
+ .label {float: left; font-size: 0.7em; color: Black; line-height: 17px; padding-left: 10px;}
+ .text {float: left; font-size: 0.8em; color: Navy; padding-left: 2px;}
+ .date {float: right;}
+
+ .smallgreytext {float: right; font-size: 0.5em; color: gray;}
+
+ /* Bar */
+ .bar{
+ background: linear-gradient(to bottom, #126666 0%, #284753 77%);
+ width:100%;
+ overflow:hidden;
+ display: inline-block;
+ }
+ .bar .bar-item{
+ padding:8px 16px;
+ float:left;
+ width:auto;
+ border:none;
+ display:block;
+ outline:0;
+ color: White;
+ background-color: transparent;
+ }
+
+ .bar .bar-item:hover {
+ background-color: #328686;
+ }
+
+ .bar .bar-item.active {
+ background-color: #328686;
+ color: white;
+ }
+
+ .collapsable {
+ visibility: collapse;
+ display: none;
+ }
+
+ .collapsable.in {
+ visibility: visible;
+ display: table-row;
+ }
+
+ table {
+ border: 0 hidden;
+ table-layout: fixed;
+ width: 100%;
+ }
+
+ .table_header {
+ background-color: #284753;
+ color: wheat;
+ text-align: center;
+ font-family: "Open Sans", Arial, Helvetica, sans-serif;
+ }
+
+ /* Tooltip container */
+ .tooltip {
+ position: relative;
+ display: inline-block;
+ border-bottom: 1px dotted black;
+ }
+
+ .tooltip .tooltiptext {
+ visibility: hidden;
+ background-color: black;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 0.5em;
+ width: auto;
+ color: #fff;
+ border-radius: 6px;
+ padding: 5px 5px;
+
+ /* Position the tooltip */
+ position: absolute;
+ z-index: 1;
+ }
+
+ .tooltip:hover .tooltiptext {
+ visibility: visible;
+ }
+
+</style>
diff --git a/templates/network_check_tmpl.j2 b/templates/network_check_tmpl.j2
index 553b554..9f0f556 100644
--- a/templates/network_check_tmpl.j2
+++ b/templates/network_check_tmpl.j2
@@ -2,207 +2,120 @@
<html lang="en">
<head>
<meta charset="UTF-8">
- <title>Model Tree Changes</title>
+ <title>Nodes and Networks report</title>
+ {% include 'common_styles.j2' %}
+ {% include 'common_scripts.j2' %}
<style>
- body {
- font-family: Verdana, Geneva, Tahoma, sans-serif;
- font-size: 90% !important;
+ table.cluster_nodes {
+ width: 90%;
+ margin-left: 5%;
+ margin-right: 5%;
}
- .dot_green {
- float: left;
- color: green;
- margin-right: 0.5em;
- margin-top: 0.2em;
- }
- .dot_red {
- float: left;
- color: red;
- margin-right: 0.5em;
- margin-top: 0.2em;
- }
- .dot_empty {
- float: left;
- color: darkgray;
- margin-right: 0.5em;
- margin-top: 0.2em;
- }
- /* Style the tab */
- .tab {
- float: left;
- width: 130px;
- border: 1px solid #fff;
- background-color: #efe;
- }
-
- /* Style the buttons that are used to open the tab content */
- .tab button {
+
+ /* Node rows*/
+ .node {
+ display: inline-block;
+ background-color: white;
+ }
+
+ tr.node > td {
display: block;
- background-color: inherit;
- color: Black;
- border: none;
- outline: none;
- font-family: "Lucida Console", Monaco, monospace;
- text-align: left;
- cursor: pointer;
- transition: 0.3s;
- font-size: 1.3em;
- width: 100%;
- padding: 1px;
- margin: 1px;
- }
-
- button > div.node_name {
float: left;
- font-size: 1.3em;
- }
-
- .smallgreytext {
- float: right;
- font-size: 0.7em;
- color: gray;
- }
-
- /* Change background color of buttons on hover */
- .tab button:hover {
- background-color: #7b7;
- }
-
- /* Create an active/current "tab button" class */
- .tab button.active {
- background-color: #8c8;
- color: white;
- }
-
- /* Style the tab content */
- .tabcontent {
- display: none;
- position: absolute;
- font-size: 1em;
- padding: 0.5em;
- right: -10%;
- top: 0%;
- transform: translateX(-12%);
- width: calc(100% - 170px);
- overflow-x: scroll;
- overflow-wrap: break-word;
- }
-
- table {
- border: 0 hidden;
- width: 100%;
- }
- tr:nth-child(even) {
- background-color: #fff;
- }
- tr:nth-child(odd) {
- background-color: #ddd;
- }
- .Header {
- background-color: #bbb;
- color: Black;
- width: 30%;
- text-align: center;
- }
- .param {
- font-size: 0.8em;
- color: #555;
- padding-left: 50px;
- padding-right: 10px;
- }
- .class_file {
- font-size: 0.8em;
- font-weight: bold;
- min-width: 300px;
- text-align: left;
+ padding: 1px;
+ padding-left: 5px;
+ padding-right: 5px;
color: black;
+ background-color: #A1BbA1;
+ text-align: center;
+ margin: 2px;
}
-
- .pkgName {
- font-size: 1em;
- padding-left: 10px;
- max-width: 800px;
+
+ .meters {
+ display: inline-block;
}
-
- .version {
- font-size: 1em;
- text-align: left;
- max-width: 400px;
- overflow-wrap: break-word;
+
+ td.meters > .meter {
+ display: block;
+ float: left;
}
-
- .differ {
- background-color: #eaa;
- }
- /* Tooltip container */
- .tooltip {
- position: relative;
- display: inline-block;
- border-bottom: 1px dotted black;
- }
-
- .tooltip .tooltiptext {
- visibility: hidden;
- background-color: black;
- font-family: "Lucida Console", Monaco, monospace;
- font-size: 0.5em;
- width: auto;
- color: #fff;
- border-radius: 6px;
- padding: 5px 5px;
-
- /* Position the tooltip */
- position: absolute;
- z-index: 1;
- }
-
- .tooltip:hover .tooltiptext {
- visibility: visible;
- }
-
</style>
- <script language="JavaScript">
- function init() {
- // Declare all variables
- var i, tabcontent, tablinks;
-
- // Get all elements with class="tabcontent" and hide them
- tabcontent = document.getElementsByClassName("tabcontent");
- for (i = 1; i < tabcontent.length; i++) {
- tabcontent[i].style.display = "none";
- }
- tabcontent[0].style.display = "block";
-
- // Get all elements with class="tablinks" and remove the class "active"
- tablinks = document.getElementsByClassName("tablinks");
- for (i = 1; i < tablinks.length; i++) {
- tablinks[i].className = tablinks[i].className.replace(" active", "");
- }
- tablinks[0].className += " active";
-
- }
- function openTab(evt, tabName) {
- // Declare all variables
- var i, tabcontent, tablinks;
-
- // Get all elements with class="tabcontent" and hide them
- tabcontent = document.getElementsByClassName("tabcontent");
- for (i = 0; i < tabcontent.length; i++) {
- tabcontent[i].style.display = "none";
- }
-
- // Get all elements with class="tablinks" and remove the class "active"
- tablinks = document.getElementsByClassName("tablinks");
- for (i = 0; i < tablinks.length; i++) {
- tablinks[i].className = tablinks[i].className.replace(" active", "");
- }
-
- // Show the current tab, and add an "active" class to the link that opened the tab
- document.getElementById(tabName).style.display = "block";
- evt.currentTarget.className += " active";
- }
- </script>
</head>
<body onload="init()">
+<div class="header">
+ <div class="label">OpenStack release:</div>
+ <div class="text">{{ openstack_release }}</div>
+ <div class="label">MCP Version:</div>
+ <div class="text">{{ mcp_release }}</div>
+ <div class="label date">generated on: {{ gen_date }}</div>
+</div>
+
+<div class="bar">
+ <button class="bar-item" onclick="openBar(event, 'nodes')">Nodes</button>
+ <button class="bar-item" onclick="openBar(event, 'networks')">Networks</button>
+ <button class="bar-item" onclick="openBar(event, 'services')">Other</button>
+</div>
+
+{% macro nodes_page(nodes, id_label) %}
+<div id="{{ id_label }}" class="barcontent">
+ <h5>{{ caller() }}</h5>
+ <hr>
+ <table class="cluster_nodes">
+ {% for node in nodes.keys() | sort %}
+ {% set _ndat = nodes[node] %}
+ <tr class="node virt">
+ <td class="status">{{ _ndat['status'] }}</td>
+ <td class="name">{{ node }}</td>
+ <td class="role">{{ _ndat['role'] }}</td>
+ <td class="vendor">QEMU</td>
+ <td class="meter cpu">vCPU: 12</td>
+ <td class="meter ram">RAM: 500GB</td>
+ <td class="meter disk">VDA: 150/140/135</td>
+ </tr>
+ {% endfor %}
+ </table>
+ <hr>
+</div>
+{% endmacro %}
+
+{% macro networks_page(networks, id_label) %}
+<div id="{{ id_label }}" class="barcontent">
+ <h5>{{ caller() }}</h5>
+ <hr>
+ <table class="networks">
+ <tr class="subnet">192.168.10.0/24</tr>
+ <tr class="net collapsable">
+ <td class="status">UP</td>
+ <td class="name">cfg01.internal.net</td>
+ <td class="ip">192.168.10.11</td>
+ <td class="param">1500</td>
+ </tr>
+ </table>
+ <hr>
+</div>
+{% endmacro %}
+
+{% macro services_page(services, id_label) %}
+<div id="{{ id_label }}" class="barcontent">
+ <h5>{{ caller() }}</h5>
+ <hr>
+</div>
+{% endmacro %}
+
+<!-- Cluster nodes page -->
+{% call nodes_page(nodes, "nodes") %}
+ Cluster nodes status and simple meterings
+{% endcall %}
+
+<!-- Cluster nodes page -->
+{% call networks_page(networks, "networks") %}
+ Networks in the cluster
+{% endcall %}
+
+<!-- Cluster nodes page -->
+{% call services_page(services, "services") %}
+ Services status in the cluster
+{% endcall %}
+
</body>
</html>
\ No newline at end of file
diff --git a/templates/pkg_versions_csv.j2 b/templates/pkg_versions_csv.j2
new file mode 100644
index 0000000..c754f63
--- /dev/null
+++ b/templates/pkg_versions_csv.j2
@@ -0,0 +1,23 @@
+{% macro package_list(pkg_dict, id_label) %}
+ {% for pkg_name in pkg_dict | get_sorted_keys %}
+ {% set p = pkg_dict[pkg_name] %}
+ {% for status in p['results'].keys() | sort(reverse=true) %}
+ {% for action in p['results'][status].keys() | sort(reverse=true) %}
+ {% for node in p['results'][status][action].keys() | sort %}
+ {% set nd = p['results'][status][action][node] %}
+{{ id_label }},{{ pkg_name }},{{ node }},{{ status | make_status_label }},{{ action | make_action_label }},{{ nd['i'].version }},{{ nd['c'].version }},{{ p['r'].version }}
+ {% endfor %}
+ {% endfor %}
+ {% endfor %}
+ {% endfor %}
+ {{ caller() }}
+{% endmacro %}
+type,package_name,node,status,action,installed,candidate,release
+{% call package_list(critical, "mirantis") %}
+{% endcall %}
+{% call package_list(system, "system") %}
+{%- endcall %}
+{% call package_list(other, "other") %}
+{%- endcall %}
+{% call package_list(unlisted, "unlisted") %}
+{%- endcall %}
diff --git a/templates/pkg_versions_html.j2 b/templates/pkg_versions_html.j2
new file mode 100644
index 0000000..d1b71bb
--- /dev/null
+++ b/templates/pkg_versions_html.j2
@@ -0,0 +1,328 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Cloud Package versions check</title>
+ {% include 'common_styles.j2' %}
+ {% include 'common_scripts.j2' %}
+ <style>
+ td.repo {width: 3em; text-align: center; font-size: 0.7em; color: #113b11; font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;}
+ td.component, td.app, td.package_name {
+ font-size: 0.75em;
+ text-align: center;
+ color: #113b11;
+ font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
+ }
+
+ td.repo {column-width: 50px;}
+ td.component {column-width: 130px;}
+ td.app {column-width: 80px;}
+ td.package_name {column-width: 200px; padding-left: 10px; text-align: left;}
+ td.node_name {column-width: 210px;}
+ td.installed {column-width: 16%;}
+ td.status_container {column-width: 200px;}
+ td.candidate {column-width: 16%;}
+ td.release {column-width: 13%;}
+
+ .status_container {
+ display: inline-block;
+ }
+
+ .status {
+ display: block;
+ float: left;
+ width: 80px;
+ padding: 1px;
+ padding-left: 5px;
+ padding-right: 5px;
+ color: white;
+ background-color: #113b11;
+ text-align: center;
+ }
+ .action {
+ display: block;
+ float: left;
+ width: 120px;
+ padding: 1px;
+ padding-left: 5px;
+ padding-right: 5px;
+ color: gray;
+ background-color: #d4dad9;
+ text-align: center;
+ }
+
+ .status_container .ok {
+ color: white;
+ background-color: #113b11;
+ }
+ .status_container .error {
+ color: white;
+ background-color: darkred;
+ }
+ .status_container .upgraded {
+ color: azure;
+ background-color: green;
+ }
+ .status_container .downgraded {
+ color: white;
+ background-color: darkolivegreen;
+ }
+
+ .status_container .needs_repo {
+ color: black;
+ background-color: #50aacc;
+ }
+
+ .status_container .needs_up {
+ color: black;
+ background-color: #aaccaa;
+ }
+
+ .status_container .needs_down {
+ color: black;
+ background-color: #ffcc48;
+ }
+
+ .status_container .possible {
+ color: gray;
+ background-color: #d4dad9;
+ }
+
+
+
+ .version {text-align: left; padding: 2px}
+ .v_epoch, .v_upstream, .v_debian, .colon, .dash {
+ color: darkslategray;
+ float: left;
+ display: block;
+ }
+
+ .ok {color: darkslategray;}
+ .error {color: white; background-color: darkred;}
+ .upgraded {color: whitesmoke; background-color: darkslategray;}
+ .downgraded {color: red;}
+
+ .smallgreytext {float: right; font-size: 0.5em; color: gray;}
+
+ /* Table specific */
+ .nodes tr:nth-child(even) {
+ background-color: #fff;
+ }
+ .nodes tr:nth-child(odd) {
+ background-color: #d4dad9;
+
+ }
+ </style>
+</head>
+<body onload="init()">
+
+<div class="header">
+ <div class="label">OpenStack release:</div>
+ <div class="text">{{ openstack_release }}</div>
+ <div class="label">MCP Version:</div>
+ <div class="text">{{ mcp_release }}</div>
+ <div class="label date">generated on: {{ gen_date }}</div>
+</div>
+
+<div class="bar">
+ <button class="bar-item" onclick="openBar(event, 'mirantis')">Mirantis</button>
+ <button class="bar-item" onclick="openBar(event, 'system')">System</button>
+ <button class="bar-item" onclick="openBar(event, 'other')">Other</button>
+ <button class="bar-item" onclick="openBar(event, 'unlisted')">Unlisted</button>
+ <button class="bar-item" onclick="openBar(event, 'legend')">Legend</button>
+</div>
+
+{% macro prettify_version(v) %}
+ <div class="version">
+ {% if v.epoch %}
+ <div class="v_epoch {{ v.epoch_status | make_status_class }}">{{ v.epoch }}</div>
+ <div class="colon">:</div>
+ {% endif %}
+ <div class="v_upstream {{ v.upstream_status | make_status_class }}">{{ v.upstream }}{{ v.upstream_rev }}</div>
+ {% if v.debian %}
+ <div class="dash">-</div>
+ <div class="v_debian {{ v.debian_status | make_status_class }}">{{ v.debian }}{{ v.debian_rev }}</div>
+ {% endif %}
+ {{ caller() }}
+ </div>
+{% endmacro %}
+
+{% macro render_package(pkg_name, dat, status_shown, action_shown, id_label) %}
+ <tr onclick="toggleClassByID('{{ id_label }}_{{ pkg_name }}_{{ status_shown }}_{{ action_shown }}')" id="{{ id_label }}_{{ pkg_name }}_{{ status_shown }}_{{ action_shown }}_button">
+ <td class="repo">{{ dat['desc']['repo'] }}</td>
+ <td class="component">{{ dat['desc']['component'] }}</td>
+ <td class="app">{{ dat['desc']['app'] }}</td>
+ <td class="package_name">{{ pkg_name }}</td>
+ <td class="status_container" colspan="3">
+ <div class="status {{ status_shown | make_status_class }}">{{ status_shown | make_status_label }}</div>
+ {% if action_shown | make_action_label %}
+ <div class="action {{ action_shown | make_action_class }}">{{ action_shown | make_action_label }}</div>
+ {% endif %}
+ </td>
+ </tr>
+ <tr class="collapsable" id="{{ id_label }}_{{ pkg_name }}_{{ status_shown }}_{{ action_shown }}"><td colspan="7">
+ <table class="nodes"><tbody>
+ {% for status in dat['results'].keys() | sort(reverse=true) %}
+ {% for action in dat['results'][status].keys() | sort(reverse=true) %}
+ {% set counter = 1 + loop.index0 %}
+ {% for node in dat['results'][status][action].keys() | sort %}
+ {% set n_counter = 1 + loop.index0 %}
+ {% set nd = dat['results'][status][action][node] %}
+ <tr>
+ <td class="repo">{{ n_counter }}</td>
+ <td class="node_name">{{ node }}</td>
+ <td class="status_container">
+ <div class="status {{ status | make_status_class }}">{{ status | make_status_label }}</div>
+ {% if action | make_action_label %}
+ <div class="action {{ action | make_action_class }}">{{ action | make_action_label }}</div>
+ {% endif %}
+ </td>
+ <td class="installed">
+ <div class="tooltip">
+ {% call prettify_version(nd['i']) %}
+ <pre class="tooltiptext">{{ nd['raw'] | linebreaks }}</pre>
+ {% endcall %}
+ </div>
+ </td>
+ <td class="candidate">{{ nd['c'].version }}</td>
+ <td class="release">{{ dat['r'].version }}</td>
+ </tr>
+ {% endfor %}
+ {% endfor %}
+ {% endfor %}
+ </tbody></table>
+ </td></tr>
+ {{ caller() }}
+{% endmacro %}
+
+{% macro package_table(pkg_dict, id_label) %}
+<div id="{{ id_label }}" class="barcontent">
+ <h5>{{ caller() }}</h5>
+ <table class="pkgversions">
+ <tbody>
+ <tr>
+ <td class="table_header" width="50px">repo</td>
+ <td class="table_header" width="130px">Component</td>
+ <td class="table_header" width="80px">App</td>
+ <td class="table_header" width="200px">Package name</td>
+ <td class="table_header">Installed</td>
+ <td class="table_header">Candidate</td>
+ <td class="table_header">Release</td>
+ </tr>
+ <!-- Print errors -->
+ <tr><td colspan="7">Errors ({{ errors[id_label] }})</td></tr>
+ {% for pkg_name in pkg_dict | get_sorted_keys %}
+ {% set dat = pkg_dict[pkg_name] %}
+ {% if status_err in dat['results'] %}
+ {% set action_to_show = dat['results'][status_err].keys() | get_max %}
+ {% call render_package(pkg_name, dat, status_err, action_to_show, id_label) %}
+ {% endcall %}
+ {% endif%}
+ {% endfor %}
+ {% if not errors[id_label] %}
+ <tr><td class="note" colspan="7">no errors found </td></tr>
+ {% endif %}
+
+ <!-- Print downgrades -->
+ <tr><td colspan="7">Downgrades ({{ downgrades[id_label] }})</td></tr>
+ {% for pkg_name in pkg_dict | get_sorted_keys %}
+ {% set dat = pkg_dict[pkg_name] %}
+ {% if status_down in dat['results'] %}
+ {% set action_to_show = dat['results'][status_down].keys() | get_max %}
+ {% call render_package(pkg_name, dat, status_down, action_to_show, id_label) %}
+ {% endcall %}
+ {% endif %}
+ {% endfor %}
+ {% if not downgrades[id_label] %}
+ <tr><td class="note" colspan="7">no downgrades found</td></tr>
+ {% endif %}
+
+ <!-- Print all other -->
+ <tr><td colspan="7">All others</td></tr>
+ {% for pkg_name in pkg_dict | get_sorted_keys %}
+ {% set dat = pkg_dict[pkg_name] %}
+ {% set status_to_show = dat['results'].keys() | get_max %}
+ {% set action_to_show = dat['results'][status_to_show].keys() | get_max %}
+ {% if status_err != status_to_show and status_down != status_to_show %}
+ {% call render_package(pkg_name, dat, status_to_show, action_to_show, id_label) %}
+ {% endcall %}
+ {% endif %}
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+{%- endmacro %}
+
+<!-- Mirantis packages which version is critical for functionality -->
+{% call package_table(critical, "mirantis") %}
+ Packages maintained and updated by Mirantis
+{% endcall %}
+
+<!-- System labeled packages-->
+{% call package_table(system, "system") %}
+ System packages which versions are critical to proper cloud function
+{%- endcall %}
+
+<!-- Other packages -->
+{% call package_table(other, "other") %}
+ Packages with no description or not critical
+{%- endcall %}
+
+{% call package_table(unlisted, "unlisted") %}
+ Packages that are not listed in version map. I.e. unexpected on the environment
+{%- endcall %}
+
+<!-- Legend -->
+<div id="legend" class="barcontent">
+ <h5>Legend: status and action explanation and possible combinations</h5>
+ <table class="pkgversions">
+ <tbody>
+ <tr><td colspan="7">Version status desctiptions</td></tr>
+ <tr>
+ <td class="status_container"><div class="status {{ cs.ok | make_status_class }}">{{ cs.ok | make_status_label }}</div></td>
+ <td>Installed and Candidate epoch:upstream version mach</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="status {{ cs.up | make_status_class }}">{{ cs.up | make_status_label }}</div></td>
+ <td>Installed version is newer that the one found in Repo (i.e. candidate) or Release notes recordset</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="status {{ cs.down | make_status_class }}">{{ cs.down | make_status_label }}</div></td>
+ <td>Installed version is older that the one found in Repo (i.e. candidate) or Release notes recordset</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="status {{ cs.err | make_status_class }}">{{ cs.err | make_status_label }}</div></td>
+ <td>Installed version conflicts with a combination of Candidate and Release notes versions</td>
+ </tr>
+ <tr><td colspan="7">Action descriptions</td></tr>
+ <tr>
+ <td class="status_container"><div class="action {{ ca.na | make_action_class }}">{{ ca.na | make_action_label }} (no action)</div></td>
+ <td>No action suggested</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="action {{ ca.up | make_action_class }}">{{ ca.up | make_action_label }}</div></td>
+ <td>There is an upgrade possible for the package. But it is not strictly required action.</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="action {{ ca.need_up | make_action_class }}">{{ ca.need_up | make_action_label }}</div></td>
+ <td>Package should be upgraded to match version either in repo or in Release notes</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="action {{ ca.need_down | make_action_class }}">{{ ca.need_down | make_action_label }}</div></td>
+ <td>Package should be downgraded to match version either in repo or in Release notes</td>
+ </tr>
+ <tr>
+ <td class="status_container"><div class="action {{ ca.repo | make_action_class }}">{{ ca.repo | make_action_label }}</div></td>
+ <td>Repo that is configured on the target node contains invalid version and should be updated</td>
+ </tr>
+ <tr><td colspan="7">Versions status and Action combinations</td></tr>
+ <tr>
+ <td class="status_container">
+ <div class="status {{ cs.err | make_status_class }}">{{ cs.err | make_status_label }}</div>
+ <div class="action {{ ca.repo | make_action_class }}">{{ ca.repo | make_action_label }}</div>
+ </td>
+ </tr>
+ </tbody></table>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/templates/pkg_versions_tmpl.j2 b/templates/pkg_versions_tmpl.j2
deleted file mode 100644
index b03e2ef..0000000
--- a/templates/pkg_versions_tmpl.j2
+++ /dev/null
@@ -1,327 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title>Cloud Package versions check</title>
- <style>
- body {
- font-family: Verdana, Geneva, Tahoma, sans-serif;
- font-size: 90% !important;
- }
- .dot_green {
- float: left;
- color: green;
- margin-right: 0.5em;
- margin-top: 0.2em;
- }
- .dot_red {
- float: left;
- color: red;
- margin-right: 0.5em;
- margin-top: 0.2em;
- }
- .dot_empty {
- float: left;
- color: darkgray;
- margin-right: 0.5em;
- margin-top: 0.2em;
- }
- /* Style the tab */
- .tab {
- float: left;
- width: 130px;
- border: 1px solid #fff;
- background-color: #efe;
- }
-
- /* Style the buttons that are used to open the tab content */
- .tab button {
- display: block;
- background-color: inherit;
- color: Black;
- border: none;
- outline: none;
- font-family: "Lucida Console", Monaco, monospace;
- text-align: left;
- cursor: pointer;
- transition: 0.3s;
- font-size: 1.1em;
- width: 100%;
- padding: 1px;
- margin: 1px;
- }
-
- button > div.node_name {
- float: left;
- font-size: 0.8em;
- }
-
- .smallgreytext {
- float: right;
- font-size: 0.5em;
- color: gray;
- }
-
- /* Change background color of buttons on hover */
- .tab button:hover {
- background-color: #7b7;
- }
-
- /* Create an active/current "tab button" class */
- .tab button.active {
- background-color: #8c8;
- color: white;
- }
-
- /* Style the tab content */
- .tabcontent {
- display: none;
- position: absolute;
- font-size: 1em;
- padding: 0.5em;
- right: -10%;
- top: 0%;
- transform: translateX(-12%);
- width: calc(100% - 170px);
- overflow-x: scroll;
- overflow-wrap: break-word;
- }
- .collapsable {
- visibility: collapse;
- display: none;
- }
-
- .collapsable.in {
- visibility: visible;
- display: table-row;
- }
-
- table {
- border: 0 hidden;
- width: 100%;
- }
- tr:nth-child(even) {
- background-color: #fff;
- }
- tr:nth-child(odd) {
- background-color: #ddd;
- }
- .Header {
- background-color: #bbb;
- color: Black;
- width: 30%;
- text-align: center;
- }
- .pkgName {
- font-size: 1em;
- padding-left: 10px;
- }
-
- .version {
- font-size: 1.1em;
- text-align: left;
- }
-
- .differ {
- background-color: #eaa;
- }
- /* Tooltip container */
- .tooltip {
- position: relative;
- display: inline-block;
- border-bottom: 1px dotted black;
- }
-
- .tooltip .tooltiptext {
- visibility: hidden;
- background-color: black;
- font-family: "Lucida Console", Monaco, monospace;
- font-size: 0.5em;
- width: auto;
- color: #fff;
- border-radius: 6px;
- padding: 5px 5px;
-
- /* Position the tooltip */
- position: absolute;
- z-index: 1;
- }
-
- .tooltip:hover .tooltiptext {
- visibility: visible;
- }
-
- </style>
- <script language="JavaScript">
- function toggleClassByID(pkg, number) {
- var elements = document.querySelectorAll("#"+pkg+"_"+number);
- var ii = elements.length;
- var button = document.querySelector("#"+pkg+"_button"+number);
-
- while (ii--) {
- if( elements[ii].className && elements[ii].className.indexOf("in") > -1 ) {
- elements[ii].classList.remove("in");
- button.innerHTML = "↑"
- }
- else {
- elements[ii].classList.add("in");
- button.innerHTML = "↓"
- }
- }
-
-
- }
- </script>
- <script language="JavaScript">
- function init() {
- // Declare all variables
- var i, tabcontent, tablinks;
-
- // Get all elements with class="tabcontent" and hide them
- tabcontent = document.getElementsByClassName("tabcontent");
- for (i = 1; i < tabcontent.length; i++) {
- tabcontent[i].style.display = "none";
- }
- tabcontent[0].style.display = "block";
-
- // Get all elements with class="tablinks" and remove the class "active"
- tablinks = document.getElementsByClassName("tablinks");
- for (i = 1; i < tablinks.length; i++) {
- tablinks[i].className = tablinks[i].className.replace(" active", "");
- }
- tablinks[0].className += " active";
-
- }
- function openTab(evt, tabName) {
- // Declare all variables
- var i, tabcontent, tablinks;
-
- // Get all elements with class="tabcontent" and hide them
- tabcontent = document.getElementsByClassName("tabcontent");
- for (i = 0; i < tabcontent.length; i++) {
- tabcontent[i].style.display = "none";
- }
-
- // Get all elements with class="tablinks" and remove the class "active"
- tablinks = document.getElementsByClassName("tablinks");
- for (i = 0; i < tablinks.length; i++) {
- tablinks[i].className = tablinks[i].className.replace(" active", "");
- }
-
- // Show the current tab, and add an "active" class to the link that opened the tab
- document.getElementById(tabName).style.display = "block";
- evt.currentTarget.className += " active";
- }
- </script>
-</head>
-<body onload="init()">
-<div class="tab">
- <button class="tablinks" onclick="openTab(event, 'All Diffs')")>
- <div class="node_name">All Diffs</div>
- </button>
-{% for node_name in nodes.keys() | sort %}
- {% if counters[node_name]['package_diff'] %}
- <button class="tablinks" onclick="openTab(event, '{{ node_name | shortname }}')">
- <div class="dot_green">●</div>
- <div class="node_name">{{ node_name | shortname }}</div>
- <div class="smallgreytext">({{ counters[node_name]['package_diff'] }} / {{ counters[node_name]['packages'] }})</div>
- </button>
- {% endif %}
-{% endfor %}
-{% for node_name in nodes.keys() | sort %}
- {% if not counters[node_name]['package_diff'] %}
- <button class="tablinks" onclick="openTab(event, '{{ node_name | shortname }}')">
- <div class="dot_empty">○</div>
- <div class="node_name">{{ node_name | shortname }}</div>
- <div class="smallgreytext">({{ counters[node_name]['package_diff'] }} / {{ counters[node_name]['packages'] }})</div>
- </button>
- {% endif %}
-{% endfor %}
-</div>
-<div id="All Diffs" class="tabcontent">
- <table class="pkgversions">
- <tbody>
- <tr>
- <td class="Header">Node name</td>
- <td class="Header">Installed</td>
- <td class="Header">Candidate</td>
- </tr>
- {% for pkg_name in pkg_diffs.keys() | sort %}
- {% if counters[pkg_name]['df_nodes'] %}
- {% set pkg_counter = 1 + loop.index0 %}
- <tr>
- <td>
- <a href="#" onclick="toggleClassByID('{{ pkg_name }}', '{{ pkg_counter }}')" id="{{ pkg_name }}_button{{ pkg_counter }}">↑</a>
- {{ pkg_name }}
- </td>
- <td>{{ counters[pkg_name]['df_nodes'] }}</td>
- <td></td>
- </tr>
- <tr><td colspan=3>
- <table class="nodes"><tbody>
- {% for node in pkg_diffs[pkg_name]['df_nodes'].keys() | sort %}
- <tr class="collapsable" id="{{ pkg_name }}_{{ pkg_counter }}">
- <td class="pkgName">{{ node }}</td>
- <td class="version differ">
- <div class="tooltip">{{ pkg_diffs[pkg_name]['df_nodes'][node]['i'] }}
- <pre class="tooltiptext">{{ pkg_diffs[pkg_name]['df_nodes'][node]['raw'] | linebreaks }}</pre>
- </div>
- </td>
- <td class="version">{{ pkg_diffs[pkg_name]['df_nodes'][node]['c'] }}</td>
- </tr>
- {% endfor %}
- </tbody></table>
- </td></tr>
- {% endif%}
- {% endfor %}
- </tbody>
- </table>
-</div>
-{% for node_name in nodes.keys() | sort %}
-<div id="{{ node_name | shortname }}" class="tabcontent">
- <table class="pkgversions">
- <tbody>
- <tr>
- <td class="Header">Package name</td>
- <td class="Header">Installed</td>
- <td class="Header">Candidate</td>
- </tr>
- <tr><td colspan=3>Package with different versions uniq for this node</td></tr>
- {% for package_name in nodes[node_name]['packages'] | sort %}
- {% if not nodes[node_name]['packages'][package_name]['is_equal'] %}
- {% if nodes[node_name]['packages'][package_name]['fail_uniq'] %}
- <tr>
- <td class="pkgName">{{ package_name }}</td>
- <td class="version differ">
- <div class="tooltip">{{ nodes[node_name]['packages'][package_name]['installed'] }}
- <pre class="tooltiptext">{{ nodes[node_name]['packages'][package_name]['raw'] | linebreaks }}</pre>
- </div>
- </td>
- <td class="version">{{ nodes[node_name]['packages'][package_name]['candidate'] }}</td>
- </tr>
- {% endif %}
- {% endif %}
- {% endfor %}
- <tr><td colspan=3>Packages with different versions on nodes with similar role</td></tr>
- {% for package_name in nodes[node_name]['packages'] | sort %}
- {% if not nodes[node_name]['packages'][package_name]['is_equal'] %}
- {% if not nodes[node_name]['packages'][package_name]['fail_uniq'] %}
- <tr>
- <td class="pkgName">{{ package_name }}</td>
- <td class="version differ">
- <div class="tooltip">{{ nodes[node_name]['packages'][package_name]['installed'] }}
- <pre class="tooltiptext">{{ nodes[node_name]['packages'][package_name]['raw'] | linebreaks }}</pre>
- </div>
- </td>
- <td class="version">{{ nodes[node_name]['packages'][package_name]['candidate'] }}</td>
- </tr>
- {% endif %}
- {% endif %}
- {% endfor %}
- <tr><td colspan=3>Packages with same versions (installed vs candidate): {{ counters[node_name]['package_eq'] }}</td></tr>
- </tbody>
- </table>
-</div>
-{% endfor %}
-</body>
-</html>
\ No newline at end of file