1"""
2Module for sending messages to Mattermost
3
4.. versionadded:: 2017.7.0
5
6:configuration: This module can be used by either passing an api_url and hook
7    directly or by specifying both in a configuration profile in the salt
8    master/minion config. For example:
9
10    .. code-block:: yaml
11
12        mattermost:
13          hook: peWcBiMOS9HrZG15peWcBiMOS9HrZG15
14          api_url: https://example.com
15"""
16
17
18import logging
19
20import salt.utils.json
21
22# pylint: disable=import-error,no-name-in-module,redefined-builtin
23import salt.utils.mattermost
24
25# pylint: enable=import-error,no-name-in-module
26from salt.exceptions import SaltInvocationError
27
28log = logging.getLogger(__name__)
29
30__virtualname__ = "mattermost"
31
32
33def __virtual__():
34    """
35    Return virtual name of the module.
36    :return: The virtual name of the module.
37    """
38    return __virtualname__
39
40
41def _get_hook():
42    """
43    Retrieves and return the Mattermost's configured hook
44    :return:            String: the hook string
45    """
46    hook = __salt__["config.get"]("mattermost.hook") or __salt__["config.get"](
47        "mattermost:hook"
48    )
49    if not hook:
50        raise SaltInvocationError("No Mattermost Hook found")
51
52    return hook
53
54
55def _get_api_url():
56    """
57    Retrieves and return the Mattermost's configured api url
58    :return:            String: the api url string
59    """
60    api_url = __salt__["config.get"]("mattermost.api_url") or __salt__["config.get"](
61        "mattermost:api_url"
62    )
63    if not api_url:
64        raise SaltInvocationError("No Mattermost API URL found")
65
66    return api_url
67
68
69def _get_channel():
70    """
71    Retrieves the Mattermost's configured channel
72    :return:            String: the channel string
73    """
74    channel = __salt__["config.get"]("mattermost.channel") or __salt__["config.get"](
75        "mattermost:channel"
76    )
77
78    return channel
79
80
81def _get_username():
82    """
83    Retrieves the Mattermost's configured username
84    :return:            String: the username string
85    """
86    username = __salt__["config.get"]("mattermost.username") or __salt__["config.get"](
87        "mattermost:username"
88    )
89
90    return username
91
92
93def post_message(message, channel=None, username=None, api_url=None, hook=None):
94    """
95    Send a message to a Mattermost channel.
96    :param channel:     The channel name, either will work.
97    :param username:    The username of the poster.
98    :param message:     The message to send to the Mattermost channel.
99    :param api_url:     The Mattermost api url, if not specified in the configuration.
100    :param hook:        The Mattermost hook, if not specified in the configuration.
101    :return:            Boolean if message was sent successfully.
102
103    CLI Example:
104
105    .. code-block:: bash
106
107        salt-run mattermost.post_message message='Build is done'
108    """
109    if not api_url:
110        api_url = _get_api_url()
111
112    if not hook:
113        hook = _get_hook()
114
115    if not username:
116        username = _get_username()
117
118    if not channel:
119        channel = _get_channel()
120
121    if not message:
122        log.error("message is a required option.")
123
124    parameters = dict()
125    if channel:
126        parameters["channel"] = channel
127    if username:
128        parameters["username"] = username
129    parameters["text"] = "```" + message + "```"  # pre-formatted, fixed-width text
130    log.debug("Parameters: %s", parameters)
131    data = salt.utils.json.dumps(parameters)
132    result = salt.utils.mattermost.query(
133        api_url=api_url, hook=hook, data="payload={}".format(data)
134    )
135
136    if result:
137        return True
138    else:
139        return result
140
141
142def post_event(event, channel=None, username=None, api_url=None, hook=None):
143    """
144    Send an event to a Mattermost channel.
145    :param channel:     The channel name, either will work.
146    :param username:    The username of the poster.
147    :param event:       The event to send to the Mattermost channel.
148    :param api_url:     The Mattermost api url, if not specified in the configuration.
149    :param hook:        The Mattermost hook, if not specified in the configuration.
150    :return:            Boolean if message was sent successfully.
151    """
152    if not api_url:
153        api_url = _get_api_url()
154
155    if not hook:
156        hook = _get_hook()
157
158    if not username:
159        username = _get_username()
160
161    if not channel:
162        channel = _get_channel()
163
164    if not event:
165        log.error("message is a required option.")
166
167    log.debug("Event: %s", event)
168    log.debug("Event data: %s", event["data"])
169    message = "tag: {}\r\n".format(event["tag"])
170    for key, value in event["data"].items():
171        message += "{}: {}\r\n".format(key, value)
172    result = post_message(
173        message, channel=channel, username=username, api_url=api_url, hook=hook
174    )
175    return bool(result)
176