PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/returners/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/returners/smtp_return.py |
""" Return salt data via email The following fields can be set in the minion conf file. Fields are optional unless noted otherwise. * ``from`` (required) The name/address of the email sender. * ``to`` (required) The names/addresses of the email recipients; comma-delimited. For example: ``you@example.com,someoneelse@example.com``. * ``host`` (required) The SMTP server hostname or address. * ``port`` The SMTP server port; defaults to ``25``. * ``username`` The username used to authenticate to the server. If specified a password is also required. It is recommended but not required to also use TLS with this option. * ``password`` The password used to authenticate to the server. * ``tls`` Whether to secure the connection using TLS; defaults to ``False`` * ``subject`` The email subject line. * ``fields`` Which fields from the returned data to include in the subject line of the email; comma-delimited. For example: ``id,fun``. Please note, *the subject line is not encrypted*. * ``gpgowner`` A user's :file:`~/.gpg` directory. This must contain a gpg public key matching the address the mail is sent to. If left unset, no encryption will be used. Requires :program:`python-gnupg` to be installed. * ``template`` The path to a file to be used as a template for the email body. * ``renderer`` A Salt renderer, or render-pipe, to use to render the email template. Default ``jinja``. Below is an example of the above settings in a Salt Minion configuration file: .. code-block:: yaml smtp.from: me@example.net smtp.to: you@example.com smtp.host: localhost smtp.port: 1025 Alternative configuration values can be used by prefacing the configuration. Any values not found in the alternative configuration will be pulled from the default location. For example: .. code-block:: yaml alternative.smtp.username: saltdev alternative.smtp.password: saltdev alternative.smtp.tls: True To use the SMTP returner, append '--return smtp' to the ``salt`` command. .. code-block:: bash salt '*' test.ping --return smtp To use the alternative configuration, append '--return_config alternative' to the ``salt`` command. .. versionadded:: 2015.5.0 .. code-block:: bash salt '*' test.ping --return smtp --return_config alternative To override individual configuration items, append --return_kwargs '{"key:": "value"}' to the ``salt`` command. .. versionadded:: 2016.3.0 .. code-block:: bash salt '*' test.ping --return smtp --return_kwargs '{"to": "user@domain.com"}' An easy way to test the SMTP returner is to use the development SMTP server built into Python. The command below will start a single-threaded SMTP server that prints any email it receives to the console. .. code-block:: python python -m smtpd -n -c DebuggingServer localhost:1025 .. versionadded:: 2016.11.0 It is possible to send emails with selected Salt events by configuring ``event_return`` option for Salt Master. For example: .. code-block:: yaml event_return: smtp event_return_whitelist: - salt/key smtp.from: me@example.net smtp.to: you@example.com smtp.host: localhost smtp.subject: 'Salt Master {{act}}ed key from Minion ID: {{id}}' smtp.template: /srv/salt/templates/email.j2 Also you need to create additional file ``/srv/salt/templates/email.j2`` with email body template: .. code-block:: yaml act: {{act}} id: {{id}} result: {{result}} This configuration enables Salt Master to send an email when accepting or rejecting minions keys. """ import io import logging import os import smtplib from email.utils import formatdate import salt.loader import salt.returners import salt.utils.jid from salt.template import compile_template try: import gnupg HAS_GNUPG = True except ImportError: HAS_GNUPG = False log = logging.getLogger(__name__) __virtualname__ = "smtp" def __virtual__(): return __virtualname__ def _get_options(ret=None): """ Get the SMTP options from salt. """ attrs = { "from": "from", "to": "to", "host": "host", "port": "port", "username": "username", "password": "password", "subject": "subject", "gpgowner": "gpgowner", "fields": "fields", "tls": "tls", "renderer": "renderer", "template": "template", } _options = salt.returners.get_returner_options( __virtualname__, ret, attrs, __salt__=__salt__, __opts__=__opts__ ) return _options def returner(ret): """ Send an email with the data """ _options = _get_options(ret) from_addr = _options.get("from") to_addrs = _options.get("to").split(",") host = _options.get("host") port = _options.get("port") user = _options.get("username") passwd = _options.get("password") subject = _options.get("subject") or "Email from Salt" gpgowner = _options.get("gpgowner") fields = _options.get("fields").split(",") if "fields" in _options else [] smtp_tls = _options.get("tls") renderer = _options.get("renderer") or "jinja" rend = salt.loader.render(__opts__, {}) blacklist = __opts__.get("renderer_blacklist") whitelist = __opts__.get("renderer_whitelist") if not port: port = 25 log.debug("SMTP port has been set to %s", port) for field in fields: if field in ret: subject += f" {ret[field]}" subject = compile_template( ":string:", rend, renderer, blacklist, whitelist, input_data=subject, **ret ) if isinstance(subject, io.StringIO): subject = subject.read() log.debug("smtp_return: Subject is '%s'", subject) template = _options.get("template") if template: content = compile_template( template, rend, renderer, blacklist, whitelist, **ret ) else: template = ( "id: {{id}}\r\n" "function: {{fun}}\r\n" "function args: {{fun_args}}\r\n" "jid: {{jid}}\r\n" "return: {{return}}\r\n" ) content = compile_template( ":string:", rend, renderer, blacklist, whitelist, input_data=template, **ret ) if gpgowner: if HAS_GNUPG: gpg = gnupg.GPG( gnupghome=os.path.expanduser(f"~{gpgowner}/.gnupg"), options=["--trust-model always"], ) encrypted_data = gpg.encrypt(content, to_addrs) if encrypted_data.ok: log.debug("smtp_return: Encryption successful") content = str(encrypted_data) else: log.error( "smtp_return: Encryption failed, only an error message will be sent" ) content = "Encryption failed, the return data was not sent.\r\n\r\n{}\r\n{}".format( encrypted_data.status, encrypted_data.stderr ) else: log.error( "gnupg python module is required in order to user gpgowner in smtp" " returner ; ignoring gpgowner configuration for now" ) if isinstance(content, io.StringIO): content = content.read() message = "From: {}\r\nTo: {}\r\nDate: {}\r\nSubject: {}\r\n\r\n{}".format( from_addr, ", ".join(to_addrs), formatdate(localtime=True), subject, content ) log.debug("smtp_return: Connecting to the server...") server = smtplib.SMTP(host, int(port)) if smtp_tls is True: server.starttls() log.debug("smtp_return: TLS enabled") if user and passwd: server.login(user, passwd) log.debug("smtp_return: Authenticated") # enable logging SMTP session after the login credentials were passed server.set_debuglevel(1) server.sendmail(from_addr, to_addrs, message) log.debug("smtp_return: Message sent.") server.quit() def prep_jid(nocache=False, passed_jid=None): # pylint: disable=unused-argument """ Do any work necessary to prepare a JID, including sending a custom id """ return passed_jid if passed_jid is not None else salt.utils.jid.gen_jid(__opts__) def event_return(events): """ Return event data via SMTP """ for event in events: ret = event.get("data", False) if ret: returner(ret)