logging_patch.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/python
  2. """ Ansible module to help with creating context patch file with whitelisting for logging """
  3. import difflib
  4. import re
  5. from ansible.module_utils.basic import AnsibleModule
  6. DOCUMENTATION = '''
  7. ---
  8. module: logging_patch
  9. short_description: This will create a context patch file while giving ability
  10. to whitelist some lines (excluding them from comparison)
  11. description:
  12. - "To create configmap patches for logging"
  13. author:
  14. - Eric Wolinetz ewolinet@redhat.com
  15. '''
  16. EXAMPLES = '''
  17. - logging_patch:
  18. original_file: "{{ tempdir }}/current.yml"
  19. new_file: "{{ configmap_new_file }}"
  20. whitelist: "{{ configmap_protected_lines | default([]) }}"
  21. '''
  22. def account_for_whitelist(current_file_contents, new_file_contents, white_list=None):
  23. """ This method will remove lines that contain whitelist values from the content
  24. of the file so that we aren't build a patch based on that line
  25. Usage:
  26. for current_file_contents:
  27. index:
  28. number_of_shards: 1
  29. number_of_replicas: 0
  30. unassigned.node_left.delayed_timeout: 2m
  31. translog:
  32. flush_threshold_size: 256mb
  33. flush_threshold_period: 5m
  34. and new_file_contents:
  35. index:
  36. number_of_shards: 2
  37. number_of_replicas: 1
  38. unassigned.node_left.delayed_timeout: 2m
  39. translog:
  40. flush_threshold_size: 256mb
  41. flush_threshold_period: 5m
  42. and white_list:
  43. ['number_of_shards', 'number_of_replicas']
  44. We would end up with:
  45. index:
  46. number_of_shards: 2
  47. number_of_replicas: 1
  48. unassigned.node_left.delayed_timeout: 2m
  49. translog:
  50. flush_threshold_size: 256mb
  51. flush_threshold_period: 5m
  52. """
  53. for line in white_list:
  54. regex_line = r".*" + re.escape(line) + r":.*\n"
  55. new_file_line = re.search(regex_line, new_file_contents)
  56. if new_file_line:
  57. current_file_contents = re.sub(regex_line, new_file_line.group(0), current_file_contents)
  58. else:
  59. current_file_contents = re.sub(regex_line, "", current_file_contents)
  60. return current_file_contents
  61. def run_module():
  62. """ The body of the module, we check if the variable name specified as the value
  63. for the key is defined. If it is then we use that value as for the original key """
  64. module = AnsibleModule(
  65. argument_spec=dict(
  66. original_file=dict(type='str', required=True),
  67. new_file=dict(type='str', required=True),
  68. whitelist=dict(required=False, type='list', default=[])
  69. ),
  70. supports_check_mode=True
  71. )
  72. original_fh = open(module.params['original_file'], "r")
  73. original_contents = original_fh.read()
  74. original_fh.close()
  75. new_fh = open(module.params['new_file'], "r")
  76. new_contents = new_fh.read()
  77. new_fh.close()
  78. original_contents = account_for_whitelist(original_contents, new_contents, module.params['whitelist'])
  79. uni_diff = difflib.unified_diff(new_contents.splitlines(),
  80. original_contents.splitlines(),
  81. lineterm='')
  82. return module.exit_json(changed=False, # noqa: F405
  83. raw_patch="\n".join(uni_diff))
  84. def main():
  85. """ main """
  86. run_module()
  87. if __name__ == '__main__':
  88. main()