diff options
-rw-r--r-- | playbooks/byo/openshift-master/scaleup.yml | 4 | ||||
-rw-r--r-- | roles/openshift_health_checker/callback_plugins/zz_failure_summary.py | 16 | ||||
-rw-r--r-- | roles/openshift_health_checker/test/zz_failure_summary_test.py | 15 | ||||
-rw-r--r-- | roles/openshift_master_facts/filter_plugins/openshift_master.py | 2 | ||||
-rw-r--r-- | roles/openshift_metrics/tasks/pre_install.yaml | 2 | ||||
-rw-r--r-- | setup.py | 101 |
6 files changed, 112 insertions, 28 deletions
diff --git a/playbooks/byo/openshift-master/scaleup.yml b/playbooks/byo/openshift-master/scaleup.yml index 2179d1416..a09edd55a 100644 --- a/playbooks/byo/openshift-master/scaleup.yml +++ b/playbooks/byo/openshift-master/scaleup.yml @@ -1,7 +1,7 @@ --- - include: ../openshift-cluster/initialize_groups.yml -- name: Ensure there are new_masters +- name: Ensure there are new_masters or new_nodes hosts: localhost connection: local become: no @@ -13,7 +13,7 @@ add hosts to the new_masters and new_nodes host groups to add masters. when: - - (g_new_master_hosts | default([]) | length == 0) or (g_new_node_hosts | default([]) | length == 0) + - (g_new_master_hosts | default([]) | length == 0) and (g_new_node_hosts | default([]) | length == 0) - include: ../../common/openshift-cluster/std_include.yml diff --git a/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py b/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py index 349655966..dcaf87eca 100644 --- a/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py +++ b/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py @@ -10,6 +10,7 @@ import traceback from ansible.plugins.callback import CallbackBase from ansible import constants as C from ansible.utils.color import stringc +from ansible.module_utils.six import string_types FAILED_NO_MSG = u'Failed without returning a message.' @@ -140,11 +141,19 @@ def deduplicate_failures(failures): Returns a new list of failures such that identical failures from different hosts are grouped together in a single entry. The relative order of failures is preserved. + + If failures is unhashable, the original list of failures is returned. """ groups = defaultdict(list) for failure in failures: group_key = tuple(sorted((key, value) for key, value in failure.items() if key != 'host')) - groups[group_key].append(failure) + try: + groups[group_key].append(failure) + except TypeError: + # abort and return original list of failures when failures has an + # unhashable type. + return failures + result = [] for failure in failures: group_key = tuple(sorted((key, value) for key, value in failure.items() if key != 'host')) @@ -159,7 +168,10 @@ def format_failure(failure): """Return a list of pretty-formatted text entries describing a failure, including relevant information about it. Expect that the list of text entries will be joined by a newline separator when output to the user.""" - host = u', '.join(failure['host']) + if isinstance(failure['host'], string_types): + host = failure['host'] + else: + host = u', '.join(failure['host']) play = failure['play'] task = failure['task'] msg = failure['msg'] diff --git a/roles/openshift_health_checker/test/zz_failure_summary_test.py b/roles/openshift_health_checker/test/zz_failure_summary_test.py index 0fc258133..69f27653c 100644 --- a/roles/openshift_health_checker/test/zz_failure_summary_test.py +++ b/roles/openshift_health_checker/test/zz_failure_summary_test.py @@ -65,6 +65,21 @@ import pytest }, ], ), + # if a failure contain an unhashable value, it will not be deduplicated + ( + [ + { + 'host': 'master1', + 'msg': {'unhashable': 'value'}, + }, + ], + [ + { + 'host': 'master1', + 'msg': {'unhashable': 'value'}, + }, + ], + ), ]) def test_deduplicate_failures(failures, deduplicated): assert deduplicate_failures(failures) == deduplicated diff --git a/roles/openshift_master_facts/filter_plugins/openshift_master.py b/roles/openshift_master_facts/filter_plugins/openshift_master.py index e767772ce..5558f55cb 100644 --- a/roles/openshift_master_facts/filter_plugins/openshift_master.py +++ b/roles/openshift_master_facts/filter_plugins/openshift_master.py @@ -383,7 +383,7 @@ class OpenIDIdentityProvider(IdentityProviderOauthBase): if 'extraAuthorizeParameters' in self._idp: if 'include_granted_scopes' in self._idp['extraAuthorizeParameters']: val = ansible_bool(self._idp['extraAuthorizeParameters'].pop('include_granted_scopes')) - self._idp['extraAuthorizeParameters']['include_granted_scopes'] = val + self._idp['extraAuthorizeParameters']['include_granted_scopes'] = '"true"' if val else '"false"' def validate(self): ''' validate this idp instance ''' diff --git a/roles/openshift_metrics/tasks/pre_install.yaml b/roles/openshift_metrics/tasks/pre_install.yaml index 2e2013d40..d6756f9b9 100644 --- a/roles/openshift_metrics/tasks/pre_install.yaml +++ b/roles/openshift_metrics/tasks/pre_install.yaml @@ -10,7 +10,7 @@ is invalid, must be one of: emptydir, pv, dynamic when: - openshift_metrics_cassandra_storage_type not in openshift_metrics_cassandra_storage_types - - "not {{ openshift_metrics_heapster_standalone | bool }}" + - not (openshift_metrics_heapster_standalone | bool) - name: list existing secrets command: > @@ -48,6 +48,27 @@ def find_files(base_dir, exclude_dirs, include_dirs, file_regex): return found +def recursive_search(search_list, field): + """ + Takes a list with nested dicts, and searches all dicts for a key of the + field provided. If the items in the list are not dicts, the items are not + processed. + """ + fields_found = [] + + for item in search_list: + if isinstance(item, dict): + for key, value in item.items(): + if key == field: + fields_found.append(value) + elif isinstance(value, list): + results = recursive_search(value, field) + for result in results: + fields_found.append(result) + + return fields_found + + def find_entrypoint_playbooks(): '''find entry point playbooks as defined by openshift-ansible''' playbooks = set() @@ -248,37 +269,73 @@ class OpenShiftAnsibleSyntaxCheck(Command): ''' finalize_options ''' pass + def deprecate_jinja2_in_when(self, yaml_contents, yaml_file): + ''' Check for Jinja2 templating delimiters in when conditions ''' + test_result = False + failed_items = [] + + search_results = recursive_search(yaml_contents, 'when') + for item in search_results: + if isinstance(item, str): + if '{{' in item or '{%' in item: + failed_items.append(item) + else: + for sub_item in item: + if '{{' in sub_item or '{%' in sub_item: + failed_items.append(sub_item) + + if len(failed_items) > 0: + print('{}Error: Usage of Jinja2 templating delimiters in when ' + 'conditions is deprecated in Ansible 2.3.\n' + ' File: {}'.format(self.FAIL, yaml_file)) + for item in failed_items: + print(' Found: "{}"'.format(item)) + print(self.ENDC) + test_result = True + + return test_result + + def deprecate_include(self, yaml_contents, yaml_file): + ''' Check for usage of include directive ''' + test_result = False + + search_results = recursive_search(yaml_contents, 'include') + + if len(search_results) > 0: + print('{}Error: The `include` directive is deprecated in Ansible 2.4.\n' + 'https://github.com/ansible/ansible/blob/devel/CHANGELOG.md\n' + ' File: {}'.format(self.FAIL, yaml_file)) + for item in search_results: + print(' Found: "include: {}"'.format(item)) + print(self.ENDC) + test_result = True + + return test_result + def run(self): ''' run command ''' has_errors = False print('Ansible Deprecation Checks') - exclude_dirs = ['adhoc', 'files', 'meta', 'test', 'tests', 'vars', '.tox'] + exclude_dirs = ['adhoc', 'files', 'meta', 'test', 'tests', 'vars', 'defaults', '.tox'] for yaml_file in find_files( os.getcwd(), exclude_dirs, None, r'\.ya?ml$'): with open(yaml_file, 'r') as contents: - for task in yaml.safe_load(contents) or {}: - if not isinstance(task, dict): - # Skip yaml files which are not a dictionary of tasks - continue - if 'when' in task: - if '{{' in task['when'] or '{%' in task['when']: - print('{}Error: Usage of Jinja2 templating delimiters ' - 'in when conditions is deprecated in Ansible 2.3.\n' - ' File: {}\n' - ' Found: "{}"{}'.format( - self.FAIL, yaml_file, - task['when'], self.ENDC)) - has_errors = True - # TODO (rteague): This test will be enabled once we move to Ansible 2.4 - # if 'include' in task: - # print('{}Error: The `include` directive is deprecated in Ansible 2.4.\n' - # 'https://github.com/ansible/ansible/blob/devel/CHANGELOG.md\n' - # ' File: {}\n' - # ' Found: "include: {}"{}'.format( - # self.FAIL, yaml_file, task['include'], self.ENDC)) - # has_errors = True + yaml_contents = yaml.safe_load(contents) + if not isinstance(yaml_contents, list): + continue + + # Check for Jinja2 templating delimiters in when conditions + result = self.deprecate_jinja2_in_when(yaml_contents, yaml_file) + has_errors = result or has_errors + + # TODO (rteague): This test will be enabled once we move to Ansible 2.4 + # result = self.deprecate_include(yaml_contents, yaml_file) + # has_errors = result or has_errors + + if not has_errors: + print('...PASSED') print('Ansible Playbook Entry Point Syntax Checks') for playbook in find_entrypoint_playbooks(): |