my ansible modules which are stock in pull request
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
7.2 KiB

  1. #!/usr/bin/python
  2. # Copyright: Ansible Project
  3. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
  4. from __future__ import absolute_import, division, print_function
  5. __metaclass__ = type
  6. ANSIBLE_METADATA = {'metadata_version': '1.1',
  7. 'status': ['preview'],
  8. 'supported_by': 'community'}
  9. DOCUMENTATION = '''
  10. ---
  11. module: cloudwatchlogs_log_group_metric_filter
  12. version_added: "2.10"
  13. author:
  14. - "Markus Bergholz (@markuman)"
  15. short_description: Manage CloudWatch log group metric filter
  16. description:
  17. - Create, modify and delete CloudWatch log group metric filter.
  18. - CloudWatch log group metric filter can be use with M(ec2_metric_alarm).
  19. requirements:
  20. - boto3
  21. - botocore
  22. options:
  23. state:
  24. description:
  25. - Whether the rule is present or absent.
  26. choices: ["present", "absent"]
  27. required: true
  28. type: str
  29. log_group_name:
  30. description:
  31. - The name of the log group where the metric filter is applied on.
  32. required: true
  33. type: str
  34. filter_name:
  35. description:
  36. - A name for the metric filter you create.
  37. required: true
  38. type: str
  39. filter_pattern:
  40. description:
  41. - A filter pattern for extracting metric data out of ingested log events. Required when I(state=present).
  42. type: str
  43. metric_transformation:
  44. description:
  45. - A collection of information that defines how metric data gets emitted. Required when I(state=present).
  46. type: dict
  47. suboptions:
  48. metric_name:
  49. description:
  50. - The name of the cloudWatch metric.
  51. type: str
  52. metric_namespace:
  53. description:
  54. - The namespace of the cloudWatch metric.
  55. type: str
  56. metric_value:
  57. description:
  58. - The value to publish to the cloudWatch metric when a filter pattern matches a log event.
  59. type: str
  60. default_value:
  61. description:
  62. - The value to emit when a filter pattern does not match a log event.
  63. type: float
  64. extends_documentation_fragment:
  65. - aws
  66. - ec2
  67. '''
  68. EXAMPLES = '''
  69. - name: set metric filter on log group /fluentd/testcase
  70. cloudwatchlogs_log_group_metric_filter:
  71. log_group_name: /fluentd/testcase
  72. filter_name: BoxFreeStorage
  73. filter_pattern: '{($.value = *) && ($.hostname = "box")}'
  74. state: present
  75. metric_transformation:
  76. metric_name: box_free_space
  77. metric_namespace: fluentd_metrics
  78. metric_value: "$.value"
  79. - name: delete metric filter on log group /fluentd/testcase
  80. cloudwatchlogs_log_group_metric_filter:
  81. log_group_name: /fluentd/testcase
  82. filter_name: BoxFreeStorage
  83. state: absent
  84. '''
  85. RETURN = """
  86. metric_filters:
  87. description: Return the origin response value
  88. returned: success
  89. type: list
  90. contains:
  91. creation_time:
  92. filter_name:
  93. filter_pattern:
  94. log_group_name:
  95. metric_filter_count:
  96. """
  97. from ansible.module_utils.aws.core import AnsibleAWSModule, is_boto3_error_code, get_boto3_client_method_parameters
  98. from ansible.module_utils.ec2 import camel_dict_to_snake_dict
  99. try:
  100. from botocore.exceptions import ClientError, BotoCoreError, WaiterError
  101. except ImportError:
  102. pass # caught by AnsibleAWSModule
  103. def metricTransformationHandler(metricTransformations, originMetricTransformations=None):
  104. if originMetricTransformations:
  105. change = False
  106. originMetricTransformations = camel_dict_to_snake_dict(
  107. originMetricTransformations)
  108. for item in ["default_value", "metric_name", "metric_namespace", "metric_value"]:
  109. if metricTransformations.get(item) != originMetricTransformations.get(item):
  110. change = True
  111. else:
  112. change = True
  113. defaultValue = metricTransformations.get("default_value")
  114. if isinstance(defaultValue, int) or isinstance(defaultValue, float):
  115. retval = [
  116. {
  117. 'metricName': metricTransformations.get("metric_name"),
  118. 'metricNamespace': metricTransformations.get("metric_namespace"),
  119. 'metricValue': metricTransformations.get("metric_value"),
  120. 'defaultValue': defaultValue
  121. }
  122. ]
  123. else:
  124. retval = [
  125. {
  126. 'metricName': metricTransformations.get("metric_name"),
  127. 'metricNamespace': metricTransformations.get("metric_namespace"),
  128. 'metricValue': metricTransformations.get("metric_value"),
  129. }
  130. ]
  131. return retval, change
  132. def main():
  133. arg_spec = dict(
  134. state=dict(type='str', required=True, choices=['present', 'absent']),
  135. log_group_name=dict(type='str', required=True),
  136. filter_name=dict(type='str', required=True),
  137. filter_pattern=dict(type='str'),
  138. metric_transformation=dict(type='dict', options=dict(
  139. metric_name=dict(type='str'),
  140. metric_namespace=dict(type='str'),
  141. metric_value=dict(type='str'),
  142. default_value=dict(type='float')
  143. )),
  144. )
  145. module = AnsibleAWSModule(
  146. argument_spec=arg_spec,
  147. supports_check_mode=True,
  148. required_if=[('state', 'present', ['metric_transformation', 'filter_pattern'])]
  149. )
  150. log_group_name = module.params.get("log_group_name")
  151. filter_name = module.params.get("filter_name")
  152. filter_pattern = module.params.get("filter_pattern")
  153. metric_transformation = module.params.get("metric_transformation")
  154. state = module.params.get("state")
  155. cwl = module.client('logs')
  156. # check if metric filter exists
  157. response = cwl.describe_metric_filters(
  158. logGroupName=log_group_name,
  159. filterNamePrefix=filter_name
  160. )
  161. if len(response.get("metricFilters")) == 1:
  162. originMetricTransformations = response.get(
  163. "metricFilters")[0].get("metricTransformations")[0]
  164. originFilterPattern = response.get("metricFilters")[
  165. 0].get("filterPattern")
  166. else:
  167. originMetricTransformations = None
  168. originFilterPattern = None
  169. change = False
  170. metricTransformation = None
  171. if state == "absent" and originMetricTransformations:
  172. if not module.check_mode:
  173. response = cwl.delete_metric_filter(
  174. logGroupName=log_group_name,
  175. filterName=filter_name
  176. )
  177. change = True
  178. metricTransformation = [camel_dict_to_snake_dict(item) for item in [originMetricTransformations]]
  179. elif state == "present":
  180. metricTransformation, change = metricTransformationHandler(
  181. metricTransformations=metric_transformation, originMetricTransformations=originMetricTransformations)
  182. change = change or filter_pattern != originFilterPattern
  183. if change:
  184. if not module.check_mode:
  185. response = cwl.put_metric_filter(
  186. logGroupName=log_group_name,
  187. filterName=filter_name,
  188. filterPattern=filter_pattern,
  189. metricTransformations=metricTransformation
  190. )
  191. metricTransformation = [camel_dict_to_snake_dict(item) for item in metricTransformation]
  192. module.exit_json(changed=change, metric_filters=metricTransformation)
  193. if __name__ == '__main__':
  194. main()