Packages report updates
- All Errors are warnings by default
- If package version differs across nodes
warning becomes error
Change-Id: I1e6d338cfae252cc5d8ee6ededdd757ec070eb2c
Related-PROD: PROD-38972
diff --git a/cfg_checker/common/const.py b/cfg_checker/common/const.py
index 5826f43..9e5fea2 100644
--- a/cfg_checker/common/const.py
+++ b/cfg_checker/common/const.py
@@ -15,6 +15,7 @@
VERSION_OK = next(_cnt)
VERSION_UP = next(_cnt)
VERSION_DOWN = next(_cnt)
+VERSION_WARN = next(_cnt)
VERSION_ERR = next(_cnt)
# action const order is important!
@@ -39,6 +40,7 @@
VERSION_OK: "ok",
VERSION_UP: "upgraded",
VERSION_DOWN: "downgraded",
+ VERSION_WARN: "warning",
VERSION_ERR: "error",
VERSION_NA: "no status"
}
@@ -65,6 +67,8 @@
"mon": "monitoring",
"msg": "messaging",
"mtr": "stacklight_metering",
+ "ntw": "contrail_networking",
+ "nal": "contrail_analytics",
"osd": "storage_node",
"prx": "proxy",
"rgw": "storage_rados",
diff --git a/cfg_checker/common/other.py b/cfg_checker/common/other.py
index 2620d05..c5ad7c8 100644
--- a/cfg_checker/common/other.py
+++ b/cfg_checker/common/other.py
@@ -20,6 +20,35 @@
return _ps
+def merge_dict(source, destination):
+ """
+ Dict merger, thanks to vincent
+ http://stackoverflow.com/questions/20656135/python-deep-merge-dictionary-data
+
+ >>> a = { 'first' : { 'all_rows' : { 'pass' : 'dog', 'number' : '1' } } }
+ >>> b = { 'first' : { 'all_rows' : { 'fail' : 'cat', 'number' : '5' } } }
+ >>> merge(b, a) == {
+ 'first': {
+ 'all_rows': {
+ 'pass': 'dog',
+ 'fail': 'cat',
+ 'number': '5'
+ }
+ }
+ }
+ True
+ """
+ for key, value in source.items():
+ if isinstance(value, dict):
+ # get node or create one
+ node = destination.setdefault(key, {})
+ merge_dict(value, node)
+ else:
+ destination[key] = value
+
+ return destination
+
+
class Utils(object):
@staticmethod
def validate_name(fqdn, message=False):
diff --git a/cfg_checker/modules/packages/checker.py b/cfg_checker/modules/packages/checker.py
index 631c992..92d9e1c 100644
--- a/cfg_checker/modules/packages/checker.py
+++ b/cfg_checker/modules/packages/checker.py
@@ -2,6 +2,7 @@
from cfg_checker.common import const, logger_cli
from cfg_checker.common.exception import ConfigException
+from cfg_checker.common.other import merge_dict
from cfg_checker.helpers.console_utils import Progress
from cfg_checker.modules.packages.repos import RepoManager
from cfg_checker.nodes import salt_master
@@ -42,6 +43,7 @@
"ok": const.VERSION_OK,
"up": const.VERSION_UP,
"down": const.VERSION_DOWN,
+ "warn": const.VERSION_WARN,
"err": const.VERSION_ERR
},
"ca": {
@@ -53,6 +55,7 @@
}
}
_data['status_err'] = const.VERSION_ERR
+ _data['status_warn'] = const.VERSION_WARN
_data['status_down'] = const.VERSION_DOWN
# Presort packages
@@ -66,6 +69,7 @@
_progress_index = 0
# counters
_ec = _es = _eo = _eu = 0
+ _wc = _ws = _wo = _wu = 0
_dc = _ds = _do = _du = 0
while _progress_index < _l:
# progress bar
@@ -86,12 +90,43 @@
# ...just skip it from report
continue
+ _differ = len(set(_val['results'].keys())) > 1
+ if _differ:
+ # in case package has different status across nodes
+ # Warning becomes Error.
+ if const.VERSION_WARN in _val['results']:
+ if const.VERSION_ERR in _val['results']:
+ # add warns to err
+ # should never happen, though
+ merge_dict(
+ _val['results'].pop(const.VERSION_WARN),
+ _val['results'][const.VERSION_ERR]
+ )
+ else:
+ _val['results'][const.VERSION_ERR] = \
+ _val['results'].pop(const.VERSION_WARN)
+ else:
+ # in case package has same status on all nodes
+ # Error becomes Warning
+ if const.VERSION_ERR in _val['results']:
+ if const.VERSION_WARN in _val['results']:
+ # add warns to err
+ # should never happen, though
+ merge_dict(
+ _val['results'].pop(const.VERSION_ERR),
+ _val['results'][const.VERSION_WARN]
+ )
+ else:
+ _val['results'][const.VERSION_WARN] = \
+ _val['results'].pop(const.VERSION_ERR)
+
if len(_c) > 0 and _val['is_mirantis'] is None:
# not listed package in version lib
_data['unlisted'].update({
_pn: _val
})
_eu += _val['results'].keys().count(const.VERSION_ERR)
+ _wu += _val['results'].keys().count(const.VERSION_WARN)
_du += _val['results'].keys().count(const.VERSION_DOWN)
# mirantis/critical
# elif len(_c) > 0 and _c != 'System':
@@ -101,6 +136,7 @@
_pn: _val
})
_ec += _val['results'].keys().count(const.VERSION_ERR)
+ _wc += _val['results'].keys().count(const.VERSION_WARN)
_dc += _val['results'].keys().count(const.VERSION_DOWN)
# system
elif _c == 'System':
@@ -108,6 +144,7 @@
_pn: _val
})
_es += _val['results'].keys().count(const.VERSION_ERR)
+ _ws += _val['results'].keys().count(const.VERSION_WARN)
_ds += _val['results'].keys().count(const.VERSION_DOWN)
# rest
else:
@@ -115,6 +152,7 @@
_pn: _val
})
_eo += _val['results'].keys().count(const.VERSION_ERR)
+ _wo += _val['results'].keys().count(const.VERSION_WARN)
_do += _val['results'].keys().count(const.VERSION_DOWN)
_progress.end()
@@ -125,6 +163,12 @@
'other': _eo,
'unlisted': _eu
}
+ _data['warnings'] = {
+ 'mirantis': _wc,
+ 'system': _ws,
+ 'other': _wo,
+ 'unlisted': _wu
+ }
_data['downgrades'] = {
'mirantis': _dc,
'system': _ds,
diff --git a/cfg_checker/modules/packages/versions.py b/cfg_checker/modules/packages/versions.py
index e16dab8..7fae9fc 100644
--- a/cfg_checker/modules/packages/versions.py
+++ b/cfg_checker/modules/packages/versions.py
@@ -303,17 +303,17 @@
self.action = const.ACT_UPGRADE
elif i < r and r < c:
# installed version is older vs release version
- self.status = const.VERSION_ERR
+ self.status = const.VERSION_WARN
self.action = const.ACT_NEED_UP
self.target = r
elif i < r and c == r:
# installed version is older vs release version
- self.status = const.VERSION_ERR
+ self.status = const.VERSION_WARN
self.action = const.ACT_NEED_UP
self.target = c
elif c < r:
# installed and repo versions older vs release version
- self.status = const.VERSION_ERR
+ self.status = const.VERSION_WARN
self.action = const.ACT_REPO
# I > C
# installed version is newer
@@ -321,7 +321,7 @@
self.target = c
if c == r:
# some unknown version installed
- self.status = const.VERSION_ERR
+ self.status = const.VERSION_WARN
self.action = const.ACT_NEED_DOWN
elif c > r:
# installed and repo versions newer than release
diff --git a/cfg_checker/reports/reporter.py b/cfg_checker/reports/reporter.py
index 40f2c59..2a38bd2 100644
--- a/cfg_checker/reports/reporter.py
+++ b/cfg_checker/reports/reporter.py
@@ -81,6 +81,7 @@
const.VERSION_OK: "OK",
const.VERSION_UP: "Upgraded",
const.VERSION_DOWN: "Downgraded",
+ const.VERSION_WARN: "WARNING",
const.VERSION_ERR: "ERROR",
const.VERSION_NA: "N/A"
}
diff --git a/templates/pkg_versions_html.j2 b/templates/pkg_versions_html.j2
index aaedcbc..736146b 100644
--- a/templates/pkg_versions_html.j2
+++ b/templates/pkg_versions_html.j2
@@ -106,10 +106,12 @@
.ok {color: darkslategray;}
.error {color: white; background-color: darkred;}
+ .warning {color: black; background-color: lightgoldenrodyellow;}
.upgraded {color: whitesmoke; background-color: darkslategray;}
.downgraded {color: red;}
.smallgreytext {float: right; font-size: 0.5em; color: gray;}
+ .tooltiptext { top: 120%; }
/* Table specific */
.nodes tr:nth-child(even) {
@@ -235,6 +237,20 @@
<tr><td class="note" colspan="7">no errors found </td></tr>
{% endif %}
+ <!-- Print warnings -->
+ <tr><td colspan="7">Warnings ({{ warnings[id_label] }})</td></tr>
+ {% for pkg_name in pkg_dict | get_sorted_keys %}
+ {% set dat = pkg_dict[pkg_name] %}
+ {% if status_warn in dat['results'] %}
+ {% set action_to_show = dat['results'][status_warn].keys() | get_max %}
+ {% call render_package(pkg_name, dat, status_warn, action_to_show, id_label) %}
+ {% endcall %}
+ {% endif%}
+ {% endfor %}
+ {% if not warnings[id_label] %}
+ <tr><td class="note" colspan="7">no warnings 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 %}