Add utils functions and validations List object
This commit is contained in:
parent
7cb6db10b9
commit
8cce4bfd64
26
validations_libs/constants.py
Normal file
26
validations_libs/constants.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright 2020 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 os
|
||||||
|
|
||||||
|
DEFAULT_VALIDATIONS_BASEDIR = '/usr/share/validations-common'
|
||||||
|
|
||||||
|
ANSIBLE_VALIDATION_DIR = '/usr/share/validations-common/playbooks'
|
||||||
|
|
||||||
|
VALIDATION_GROUPS_INFO = '%s/groups.yaml' % DEFAULT_VALIDATIONS_BASEDIR
|
||||||
|
|
||||||
|
VALIDATION_GROUPS = ['no-op',
|
||||||
|
'prep',
|
||||||
|
'post']
|
42
validations_libs/list.py
Normal file
42
validations_libs/list.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Copyright 2020 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 constants
|
||||||
|
import logging
|
||||||
|
import utils as validations_utils
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__ + ".list")
|
||||||
|
|
||||||
|
|
||||||
|
class List(object):
|
||||||
|
|
||||||
|
def __init__(self, group, validations_dir=None):
|
||||||
|
self.log = logging.getLogger(__name__ + ".List")
|
||||||
|
self.validations_dir = (validations_dir if validations_dir
|
||||||
|
else constants.ANSIBLE_VALIDATION_DIR)
|
||||||
|
self.group = group
|
||||||
|
|
||||||
|
def list_validations(self):
|
||||||
|
"""List the available validations"""
|
||||||
|
validations = validations_utils.parse_all_validations_on_disk(
|
||||||
|
self.validations_dir, self.group)
|
||||||
|
|
||||||
|
return_values = []
|
||||||
|
column_name = ('ID', 'Name', 'Groups')
|
||||||
|
|
||||||
|
for val in validations:
|
||||||
|
return_values.append((val.get('id'), val.get('name'),
|
||||||
|
val.get('groups')))
|
||||||
|
return (column_name, return_values)
|
0
validations_libs/run.py
Normal file
0
validations_libs/run.py
Normal file
0
validations_libs/show.py
Normal file
0
validations_libs/show.py
Normal file
0
validations_libs/tests/__init__.py
Normal file
0
validations_libs/tests/__init__.py
Normal file
141
validations_libs/tests/fakes.py
Normal file
141
validations_libs/tests/fakes.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Copyright 2020 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
|
||||||
|
VALIDATIONS_LIST = [{
|
||||||
|
'description': 'My Validation One Description',
|
||||||
|
'groups': ['prep', 'pre-deployment'],
|
||||||
|
'id': 'my_val1',
|
||||||
|
'name': 'My Validition One Name',
|
||||||
|
'parameters': {}
|
||||||
|
}, {
|
||||||
|
'description': 'My Validation Two Description',
|
||||||
|
'groups': ['prep', 'pre-introspection'],
|
||||||
|
'id': 'my_val2',
|
||||||
|
'name': 'My Validition Two Name',
|
||||||
|
'parameters': {'min_value': 8}
|
||||||
|
}]
|
||||||
|
|
||||||
|
GROUPS_LIST = [
|
||||||
|
('group1', 'Group1 description'),
|
||||||
|
('group2', 'Group2 description'),
|
||||||
|
('group3', 'Group3 description'),
|
||||||
|
]
|
||||||
|
|
||||||
|
VALIDATIONS_LOGS_CONTENTS_LIST = [{
|
||||||
|
'plays': [{
|
||||||
|
'play': {
|
||||||
|
'duration': {
|
||||||
|
'end': '2019-11-25T13:40:17.538611Z',
|
||||||
|
'start': '2019-11-25T13:40:14.404623Z',
|
||||||
|
'time_elapsed': '0:00:03.753'
|
||||||
|
},
|
||||||
|
'host': 'undercloud',
|
||||||
|
'id': '008886df-d297-1eaa-2a74-000000000008',
|
||||||
|
'validation_id': '512e',
|
||||||
|
'validation_path':
|
||||||
|
'/usr/share/openstack-tripleo-validations/playbooks'
|
||||||
|
},
|
||||||
|
'tasks': [
|
||||||
|
{
|
||||||
|
'hosts': {
|
||||||
|
'undercloud': {
|
||||||
|
'_ansible_no_log': False,
|
||||||
|
'action': 'command',
|
||||||
|
'changed': False,
|
||||||
|
'cmd': [u'ls', '/sys/class/block/'],
|
||||||
|
'delta': '0:00:00.018913',
|
||||||
|
'end': '2019-11-25 13:40:17.120368',
|
||||||
|
'invocation': {
|
||||||
|
'module_args': {
|
||||||
|
'_raw_params': 'ls /sys/class/block/',
|
||||||
|
'_uses_shell': False,
|
||||||
|
'argv': None,
|
||||||
|
'chdir': None,
|
||||||
|
'creates': None,
|
||||||
|
'executable': None,
|
||||||
|
'removes': None,
|
||||||
|
'stdin': None,
|
||||||
|
'stdin_add_newline': True,
|
||||||
|
'strip_empty_ends': True,
|
||||||
|
'warn': True
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'rc': 0,
|
||||||
|
'start': '2019-11-25 13:40:17.101455',
|
||||||
|
'stderr': '',
|
||||||
|
'stderr_lines': [],
|
||||||
|
'stdout': 'vda',
|
||||||
|
'stdout_lines': [u'vda']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'task': {
|
||||||
|
'duration': {
|
||||||
|
'end': '2019-11-25T13:40:17.336687Z',
|
||||||
|
'start': '2019-11-25T13:40:14.529880Z'
|
||||||
|
},
|
||||||
|
'id':
|
||||||
|
'008886df-d297-1eaa-2a74-00000000000d',
|
||||||
|
'name':
|
||||||
|
'advanced-format-512e-support : List the available drives'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'hosts': {
|
||||||
|
'undercloud': {
|
||||||
|
'action':
|
||||||
|
'advanced_format',
|
||||||
|
'changed': False,
|
||||||
|
'msg':
|
||||||
|
'All items completed',
|
||||||
|
'results': [{
|
||||||
|
'_ansible_item_label': 'vda',
|
||||||
|
'_ansible_no_log': False,
|
||||||
|
'ansible_loop_var': 'item',
|
||||||
|
'changed': False,
|
||||||
|
'item': 'vda',
|
||||||
|
'skip_reason': 'Conditional result was False',
|
||||||
|
'skipped': True
|
||||||
|
}],
|
||||||
|
'skipped': True
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'task': {
|
||||||
|
'duration': {
|
||||||
|
'end': '2019-11-25T13:40:17.538611Z',
|
||||||
|
'start': '2019-11-25T13:40:17.341704Z'
|
||||||
|
},
|
||||||
|
'id': '008886df-d297-1eaa-2a74-00000000000e',
|
||||||
|
'name':
|
||||||
|
'advanced-format-512e-support: Detect the drive'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
'stats': {
|
||||||
|
'undercloud': {
|
||||||
|
'changed': 0,
|
||||||
|
'failures': 0,
|
||||||
|
'ignored': 0,
|
||||||
|
'ok': 1,
|
||||||
|
'rescued': 0,
|
||||||
|
'skipped': 1,
|
||||||
|
'unreachable': 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'validation_output': []
|
||||||
|
}]
|
40
validations_libs/tests/test_validations_list.py
Normal file
40
validations_libs/tests/test_validations_list.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2018 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from validations_libs.tests import fakes
|
||||||
|
from validations_libs.list import List
|
||||||
|
|
||||||
|
|
||||||
|
class TestValidatorList(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestValidatorList, self).setUp()
|
||||||
|
self.column_name = ('ID', 'Name', 'Groups')
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
||||||
|
return_value=fakes.VALIDATIONS_LIST)
|
||||||
|
def test_validation_list(self, mock_validation_dir):
|
||||||
|
validations_list = List(fakes.GROUPS_LIST, '/tmp/foo')
|
||||||
|
|
||||||
|
self.assertEqual(validations_list.list_validations(),
|
||||||
|
(self.column_name, [('my_val1',
|
||||||
|
'My Validition One Name',
|
||||||
|
['prep', 'pre-deployment']),
|
||||||
|
('my_val2',
|
||||||
|
'My Validition Two Name',
|
||||||
|
['prep', 'pre-introspection'])]))
|
94
validations_libs/utils.py
Normal file
94
validations_libs/utils.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# Copyright 2020 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 constants
|
||||||
|
import glob
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__ + ".utils")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_all_validations_on_disk(path, groups=None):
|
||||||
|
results = []
|
||||||
|
validations_abspath = glob.glob("{path}/*.yaml".format(path=path))
|
||||||
|
|
||||||
|
for pl in validations_abspath:
|
||||||
|
validation_id, ext = os.path.splitext(os.path.basename(pl))
|
||||||
|
|
||||||
|
with open(pl, 'r') as val_playbook:
|
||||||
|
contents = yaml.safe_load(val_playbook)
|
||||||
|
|
||||||
|
validation_groups = get_validation_metadata(contents, 'groups') or []
|
||||||
|
if not groups or set.intersection(set(groups), set(validation_groups)):
|
||||||
|
results.append({
|
||||||
|
'id': validation_id,
|
||||||
|
'name': get_validation_metadata(contents, 'name'),
|
||||||
|
'groups': get_validation_metadata(contents, 'groups'),
|
||||||
|
'description': get_validation_metadata(contents,
|
||||||
|
'description'),
|
||||||
|
'parameters': get_validation_parameters(contents)
|
||||||
|
})
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def parse_all_validation_groups_on_disk(groups_file_path=None):
|
||||||
|
results = []
|
||||||
|
|
||||||
|
if not groups_file_path:
|
||||||
|
groups_file_path = constants.VALIDATION_GROUPS_INFO
|
||||||
|
|
||||||
|
if not os.path.exists(groups_file_path):
|
||||||
|
return results
|
||||||
|
|
||||||
|
with open(groups_file_path, 'r') as grps:
|
||||||
|
contents = yaml.safe_load(grps)
|
||||||
|
|
||||||
|
for grp_name, grp_desc in sorted(contents.items()):
|
||||||
|
results.append((grp_name, grp_desc[0].get('description')))
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def get_validation_metadata(validation, key):
|
||||||
|
default_metadata = {
|
||||||
|
'name': 'Unnamed',
|
||||||
|
'description': 'No description',
|
||||||
|
'stage': 'No stage',
|
||||||
|
'groups': [],
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
return validation[0]['vars']['metadata'].get(key,
|
||||||
|
default_metadata[key])
|
||||||
|
except KeyError:
|
||||||
|
LOG.exception("Key '{key}' not even found in "
|
||||||
|
"default metadata").format(key=key)
|
||||||
|
except TypeError:
|
||||||
|
LOG.exception("Failed to get validation metadata.")
|
||||||
|
|
||||||
|
|
||||||
|
def get_validation_parameters(validation):
|
||||||
|
try:
|
||||||
|
return {
|
||||||
|
k: v
|
||||||
|
for k, v in validation[0]['vars'].items()
|
||||||
|
if k != 'metadata'
|
||||||
|
}
|
||||||
|
except KeyError:
|
||||||
|
LOG.debug("No parameters found for this validation")
|
||||||
|
return dict()
|
Loading…
Reference in New Issue
Block a user