import logging from ansible_tree.plugin.common import PluginStrategyClass from ansible_tree.utils import schema_validate, str_ellipsis log = logging.getLogger(__name__) import json from pprint import pprint from jsonmerge import Merger from prettytable import PrettyTable class Plugin(PluginStrategyClass): _plugin_name = "schema" default_merge_schema = { "$schema": 'http://json-schema.org/draft-04/schema#', "oneOf": [ { "type": "array", "mergeStrategy": "append", # "mergeStrategy": "arrayMergeById", }, { "type": "object", "mergeStrategy": "objectMerge", }, { "type": "boolean", "mergeStrategy": "overwrite", }, { "type": "string", "mergeStrategy": "overwrite", }, { "type": "integer", "mergeStrategy": "overwrite", }, { "type": "number", "mergeStrategy": "overwrite", }, { "type": "null", "mergeStrategy": "overwrite", }, ], } def process(self, candidates: list, rule=None) -> (list, dict): trace = rule['trace'] explain = rule['explain'] schema = rule.get('schema', None) or self.default_merge_schema merger = Merger(schema) t = PrettyTable() t1 = PrettyTable() new_candidate = None for index, item in enumerate(candidates): new_value = item['data'] result = merger.merge(new_candidate, new_value) backend_info = dict(item['parent']) backend_run = backend_info.pop("_run") if explain: t1.add_row([ index, '\nBackendRun: ' + str_ellipsis(json.dumps( backend_run, default=lambda o: '', indent=2), 70), '\nRuleRun: ' + str_ellipsis(json.dumps( item['run'], default=lambda o: '', indent=2), 70), '---\nResult: ' + str_ellipsis(json.dumps( result, default=lambda o: '', indent=2), 70), ]) if trace: t.add_row([ index, '---\nBackendConfig: ' + str_ellipsis(json.dumps( backend_info, default=lambda o: '', indent=2), 70) + '\nBackendRun: ' + str_ellipsis(json.dumps( backend_run, default=lambda o: '', indent=2), 70), '---\nRuleConfig: ' + str_ellipsis(json.dumps( rule, default=lambda o: '', indent=2), 70) + '\nRuleRun: ' + str_ellipsis(json.dumps( item['run'], default=lambda o: '', indent=2), 70) + #'\nSource: ' + str_ellipsis(json.dumps( # new_candidate, # default=lambda o: '', indent=2), 70) + '\nNew data: ' + str_ellipsis(json.dumps( new_value, default=lambda o: '', indent=2), 70), '---\nResult: ' + str_ellipsis(json.dumps( result, default=lambda o: '', indent=2), 70), ] ) new_candidate = result if trace: t.field_names = ["Index", "Backend", "Rule", "Data"] t.align = 'l' print (t) if explain: t1.field_names = ["Index", "Backend", "Rule", "Data"] t1.align = 'l' print('Explain:\n' + repr(t1)) return new_candidate