mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-25 13:34:01 -07:00 
			
		
		
		
	Use semantic markup (modules r-s) (#6683)
* Use semantic markup.
* Use 'ignore:' for alias reference.
* Ignore sanity errors for older ansible-core versions.
* Improve markup for RHSM modules.
Co-authored-by: Pino Toscano <ptoscano@redhat.com>
* 'ignore:' is no longer needed.
* E() now works better.
---------
Co-authored-by: Pino Toscano <ptoscano@redhat.com>
(cherry picked from commit eff0cb0ed9)
Co-authored-by: Felix Fontein <felix@fontein.de>
		
	
			
		
			
				
	
	
		
			280 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| # Copyright (c) 2015, Matt Makai <matthew.makai@gmail.com>
 | |
| # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
 | |
| # SPDX-License-Identifier: GPL-3.0-or-later
 | |
| 
 | |
| from __future__ import absolute_import, division, print_function
 | |
| __metaclass__ = type
 | |
| 
 | |
| 
 | |
| DOCUMENTATION = r'''
 | |
| ---
 | |
| module: sendgrid
 | |
| short_description: Sends an email with the SendGrid API
 | |
| description:
 | |
|   - "Sends an email with a SendGrid account through their API, not through
 | |
|     the SMTP service."
 | |
| notes:
 | |
|   - "This module is non-idempotent because it sends an email through the
 | |
|     external API. It is idempotent only in the case that the module fails."
 | |
|   - "Like the other notification modules, this one requires an external
 | |
|     dependency to work. In this case, you'll need an active SendGrid
 | |
|     account."
 | |
|   - "In order to use api_key, cc, bcc, attachments, from_name, html_body, headers
 | |
|     you must pip install sendgrid"
 | |
|   - "Since Ansible 2.2 O(username) and O(password) are not required if you supply an O(api_key)"
 | |
| requirements:
 | |
|   - sendgrid Python library 1.6.22 or lower (Sendgrid API V2 supported)
 | |
| extends_documentation_fragment:
 | |
|   - community.general.attributes
 | |
| attributes:
 | |
|   check_mode:
 | |
|     support: full
 | |
|   diff_mode:
 | |
|     support: none
 | |
| options:
 | |
|   username:
 | |
|     type: str
 | |
|     description:
 | |
|       - Username for logging into the SendGrid account.
 | |
|       - Since 2.2 it is only required if O(api_key) is not supplied.
 | |
|   password:
 | |
|     type: str
 | |
|     description:
 | |
|       - Password that corresponds to the username.
 | |
|       - Since 2.2 it is only required if O(api_key) is not supplied.
 | |
|   from_address:
 | |
|     type: str
 | |
|     description:
 | |
|       - The address in the "from" field for the email.
 | |
|     required: true
 | |
|   to_addresses:
 | |
|     type: list
 | |
|     elements: str
 | |
|     description:
 | |
|       - A list with one or more recipient email addresses.
 | |
|     required: true
 | |
|   subject:
 | |
|     type: str
 | |
|     description:
 | |
|       - The desired subject for the email.
 | |
|     required: true
 | |
|   api_key:
 | |
|     type: str
 | |
|     description:
 | |
|       - Sendgrid API key to use instead of username/password.
 | |
|   cc:
 | |
|     type: list
 | |
|     elements: str
 | |
|     description:
 | |
|       - A list of email addresses to cc.
 | |
|   bcc:
 | |
|     type: list
 | |
|     elements: str
 | |
|     description:
 | |
|       - A list of email addresses to bcc.
 | |
|   attachments:
 | |
|     type: list
 | |
|     elements: path
 | |
|     description:
 | |
|       - A list of relative or explicit paths of files you want to attach (7MB limit as per SendGrid docs).
 | |
|   from_name:
 | |
|     type: str
 | |
|     description:
 | |
|       - The name you want to appear in the from field, i.e 'John Doe'.
 | |
|   html_body:
 | |
|     description:
 | |
|       - Whether the body is html content that should be rendered.
 | |
|     type: bool
 | |
|     default: false
 | |
|   headers:
 | |
|     type: dict
 | |
|     description:
 | |
|       - A dict to pass on as headers.
 | |
|   body:
 | |
|     type: str
 | |
|     description:
 | |
|       - The e-mail body content.
 | |
|     required: true
 | |
| author: "Matt Makai (@makaimc)"
 | |
| '''
 | |
| 
 | |
| EXAMPLES = r'''
 | |
| - name: Send an email to a single recipient that the deployment was successful
 | |
|   community.general.sendgrid:
 | |
|     username: "{{ sendgrid_username }}"
 | |
|     password: "{{ sendgrid_password }}"
 | |
|     from_address: "ansible@mycompany.com"
 | |
|     to_addresses:
 | |
|       - "ops@mycompany.com"
 | |
|     subject: "Deployment success."
 | |
|     body: "The most recent Ansible deployment was successful."
 | |
|   delegate_to: localhost
 | |
| 
 | |
| - name: Send an email to more than one recipient that the build failed
 | |
|   community.general.sendgrid:
 | |
|       username: "{{ sendgrid_username }}"
 | |
|       password: "{{ sendgrid_password }}"
 | |
|       from_address: "build@mycompany.com"
 | |
|       to_addresses:
 | |
|         - "ops@mycompany.com"
 | |
|         - "devteam@mycompany.com"
 | |
|       subject: "Build failure!."
 | |
|       body: "Unable to pull source repository from Git server."
 | |
|   delegate_to: localhost
 | |
| '''
 | |
| 
 | |
| # =======================================
 | |
| # sendgrid module support methods
 | |
| #
 | |
| import os
 | |
| import traceback
 | |
| 
 | |
| from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
 | |
| 
 | |
| SENDGRID_IMP_ERR = None
 | |
| try:
 | |
|     import sendgrid
 | |
|     HAS_SENDGRID = True
 | |
| except ImportError:
 | |
|     SENDGRID_IMP_ERR = traceback.format_exc()
 | |
|     HAS_SENDGRID = False
 | |
| 
 | |
| from ansible.module_utils.basic import AnsibleModule, missing_required_lib
 | |
| from ansible.module_utils.six.moves.urllib.parse import urlencode
 | |
| from ansible.module_utils.common.text.converters import to_bytes
 | |
| from ansible.module_utils.urls import fetch_url
 | |
| 
 | |
| 
 | |
| def post_sendgrid_api(module, username, password, from_address, to_addresses,
 | |
|                       subject, body, api_key=None, cc=None, bcc=None, attachments=None,
 | |
|                       html_body=False, from_name=None, headers=None):
 | |
| 
 | |
|     if not HAS_SENDGRID:
 | |
|         SENDGRID_URI = "https://api.sendgrid.com/api/mail.send.json"
 | |
|         AGENT = "Ansible"
 | |
|         data = {'api_user': username, 'api_key': password,
 | |
|                 'from': from_address, 'subject': subject, 'text': body}
 | |
|         encoded_data = urlencode(data)
 | |
|         to_addresses_api = ''
 | |
|         for recipient in to_addresses:
 | |
|             recipient = to_bytes(recipient, errors='surrogate_or_strict')
 | |
|             to_addresses_api += '&to[]=%s' % recipient
 | |
|         encoded_data += to_addresses_api
 | |
| 
 | |
|         headers = {'User-Agent': AGENT,
 | |
|                    'Content-type': 'application/x-www-form-urlencoded',
 | |
|                    'Accept': 'application/json'}
 | |
|         return fetch_url(module, SENDGRID_URI, data=encoded_data, headers=headers, method='POST')
 | |
|     else:
 | |
|         # Remove this check when adding Sendgrid API v3 support
 | |
|         if LooseVersion(sendgrid.version.__version__) > LooseVersion("1.6.22"):
 | |
|             module.fail_json(msg="Please install sendgrid==1.6.22 or lower since module uses Sendgrid V2 APIs.")
 | |
| 
 | |
|         if api_key:
 | |
|             sg = sendgrid.SendGridClient(api_key)
 | |
|         else:
 | |
|             sg = sendgrid.SendGridClient(username, password)
 | |
| 
 | |
|         message = sendgrid.Mail()
 | |
|         message.set_subject(subject)
 | |
| 
 | |
|         for recip in to_addresses:
 | |
|             message.add_to(recip)
 | |
| 
 | |
|         if cc:
 | |
|             for recip in cc:
 | |
|                 message.add_cc(recip)
 | |
|         if bcc:
 | |
|             for recip in bcc:
 | |
|                 message.add_bcc(recip)
 | |
| 
 | |
|         if headers:
 | |
|             message.set_headers(headers)
 | |
| 
 | |
|         if attachments:
 | |
|             for f in attachments:
 | |
|                 name = os.path.basename(f)
 | |
|                 message.add_attachment(name, f)
 | |
| 
 | |
|         if from_name:
 | |
|             message.set_from('%s <%s.' % (from_name, from_address))
 | |
|         else:
 | |
|             message.set_from(from_address)
 | |
| 
 | |
|         if html_body:
 | |
|             message.set_html(body)
 | |
|         else:
 | |
|             message.set_text(body)
 | |
| 
 | |
|         return sg.send(message)
 | |
| # =======================================
 | |
| # Main
 | |
| #
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     module = AnsibleModule(
 | |
|         argument_spec=dict(
 | |
|             username=dict(required=False),
 | |
|             password=dict(required=False, no_log=True),
 | |
|             api_key=dict(required=False, no_log=True),
 | |
|             bcc=dict(required=False, type='list', elements='str'),
 | |
|             cc=dict(required=False, type='list', elements='str'),
 | |
|             headers=dict(required=False, type='dict'),
 | |
|             from_address=dict(required=True),
 | |
|             from_name=dict(required=False),
 | |
|             to_addresses=dict(required=True, type='list', elements='str'),
 | |
|             subject=dict(required=True),
 | |
|             body=dict(required=True),
 | |
|             html_body=dict(required=False, default=False, type='bool'),
 | |
|             attachments=dict(required=False, type='list', elements='path')
 | |
|         ),
 | |
|         supports_check_mode=True,
 | |
|         mutually_exclusive=[
 | |
|             ['api_key', 'password'],
 | |
|             ['api_key', 'username']
 | |
|         ],
 | |
|         required_together=[['username', 'password']],
 | |
|     )
 | |
| 
 | |
|     username = module.params['username']
 | |
|     password = module.params['password']
 | |
|     api_key = module.params['api_key']
 | |
|     bcc = module.params['bcc']
 | |
|     cc = module.params['cc']
 | |
|     headers = module.params['headers']
 | |
|     from_name = module.params['from_name']
 | |
|     from_address = module.params['from_address']
 | |
|     to_addresses = module.params['to_addresses']
 | |
|     subject = module.params['subject']
 | |
|     body = module.params['body']
 | |
|     html_body = module.params['html_body']
 | |
|     attachments = module.params['attachments']
 | |
| 
 | |
|     sendgrid_lib_args = [api_key, bcc, cc, headers, from_name, html_body, attachments]
 | |
| 
 | |
|     if any(lib_arg is not None for lib_arg in sendgrid_lib_args) and not HAS_SENDGRID:
 | |
|         reason = 'when using any of the following arguments: ' \
 | |
|                  'api_key, bcc, cc, headers, from_name, html_body, attachments'
 | |
|         module.fail_json(msg=missing_required_lib('sendgrid', reason=reason),
 | |
|                          exception=SENDGRID_IMP_ERR)
 | |
| 
 | |
|     response, info = post_sendgrid_api(module, username, password,
 | |
|                                        from_address, to_addresses, subject, body, attachments=attachments,
 | |
|                                        bcc=bcc, cc=cc, headers=headers, html_body=html_body, api_key=api_key)
 | |
| 
 | |
|     if not HAS_SENDGRID:
 | |
|         if info['status'] != 200:
 | |
|             module.fail_json(msg="unable to send email through SendGrid API: %s" % info['msg'])
 | |
|     else:
 | |
|         if response != 200:
 | |
|             module.fail_json(msg="unable to send email through SendGrid API: %s" % info['message'])
 | |
| 
 | |
|     module.exit_json(msg=subject, changed=False)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |