Merge "Fuel version from cluster used in OSWL reports"
This commit is contained in:
commit
019ef0c6e7
|
@ -179,6 +179,7 @@ def get_oswls_query(resource_type, from_date=None, to_date=None):
|
||||||
IS.creation_date.label('installation_created_date'),
|
IS.creation_date.label('installation_created_date'),
|
||||||
IS.modification_date.label('installation_updated_date'),
|
IS.modification_date.label('installation_updated_date'),
|
||||||
IS.structure['fuel_release'].label('fuel_release_from_inst_info'),
|
IS.structure['fuel_release'].label('fuel_release_from_inst_info'),
|
||||||
|
IS.structure['clusters'].label('clusters'),
|
||||||
IS.is_filtered).\
|
IS.is_filtered).\
|
||||||
join(IS, IS.master_node_uid == OSWS.master_node_uid).\
|
join(IS, IS.master_node_uid == OSWS.master_node_uid).\
|
||||||
filter(OSWS.resource_type == resource_type).\
|
filter(OSWS.resource_type == resource_type).\
|
||||||
|
|
|
@ -95,25 +95,69 @@ class OswlStatsToCsv(object):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def handle_empty_version_info(self, oswl):
|
def _add_oswl_to_clusters_versions_cache(self, oswl, clusters_versions):
|
||||||
|
"""Adds oswl clusters info into clusters_versions cache.
|
||||||
|
|
||||||
|
:param oswl: OSWL DB object
|
||||||
|
:type oswl: fuel_analytics.api.db.model.OpenStackWorkloadStats
|
||||||
|
:param clusters_versions: cache for saving cluster versions with
|
||||||
|
structure {mn_uid: {cluster_id: fuel_release}}
|
||||||
|
:type clusters_versions: dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
mn_uid = oswl.master_node_uid
|
||||||
|
|
||||||
|
# Result of csv_exporter.get_oswls_query contains info about all
|
||||||
|
# clusters in the installation. Thus we need to add clusters data
|
||||||
|
# into the cache only once for specified master_node_uid.
|
||||||
|
if mn_uid in clusters_versions:
|
||||||
|
return
|
||||||
|
|
||||||
|
if oswl.clusters is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
clusters_versions[mn_uid] = {}
|
||||||
|
|
||||||
|
for cluster in oswl.clusters:
|
||||||
|
fuel_release = cluster.get('fuel_release')
|
||||||
|
if fuel_release:
|
||||||
|
clusters_versions[mn_uid][cluster['id']] = fuel_release
|
||||||
|
|
||||||
|
def handle_empty_version_info(self, oswl, clusters_versions):
|
||||||
"""Handles empty version info in oswl object
|
"""Handles empty version info in oswl object
|
||||||
|
|
||||||
For OSWLs with empty version_info data we compose version_info
|
For OSWLs with empty version_info data we compose version_info
|
||||||
from InstallationStructure data and assign it to oswl object.
|
from InstallationStructure data and assign it to oswl object.
|
||||||
If we extract OpenStack release, os, name from
|
We bound InstallationStructure.structure.clusters to the oswl
|
||||||
InstallationStructure.structure.clusters we have performance
|
and extract fuel_release from clusters data. If fuel_release
|
||||||
degradation on fetching all clusters data in csv_exporter.get_oswls
|
info doesn't provided by clusters data then
|
||||||
thus only fuel_release will be used in case of empty version_info.
|
InstallationStructure.structure.fuel_release is used.
|
||||||
|
|
||||||
:param oswl: OSWL DB object
|
:param oswl: OSWL DB object
|
||||||
:type oswl: fuel_analytics.api.db.model.OpenStackWorkloadStats
|
:type oswl: fuel_analytics.api.db.model.OpenStackWorkloadStats
|
||||||
|
:param clusters_versions: cache for saving cluster versions with
|
||||||
|
structure {mn_uid: {cluster_id: fuel_release}}
|
||||||
|
:type clusters_versions: dict
|
||||||
"""
|
"""
|
||||||
if oswl.version_info:
|
if oswl.version_info:
|
||||||
return
|
return
|
||||||
|
|
||||||
fuel_release = oswl.fuel_release_from_inst_info or {}
|
self._add_oswl_to_clusters_versions_cache(oswl, clusters_versions)
|
||||||
|
|
||||||
|
mn_uid = oswl.master_node_uid
|
||||||
|
cluster_id = oswl.cluster_id
|
||||||
|
|
||||||
|
# Fetching fuel_release info from cache
|
||||||
|
fuel_release = clusters_versions.get(mn_uid, {}).get(cluster_id)
|
||||||
|
|
||||||
|
# If clusters data doesn't contain fuel_release info we are using
|
||||||
|
# info from installation info
|
||||||
|
if fuel_release is None:
|
||||||
|
fuel_release = oswl.fuel_release_from_inst_info or {}
|
||||||
|
fuel_release = fuel_release.get('release')
|
||||||
|
|
||||||
oswl.version_info = {
|
oswl.version_info = {
|
||||||
'fuel_release': fuel_release.get('release')
|
'fuel_release': fuel_release
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_flatten_resources(self, resource_type, oswl_keys_paths,
|
def get_flatten_resources(self, resource_type, oswl_keys_paths,
|
||||||
|
@ -126,9 +170,15 @@ class OswlStatsToCsv(object):
|
||||||
:return: generator on flatten resources info collection
|
:return: generator on flatten resources info collection
|
||||||
"""
|
"""
|
||||||
app.logger.debug("Getting OSWL flatten %s info started", resource_type)
|
app.logger.debug("Getting OSWL flatten %s info started", resource_type)
|
||||||
|
|
||||||
|
# Cache for saving cluster versions. Cache is used only if version_info
|
||||||
|
# is not provided in the oswl.
|
||||||
|
# Structure: {mn_uid: {cluster_id: fuel_release}}
|
||||||
|
clusters_versions = {}
|
||||||
|
|
||||||
for oswl in oswls:
|
for oswl in oswls:
|
||||||
try:
|
try:
|
||||||
self.handle_empty_version_info(oswl)
|
self.handle_empty_version_info(oswl, clusters_versions)
|
||||||
flatten_oswl = export_utils.get_flatten_data(oswl_keys_paths,
|
flatten_oswl = export_utils.get_flatten_data(oswl_keys_paths,
|
||||||
oswl)
|
oswl)
|
||||||
resource_data = oswl.resource_data
|
resource_data = oswl.resource_data
|
||||||
|
|
|
@ -86,9 +86,8 @@ class StatsToCsv(object):
|
||||||
|
|
||||||
plugin_key_paths = export_utils.get_keys_paths(plugin_skeleton)
|
plugin_key_paths = export_utils.get_keys_paths(plugin_skeleton)
|
||||||
structure_key_paths = [['master_node_uid'],
|
structure_key_paths = [['master_node_uid'],
|
||||||
['structure', 'fuel_packages'],
|
['structure', 'fuel_packages']]
|
||||||
['structure', 'fuel_release', 'release']]
|
cluster_key_paths = [['cluster_id'], ['cluster_fuel_version']]
|
||||||
cluster_key_paths = [['cluster_id']]
|
|
||||||
result_key_paths = plugin_key_paths + cluster_key_paths + \
|
result_key_paths = plugin_key_paths + cluster_key_paths + \
|
||||||
structure_key_paths
|
structure_key_paths
|
||||||
app.logger.debug("Plugin keys paths got")
|
app.logger.debug("Plugin keys paths got")
|
||||||
|
@ -202,6 +201,8 @@ class StatsToCsv(object):
|
||||||
|
|
||||||
for cluster in clusters:
|
for cluster in clusters:
|
||||||
cluster['cluster_id'] = cluster['id']
|
cluster['cluster_id'] = cluster['id']
|
||||||
|
cluster['cluster_fuel_version'] = \
|
||||||
|
cluster.get('fuel_version')
|
||||||
flatten_cluster = export_utils.get_flatten_data(
|
flatten_cluster = export_utils.get_flatten_data(
|
||||||
cluster_keys_paths, cluster)
|
cluster_keys_paths, cluster)
|
||||||
plugins = cluster.pop('installed_plugins', [])
|
plugins = cluster.pop('installed_plugins', [])
|
||||||
|
|
|
@ -28,6 +28,7 @@ from fuel_analytics.test.base import DbTest
|
||||||
from fuel_analytics.api.app import app
|
from fuel_analytics.api.app import app
|
||||||
from fuel_analytics.api.app import db
|
from fuel_analytics.api.app import db
|
||||||
from fuel_analytics.api.common import consts
|
from fuel_analytics.api.common import consts
|
||||||
|
from fuel_analytics.api.db.model import InstallationStructure
|
||||||
from fuel_analytics.api.db.model import OpenStackWorkloadStats
|
from fuel_analytics.api.db.model import OpenStackWorkloadStats
|
||||||
from fuel_analytics.api.resources.csv_exporter import get_oswls
|
from fuel_analytics.api.resources.csv_exporter import get_oswls
|
||||||
from fuel_analytics.api.resources.csv_exporter import get_oswls_query
|
from fuel_analytics.api.resources.csv_exporter import get_oswls_query
|
||||||
|
@ -853,3 +854,95 @@ class OswlStatsToCsvTest(OswlTest, DbTest):
|
||||||
# The fourth oswl status True in is_modified, is_deleted
|
# The fourth oswl status True in is_modified, is_deleted
|
||||||
check_resource_state(flatten_resources[6], 'fourth',
|
check_resource_state(flatten_resources[6], 'fourth',
|
||||||
False, True, True)
|
False, True, True)
|
||||||
|
|
||||||
|
def test_fuel_version_from_clusters_data_is_used(self):
|
||||||
|
master_node_uid = 'x'
|
||||||
|
exporter = OswlStatsToCsv()
|
||||||
|
resource_type = consts.OSWL_RESOURCE_TYPES.vm
|
||||||
|
version_from_cluster = '7.0'
|
||||||
|
version_from_version_info = '9.0'
|
||||||
|
version_from_installation_info = '8.0'
|
||||||
|
installation_date = datetime.utcnow().date() - timedelta(days=3)
|
||||||
|
|
||||||
|
# Upgraded Fuel and not upgraded cluster
|
||||||
|
structure = InstallationStructure(
|
||||||
|
master_node_uid=master_node_uid,
|
||||||
|
structure={
|
||||||
|
'fuel_release': {'release': version_from_installation_info},
|
||||||
|
'clusters_num': 2,
|
||||||
|
'clusters': [
|
||||||
|
{'id': 1, 'fuel_release': version_from_cluster},
|
||||||
|
{'id': 2}
|
||||||
|
],
|
||||||
|
'unallocated_nodes_num_range': 0,
|
||||||
|
'allocated_nodes_num': 0
|
||||||
|
},
|
||||||
|
creation_date=installation_date,
|
||||||
|
is_filtered=False
|
||||||
|
)
|
||||||
|
db.session.add(structure)
|
||||||
|
|
||||||
|
oswls = [
|
||||||
|
OpenStackWorkloadStats(
|
||||||
|
master_node_uid=master_node_uid,
|
||||||
|
external_id=1,
|
||||||
|
cluster_id=1,
|
||||||
|
created_date=installation_date,
|
||||||
|
updated_time=datetime.utcnow().time(),
|
||||||
|
resource_type=resource_type,
|
||||||
|
resource_checksum='info_from_cluster',
|
||||||
|
resource_data={'current': [{'id': 1, 'status': 'enabled'}],
|
||||||
|
'added': [], 'modified': [], 'removed': []},
|
||||||
|
version_info=None
|
||||||
|
),
|
||||||
|
OpenStackWorkloadStats(
|
||||||
|
master_node_uid=master_node_uid,
|
||||||
|
external_id=3,
|
||||||
|
cluster_id=1,
|
||||||
|
created_date=installation_date + timedelta(days=1),
|
||||||
|
updated_time=datetime.utcnow().time(),
|
||||||
|
resource_type=resource_type,
|
||||||
|
resource_checksum='info_from_version_info',
|
||||||
|
resource_data={'current': [{'id': 1}],
|
||||||
|
'added': [], 'modified': [], 'removed': []},
|
||||||
|
version_info={'fuel_release': version_from_version_info}
|
||||||
|
),
|
||||||
|
OpenStackWorkloadStats(
|
||||||
|
master_node_uid=master_node_uid,
|
||||||
|
external_id=2,
|
||||||
|
cluster_id=2,
|
||||||
|
created_date=installation_date + timedelta(days=2),
|
||||||
|
updated_time=datetime.utcnow().time(),
|
||||||
|
resource_type=resource_type,
|
||||||
|
resource_checksum='info_from_installation_info',
|
||||||
|
resource_data={'current': [{'id': 1}],
|
||||||
|
'added': [], 'modified': [], 'removed': []},
|
||||||
|
version_info=None
|
||||||
|
)
|
||||||
|
]
|
||||||
|
for oswl in oswls:
|
||||||
|
db.session.add(oswl)
|
||||||
|
|
||||||
|
with app.test_request_context():
|
||||||
|
oswls_data = list(get_oswls(resource_type))
|
||||||
|
|
||||||
|
oswl_keys_paths, resource_keys_paths, csv_keys_paths = \
|
||||||
|
exporter.get_resource_keys_paths(resource_type)
|
||||||
|
fuel_release_pos = csv_keys_paths.index(
|
||||||
|
['version_info', 'fuel_release'])
|
||||||
|
flatten_resources = list(exporter.get_flatten_resources(
|
||||||
|
resource_type, oswl_keys_paths, resource_keys_paths, oswls_data))
|
||||||
|
|
||||||
|
self.assertEqual(len(oswls), len(flatten_resources))
|
||||||
|
|
||||||
|
# Checking release info fetched from cluster
|
||||||
|
self.assertEqual(version_from_cluster,
|
||||||
|
flatten_resources[0][fuel_release_pos])
|
||||||
|
|
||||||
|
# Checking release info fetched from oswl.version_info
|
||||||
|
self.assertEqual(version_from_version_info,
|
||||||
|
flatten_resources[1][fuel_release_pos])
|
||||||
|
|
||||||
|
# Checking release info fetched from installation info
|
||||||
|
self.assertEqual(version_from_installation_info,
|
||||||
|
flatten_resources[2][fuel_release_pos])
|
||||||
|
|
|
@ -36,14 +36,13 @@ class PluginsToCsvExportTest(InstStructureTest, DbTest):
|
||||||
exporter = StatsToCsv()
|
exporter = StatsToCsv()
|
||||||
_, _, _, csv_keys_paths = exporter.get_plugin_keys_paths()
|
_, _, _, csv_keys_paths = exporter.get_plugin_keys_paths()
|
||||||
self.assertTrue(['cluster_id'] in csv_keys_paths)
|
self.assertTrue(['cluster_id'] in csv_keys_paths)
|
||||||
|
self.assertTrue(['cluster_fuel_version'] in csv_keys_paths)
|
||||||
self.assertTrue(['master_node_uid'] in csv_keys_paths)
|
self.assertTrue(['master_node_uid'] in csv_keys_paths)
|
||||||
self.assertTrue(['name'] in csv_keys_paths)
|
self.assertTrue(['name'] in csv_keys_paths)
|
||||||
self.assertTrue(['version'] in csv_keys_paths)
|
self.assertTrue(['version'] in csv_keys_paths)
|
||||||
self.assertTrue(['fuel_version'] in csv_keys_paths)
|
self.assertTrue(['fuel_version'] in csv_keys_paths)
|
||||||
self.assertTrue(['package_version'] in csv_keys_paths)
|
self.assertTrue(['package_version'] in csv_keys_paths)
|
||||||
self.assertTrue(['structure', 'fuel_packages'] in csv_keys_paths)
|
self.assertTrue(['structure', 'fuel_packages'] in csv_keys_paths)
|
||||||
self.assertTrue(['structure', 'fuel_release', 'release'] in
|
|
||||||
csv_keys_paths)
|
|
||||||
|
|
||||||
def test_get_flatten_plugins(self):
|
def test_get_flatten_plugins(self):
|
||||||
installations_num = 10
|
installations_num = 10
|
||||||
|
@ -100,7 +99,8 @@ class PluginsToCsvExportTest(InstStructureTest, DbTest):
|
||||||
self.assertEqual(num - 1, len(list(flatten_plugins)))
|
self.assertEqual(num - 1, len(list(flatten_plugins)))
|
||||||
|
|
||||||
def test_fuel_release_info_in_flatten_plugins(self):
|
def test_fuel_release_info_in_flatten_plugins(self):
|
||||||
release = '8.0'
|
inst_fuel_version = '8.0'
|
||||||
|
cluster_fuel_version = '7.0'
|
||||||
packages = ['z', 'a', 'c']
|
packages = ['z', 'a', 'c']
|
||||||
inst_structures = [
|
inst_structures = [
|
||||||
model.InstallationStructure(
|
model.InstallationStructure(
|
||||||
|
@ -108,10 +108,11 @@ class PluginsToCsvExportTest(InstStructureTest, DbTest):
|
||||||
creation_date=datetime.datetime.utcnow(),
|
creation_date=datetime.datetime.utcnow(),
|
||||||
is_filtered=False,
|
is_filtered=False,
|
||||||
structure={
|
structure={
|
||||||
'fuel_release': {'release': release},
|
'fuel_release': {'release': inst_fuel_version},
|
||||||
'fuel_packages': packages,
|
'fuel_packages': packages,
|
||||||
'clusters': [{
|
'clusters': [{
|
||||||
'id': 1, 'nodes': [],
|
'id': 1, 'nodes': [],
|
||||||
|
'fuel_version': cluster_fuel_version,
|
||||||
'installed_plugins': [{
|
'installed_plugins': [{
|
||||||
'name': 'plugin_a',
|
'name': 'plugin_a',
|
||||||
'version': 'plugin_version_0',
|
'version': 'plugin_version_0',
|
||||||
|
@ -133,10 +134,10 @@ class PluginsToCsvExportTest(InstStructureTest, DbTest):
|
||||||
flatten_plugins = exporter.get_flatten_plugins(
|
flatten_plugins = exporter.get_flatten_plugins(
|
||||||
structure_paths, cluster_paths, plugins_paths, inst_structures)
|
structure_paths, cluster_paths, plugins_paths, inst_structures)
|
||||||
|
|
||||||
pos_release = csv_paths.index(['structure', 'fuel_release',
|
pos_fuel_version = csv_paths.index(['cluster_fuel_version'])
|
||||||
'release'])
|
|
||||||
pos_packages = csv_paths.index(['structure', 'fuel_packages'])
|
pos_packages = csv_paths.index(['structure', 'fuel_packages'])
|
||||||
for flatten_plugin in flatten_plugins:
|
for flatten_plugin in flatten_plugins:
|
||||||
self.assertEqual(release, flatten_plugin[pos_release])
|
self.assertEqual(cluster_fuel_version,
|
||||||
|
flatten_plugin[pos_fuel_version])
|
||||||
self.assertEqual(' '.join(packages),
|
self.assertEqual(' '.join(packages),
|
||||||
flatten_plugin[pos_packages])
|
flatten_plugin[pos_packages])
|
||||||
|
|
Loading…
Reference in New Issue