mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-03 07:41:30 -07:00
* openstack: standardize tls params * tower: tower_verify_ssl->validate_certs * docker: use standard tls config params - cacert_path -> ca_cert - cert_path -> client_cert - key_path -> client_key - tls_verify -> validate_certs * k8s: standardize tls connection params - verify_ssl -> validate_certs - ssl_ca_cert -> ca_cert - cert_file -> client_cert - key_file -> client_key * ingate: verify_ssl -> validate_certs * manageiq: standardize tls params - verify_ssl -> validate_certs - ca_bundle_path -> ca_cert * mysql: standardize tls params - ssl_ca -> ca_cert - ssl_cert -> client_cert - ssl_key -> client_key * nios: ssl_verify -> validate_certs * postgresql: ssl_rootcert -> ca_cert * rabbitmq: standardize tls params - cacert -> ca_cert - cert -> client_cert - key -> client_key * rackspace: verify_ssl -> validate_certs * vca: verify_certs -> validate_certs * kubevirt_cdi_upload: upload_host_verify_ssl -> upload_host_validate_certs * lxd: standardize tls params - key_file -> client_key - cert_file -> client_cert * get_certificate: ca_certs -> ca_cert * get_certificate.py: clarify one or more certs in a file Co-Authored-By: jamescassell <code@james.cassell.me> * zabbix: tls_issuer -> ca_cert * bigip_device_auth_ldap: standardize tls params - ssl_check_peer -> validate_certs - ssl_client_cert -> client_cert - ssl_client_key -> client_key - ssl_ca_cert -> ca_cert * vdirect: vdirect_validate_certs -> validate_certs * mqtt: standardize tls params - ca_certs -> ca_cert - certfile -> client_cert - keyfile -> client_key * pulp_repo: standardize tls params remove `importer_ssl` prefix * rhn_register: sslcacert -> ca_cert * yum_repository: standardize tls params The fix for yum_repository is not straightforward since this module is only a thin wrapper for the underlying commands and config. In this case, we add the new values as aliases, keeping the old as primary, only due to the internal structure of the module. Aliases added: - sslcacert -> ca_cert - sslclientcert -> client_cert - sslclientkey -> client_key - sslverify -> validate_certs * gitlab_hook: enable_ssl_verification -> hook_validate_certs * Adjust arguments for docker_swarm inventory plugin. * foreman callback: standardize tls params - ssl_cert -> client_cert - ssl_key -> client_key * grafana_annotations: validate_grafana_certs -> validate_certs * nrdp callback: validate_nrdp_certs -> validate_certs * kubectl connection: standardize tls params - kubectl_cert_file -> client_cert - kubectl_key_file -> client_key - kubectl_ssl_ca_cert -> ca_cert - kubectl_verify_ssl -> validate_certs * oc connection: standardize tls params - oc_cert_file -> client_cert - oc_key_file -> client_key - oc_ssl_ca_cert -> ca_cert - oc_verify_ssl -> validate_certs * psrp connection: cert_trust_path -> ca_cert TODO: cert_validation -> validate_certs (multi-valued vs bool) * k8s inventory: standardize tls params - cert_file -> client_cert - key_file -> client_key - ca_cert -> ca_cert - verify_ssl -> validate_certs * openshift inventory: standardize tls params - cert_file -> client_cert - key_file -> client_key - ca_cert -> ca_cert - verify_ssl -> validate_certs * tower inventory: verify_ssl -> validate_certs * hashi_vault lookup: cacert -> ca_cert * k8s lookup: standardize tls params - cert_file -> client_cert - key_file -> client_key - ca_cert -> ca_cert - verify_ssl -> validate_certs * laps_passord lookup: cacert_file -> ca_cert * changelog for TLS parameter standardization
346 lines
13 KiB
Python
346 lines
13 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
# Copyright (c) 2017 Red Hat Inc.
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
'status': ['preview'],
|
|
'supported_by': 'community'}
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
module: manageiq_alerts
|
|
|
|
short_description: Configuration of alerts in ManageIQ
|
|
extends_documentation_fragment: manageiq
|
|
version_added: '2.5'
|
|
author: Elad Alfassa (@elad661) <ealfassa@redhat.com
|
|
description:
|
|
- The manageiq_alerts module supports adding, updating and deleting alerts in ManageIQ.
|
|
|
|
options:
|
|
state:
|
|
description:
|
|
- absent - alert should not exist,
|
|
- present - alert should exist,
|
|
required: False
|
|
choices: ['absent', 'present']
|
|
default: 'present'
|
|
description:
|
|
description:
|
|
- The unique alert description in ManageIQ.
|
|
- Required when state is "absent" or "present".
|
|
resource_type:
|
|
description:
|
|
- The entity type for the alert in ManageIQ. Required when state is "present".
|
|
choices: ['Vm', 'ContainerNode', 'MiqServer', 'Host', 'Storage', 'EmsCluster',
|
|
'ExtManagementSystem', 'MiddlewareServer']
|
|
expression_type:
|
|
description:
|
|
- Expression type.
|
|
default: hash
|
|
choices: ["hash", "miq"]
|
|
expression:
|
|
description:
|
|
- The alert expression for ManageIQ.
|
|
- Can either be in the "Miq Expression" format or the "Hash Expression format".
|
|
- Required if state is "present".
|
|
enabled:
|
|
description:
|
|
- Enable or disable the alert. Required if state is "present".
|
|
type: bool
|
|
options:
|
|
description:
|
|
- Additional alert options, such as notification type and frequency
|
|
|
|
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
- name: Add an alert with a "hash expression" to ManageIQ
|
|
manageiq_alerts:
|
|
state: present
|
|
description: Test Alert 01
|
|
options:
|
|
notifications:
|
|
email:
|
|
to: ["example@example.com"]
|
|
from: "example@example.com"
|
|
resource_type: ContainerNode
|
|
expression:
|
|
eval_method: hostd_log_threshold
|
|
mode: internal
|
|
options: {}
|
|
enabled: true
|
|
manageiq_connection:
|
|
url: 'http://127.0.0.1:3000'
|
|
username: 'admin'
|
|
password: 'smartvm'
|
|
validate_certs: False
|
|
|
|
- name: Add an alert with a "miq expression" to ManageIQ
|
|
manageiq_alerts:
|
|
state: present
|
|
description: Test Alert 02
|
|
options:
|
|
notifications:
|
|
email:
|
|
to: ["example@example.com"]
|
|
from: "example@example.com"
|
|
resource_type: Vm
|
|
expression_type: miq
|
|
expression:
|
|
and:
|
|
- CONTAINS:
|
|
tag: Vm.managed-environment
|
|
value: prod
|
|
- not:
|
|
CONTAINS:
|
|
tag: Vm.host.managed-environment
|
|
value: prod
|
|
enabled: true
|
|
manageiq_connection:
|
|
url: 'http://127.0.0.1:3000'
|
|
username: 'admin'
|
|
password: 'smartvm'
|
|
validate_certs: False
|
|
|
|
- name: Delete an alert from ManageIQ
|
|
manageiq_alerts:
|
|
state: absent
|
|
description: Test Alert 01
|
|
manageiq_connection:
|
|
url: 'http://127.0.0.1:3000'
|
|
username: 'admin'
|
|
password: 'smartvm'
|
|
validate_certs: False
|
|
'''
|
|
|
|
RETURN = '''
|
|
'''
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
from ansible.module_utils.manageiq import ManageIQ, manageiq_argument_spec
|
|
|
|
|
|
class ManageIQAlert(object):
|
|
""" Represent a ManageIQ alert. Can be initialized with both the format
|
|
we recieve from the server and the format we get from the user.
|
|
"""
|
|
def __init__(self, alert):
|
|
self.description = alert['description']
|
|
self.db = alert['db']
|
|
self.enabled = alert['enabled']
|
|
self.options = alert['options']
|
|
self.hash_expression = None
|
|
self.miq_expressipn = None
|
|
|
|
if 'hash_expression' in alert:
|
|
self.hash_expression = alert['hash_expression']
|
|
if 'miq_expression' in alert:
|
|
self.miq_expression = alert['miq_expression']
|
|
if 'exp' in self.miq_expression:
|
|
# miq_expression is a field that needs a special case, because
|
|
# it's returned surrounded by a dict named exp even though we don't
|
|
# send it with that dict.
|
|
self.miq_expression = self.miq_expression['exp']
|
|
|
|
def __eq__(self, other):
|
|
""" Compare two ManageIQAlert objects
|
|
"""
|
|
return self.__dict__ == other.__dict__
|
|
|
|
|
|
class ManageIQAlerts(object):
|
|
""" Object to execute alert management operations in manageiq.
|
|
"""
|
|
|
|
def __init__(self, manageiq):
|
|
self.manageiq = manageiq
|
|
|
|
self.module = self.manageiq.module
|
|
self.api_url = self.manageiq.api_url
|
|
self.client = self.manageiq.client
|
|
self.alerts_url = '{api_url}/alert_definitions'.format(api_url=self.api_url)
|
|
|
|
def get_alerts(self):
|
|
""" Get all alerts from ManageIQ
|
|
"""
|
|
try:
|
|
response = self.client.get(self.alerts_url + '?expand=resources')
|
|
except Exception as e:
|
|
self.module.fail_json(msg="Failed to query alerts: {error}".format(error=e))
|
|
return response.get('resources', [])
|
|
|
|
def validate_hash_expression(self, expression):
|
|
""" Validate a 'hash expression' alert definition
|
|
"""
|
|
# hash expressions must have the following fields
|
|
for key in ['options', 'eval_method', 'mode']:
|
|
if key not in expression:
|
|
msg = "Hash expression is missing required field {key}".format(key=key)
|
|
self.module.fail_json(msg)
|
|
|
|
def create_alert_dict(self, params):
|
|
""" Create a dict representing an alert
|
|
"""
|
|
if params['expression_type'] == 'hash':
|
|
# hash expression supports depends on https://github.com/ManageIQ/manageiq-api/pull/76
|
|
self.validate_hash_expression(params['expression'])
|
|
expression_type = 'hash_expression'
|
|
else:
|
|
# actually miq_expression, but we call it "expression" for backwards-compatibility
|
|
expression_type = 'expression'
|
|
|
|
# build the alret
|
|
alert = dict(description=params['description'],
|
|
db=params['resource_type'],
|
|
options=params['options'],
|
|
enabled=params['enabled'])
|
|
|
|
# add the actual expression.
|
|
alert.update({expression_type: params['expression']})
|
|
|
|
return alert
|
|
|
|
def add_alert(self, alert):
|
|
""" Add a new alert to ManageIQ
|
|
"""
|
|
try:
|
|
result = self.client.post(self.alerts_url, action='create', resource=alert)
|
|
|
|
msg = "Alert {description} created successfully: {details}"
|
|
msg = msg.format(description=alert['description'], details=result)
|
|
return dict(changed=True, msg=msg)
|
|
except Exception as e:
|
|
msg = "Creating alert {description} failed: {error}"
|
|
if "Resource expression needs be specified" in str(e):
|
|
# Running on an older version of ManageIQ and trying to create a hash expression
|
|
msg = msg.format(description=alert['description'],
|
|
error="Your version of ManageIQ does not support hash_expression")
|
|
else:
|
|
msg = msg.format(description=alert['description'], error=e)
|
|
self.module.fail_json(msg=msg)
|
|
|
|
def delete_alert(self, alert):
|
|
""" Delete an alert
|
|
"""
|
|
try:
|
|
result = self.client.post('{url}/{id}'.format(url=self.alerts_url,
|
|
id=alert['id']),
|
|
action="delete")
|
|
msg = "Alert {description} deleted: {details}"
|
|
msg = msg.format(description=alert['description'], details=result)
|
|
return dict(changed=True, msg=msg)
|
|
except Exception as e:
|
|
msg = "Deleting alert {description} failed: {error}"
|
|
msg = msg.format(description=alert['description'], error=e)
|
|
self.module.fail_json(msg=msg)
|
|
|
|
def update_alert(self, existing_alert, new_alert):
|
|
""" Update an existing alert with the values from `new_alert`
|
|
"""
|
|
new_alert_obj = ManageIQAlert(new_alert)
|
|
if new_alert_obj == ManageIQAlert(existing_alert):
|
|
# no change needed - alerts are identical
|
|
return dict(changed=False, msg="No update needed")
|
|
else:
|
|
try:
|
|
url = '{url}/{id}'.format(url=self.alerts_url, id=existing_alert['id'])
|
|
result = self.client.post(url, action="edit", resource=new_alert)
|
|
|
|
# make sure that the update was indeed successful by comparing
|
|
# the result to the expected result.
|
|
if new_alert_obj == ManageIQAlert(result):
|
|
# success!
|
|
msg = "Alert {description} upated successfully: {details}"
|
|
msg = msg.format(description=existing_alert['description'], details=result)
|
|
|
|
return dict(changed=True, msg=msg)
|
|
else:
|
|
# unexpected result
|
|
msg = "Updating alert {description} failed, unexpected result {details}"
|
|
msg = msg.format(description=existing_alert['description'], details=result)
|
|
|
|
self.module.fail_json(msg=msg)
|
|
|
|
except Exception as e:
|
|
msg = "Updating alert {description} failed: {error}"
|
|
if "Resource expression needs be specified" in str(e):
|
|
# Running on an older version of ManageIQ and trying to update a hash expression
|
|
msg = msg.format(description=existing_alert['description'],
|
|
error="Your version of ManageIQ does not support hash_expression")
|
|
else:
|
|
msg = msg.format(description=existing_alert['description'], error=e)
|
|
self.module.fail_json(msg=msg)
|
|
|
|
|
|
def main():
|
|
argument_spec = dict(
|
|
description=dict(type='str'),
|
|
resource_type=dict(type='str', choices=['Vm',
|
|
'ContainerNode',
|
|
'MiqServer',
|
|
'Host',
|
|
'Storage',
|
|
'EmsCluster',
|
|
'ExtManagementSystem',
|
|
'MiddlewareServer']),
|
|
expression_type=dict(type='str', default='hash', choices=['miq', 'hash']),
|
|
expression=dict(type='dict'),
|
|
options=dict(type='dict'),
|
|
enabled=dict(type='bool'),
|
|
state=dict(require=False, default='present',
|
|
choices=['present', 'absent']),
|
|
)
|
|
# add the manageiq connection arguments to the arguments
|
|
argument_spec.update(manageiq_argument_spec())
|
|
|
|
module = AnsibleModule(argument_spec=argument_spec,
|
|
required_if=[('state', 'present', ['description',
|
|
'resource_type',
|
|
'expression',
|
|
'enabled',
|
|
'options']),
|
|
('state', 'absent', ['description'])])
|
|
|
|
state = module.params['state']
|
|
description = module.params['description']
|
|
|
|
manageiq = ManageIQ(module)
|
|
manageiq_alerts = ManageIQAlerts(manageiq)
|
|
|
|
existing_alert = manageiq.find_collection_resource_by("alert_definitions",
|
|
description=description)
|
|
|
|
# we need to add or update the alert
|
|
if state == "present":
|
|
alert = manageiq_alerts.create_alert_dict(module.params)
|
|
|
|
if not existing_alert:
|
|
# an alert with this description doesn't exist yet, let's create it
|
|
res_args = manageiq_alerts.add_alert(alert)
|
|
else:
|
|
# an alert with this description exists, we might need to update it
|
|
res_args = manageiq_alerts.update_alert(existing_alert, alert)
|
|
|
|
# this alert should not exist
|
|
elif state == "absent":
|
|
# if we have an alert with this description, delete it
|
|
if existing_alert:
|
|
res_args = manageiq_alerts.delete_alert(existing_alert)
|
|
else:
|
|
# it doesn't exist, and that's okay
|
|
msg = "Alert '{description}' does not exist in ManageIQ"
|
|
msg = msg.format(description=description)
|
|
res_args = dict(changed=False, msg=msg)
|
|
|
|
module.exit_json(**res_args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|