From 2392d7e38cc5937921c2ecaf5af2b21f3cb32c40 Mon Sep 17 00:00:00 2001 From: Jeffrey Zhang Date: Thu, 20 Oct 2016 02:21:35 +0800 Subject: [PATCH] Add file validator for *.json.j2 file All json file in Kolla are json.j2 file, it shold be render as jinja template, then validate by using json. Change-Id: Ibabbe435116fd255d68347e00407156db76fedfe Closes-Bug: #1634447 --- tools/validate-all-file.py | 57 ++++++++++++++++++++++++++++++++++++-- tools/validate-all-json.sh | 7 ----- tools/validate-json.py | 44 ----------------------------- tox.ini | 4 +-- 4 files changed, 56 insertions(+), 56 deletions(-) delete mode 100755 tools/validate-all-json.sh delete mode 100755 tools/validate-json.py diff --git a/tools/validate-all-file.py b/tools/validate-all-file.py index 601f2e4326..e44641291e 100755 --- a/tools/validate-all-file.py +++ b/tools/validate-all-file.py @@ -12,18 +12,26 @@ # See the License for the specific language governing permissions and # limitations under the License. +import collections import fnmatch +import json import logging import os import re import sys +import jinja2 + PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) NEWLINE_EOF_INCLUDE_PATTERNS = ['*.j2', '*.yml', '*.py', '*.sh'] NEWLINE_EOF_EXCLUDE_PATTERNS = ['.tox', '.testrepository', '.git'] +# Render json file by using jinja2 template is OK +JSON_J2_INCLUDE_PATTERNS = ['*.json.j2', '*.json'] +JSON_J2_EXCLUDE_PATTERNS = ['.tox', '.testrepository', '.git'] + logging.basicConfig() LOG = logging.getLogger(__name__) @@ -52,9 +60,54 @@ def check_newline_eof(): return return_code -def main(): - return sum([check_newline_eof()]) +def check_json_j2(): + includes = r'|'.join([fnmatch.translate(x) + for x in JSON_J2_INCLUDE_PATTERNS]) + excludes = r'|'.join([fnmatch.translate(x) + for x in JSON_J2_EXCLUDE_PATTERNS]) + return_code = 0 + def bool_filter(value): + return True + + # Mock ansible hostvars variable, which is a nested dict + def hostvars(): + return collections.defaultdict(hostvars) + + def validate_json_j2(root, filename): + env = jinja2.Environment( # nosec: not used to render HTML + loader=jinja2.FileSystemLoader(root)) + env.filters['bool'] = bool_filter + template = env.get_template(filename) + # Mock ansible variables. + context = { + 'hostvars': hostvars(), + 'cluster_interface': 'cluster_interface', + 'storage_interface': 'storage_interface', + 'inventory_hostname': 'hostname' + } + data = template.render(**context) + json.loads(data) + for root, dirs, files in os.walk(PROJECT_ROOT): + dirs[:] = [d for d in dirs if not re.match(excludes, d)] + for filename in files: + if not re.match(excludes, filename) and \ + re.match(includes, filename): + fullpath = os.path.join(root, filename) + try: + validate_json_j2(root, filename) + except (ValueError, jinja2.exceptions.TemplateError): + return_code = 1 + LOG.exception('%s file error', fullpath) + return return_code + + +def main(): + checks = ( + check_newline_eof, + check_json_j2 + ) + return sum([check() for check in checks]) if __name__ == "__main__": sys.exit(main()) diff --git a/tools/validate-all-json.sh b/tools/validate-all-json.sh deleted file mode 100755 index 7e61a8a1ad..0000000000 --- a/tools/validate-all-json.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -REAL_PATH=$(python -c "import os,sys;print os.path.realpath('$0')") -cd "$(dirname "$REAL_PATH")/.." - -find . -path ./.tox -prune -name '*.json' -print0 | - xargs -0 python tools/validate-json.py || exit 1 diff --git a/tools/validate-json.py b/tools/validate-json.py deleted file mode 100755 index eee2276dbc..0000000000 --- a/tools/validate-json.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python - -# 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 argparse -import json -import logging -import sys - - -def parse_args(): - p = argparse.ArgumentParser() - p.add_argument('input', nargs='*') - return p.parse_args() - - -def main(): - args = parse_args() - logging.basicConfig() - res = 0 - - for filename in args.input: - with open(filename) as fd: - try: - json.load(fd) - except ValueError as error: - res = 1 - logging.error('%s failed validation: %s', - filename, error) - - sys.exit(res) - -if __name__ == '__main__': - main() diff --git a/tox.ini b/tox.ini index ece81a6465..5bbdcc0c8e 100644 --- a/tox.ini +++ b/tox.ini @@ -25,10 +25,8 @@ commands = oslo_debug_helper {posargs} commands = {toxinidir}/tools/run-bashate.sh flake8 {posargs} - {toxinidir}/tools/validate-all-json.sh - {toxinidir}/tools/validate-all-yaml.sh {toxinidir}/tools/validate-all-dockerfiles.sh - {toxinidir}/tools/validate-all-file.py + python {toxinidir}/tools/validate-all-file.py bandit -r ansible/library docker kolla tests tools [testenv:bandit]