check_cfgfiles.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. import yaml
  5. import json
  6. import yamale
  7. import re
  8. import argparse
  9. def find_files_regex(directory, pattern):
  10. """
  11. Recursively search the specified directory and its subdirectories for files with the given name.
  12. :param directory: The path to the directory to search in.
  13. :param pattern: The file name regex pattern.
  14. :return: A list of paths to all found files.
  15. """
  16. found_files = []
  17. for root, dirs, files in os.walk(directory):
  18. for filename in files:
  19. if re.match(pattern, filename):
  20. found_files.append(os.path.join(root, filename))
  21. return found_files
  22. def validate_yaml(file_path):
  23. """
  24. Validate a YAML file to check if it is a valid YAML document.
  25. :param file_path: The path to the YAML file.
  26. :return: A tuple containing a boolean (True if the file is valid, False otherwise) and an error message (if the file is invalid).
  27. """
  28. try:
  29. with open(file_path, 'r') as file:
  30. yaml.safe_load(file)
  31. return True, None
  32. except yaml.YAMLError as exc:
  33. return False, exc
  34. def validate_json(file_path):
  35. """
  36. Validate a JSON file to check if it is a valid JSON document.
  37. :param file_path: The path to the JSON file.
  38. :return: A tuple containing a boolean (True if the file is valid, False otherwise) and an error message (if the file is invalid).
  39. """
  40. try:
  41. with open(file_path, 'r') as file:
  42. json.load(file)
  43. return True, None
  44. except json.JSONDecodeError as exc:
  45. return False, exc
  46. def validate_yaml_schema(file_path):
  47. """
  48. Validate a yaml schema file to check if it is a valid schema document.
  49. :param file_path: The path to the yaml schema file.
  50. :return: A tuple containing a boolean (True if the file is valid, False otherwise) and an error message (if the file is invalid).
  51. """
  52. try:
  53. yamale.make_schema(file_path)
  54. return True, None
  55. except Exception as exc:
  56. return False, exc
  57. def validate_cfgfile(file_path):
  58. """
  59. Validate a config file to check if it is a valid configuration file.
  60. :param file_path: The path to the configuration file.
  61. :return: A tuple containing a boolean (True if the file is valid, False otherwise) and an error message (if the file is invalid).
  62. """
  63. file_name = os.path.basename(file_path)
  64. fname = file_name.split(".")[0]
  65. suffix_keys = file_name.split(".")[1:]
  66. if "json" in suffix_keys:
  67. return validate_json(file_path)
  68. if "schema" in fname:
  69. return validate_yaml_schema(file_path)
  70. return validate_yaml(file_path)
  71. def main():
  72. parser = argparse.ArgumentParser(description="Validate json and yaml configuration files.")
  73. parser.add_argument("-d", "--directory", required=True, help="The directory to search for json and yaml files.")
  74. args = parser.parse_args()
  75. # Check if the directory exists
  76. if not os.path.isdir(args.directory):
  77. print("The directory {} does not exist!".format(args.directory))
  78. sys.exit(1)
  79. pattern = r'^.*\.(json|json\..*|yaml|yml)$'
  80. config_files = find_files_regex(args.directory, pattern)
  81. failed_files = []
  82. for file_path in config_files:
  83. is_valid, error = validate_cfgfile(file_path)
  84. if not is_valid:
  85. print("- {}: FAIL".format(file_path))
  86. failed_files.append((file_path, error))
  87. else:
  88. print("- {}: PASS".format(file_path))
  89. if failed_files:
  90. print("\nFailed config files with reasons:")
  91. for file_path, error in failed_files:
  92. print("- {}: {}".format(file_path, error))
  93. # Exit with a non-zero status code if there were failures
  94. sys.exit(1)
  95. # Exit with a zero status code if all files are valid
  96. sys.exit(0)
  97. if __name__ == "__main__":
  98. main()