forked from DimensionDataResearch/salt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request saltstack#40356 from mchugh19/develop
Initial support for sending message cards to Microsoft Teams
- Loading branch information
Showing
2 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# -*- coding: utf-8 -*- | ||
''' | ||
Module for sending messages to MS Teams | ||
.. versionadded:: Nitrogen | ||
:configuration: This module can be used by either passing a hook_url | ||
directly or by specifying it in a configuration profile in the salt | ||
master/minion config. | ||
For example: | ||
.. code-block:: yaml | ||
msteams: | ||
hook_url: https://outlook.office.com/webhook/837 | ||
''' | ||
|
||
|
||
# Import Python libs | ||
from __future__ import absolute_import | ||
import json | ||
import logging | ||
|
||
# Import 3rd-party libs | ||
# pylint: disable=import-error,no-name-in-module,redefined-builtin | ||
import salt.ext.six.moves.http_client | ||
|
||
from salt.exceptions import SaltInvocationError | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
__virtualname__ = 'msteams' | ||
|
||
|
||
def __virtual__(): | ||
''' | ||
Return virtual name of the module. | ||
:return: The virtual name of the module. | ||
''' | ||
return __virtualname__ | ||
|
||
|
||
def _get_hook_url(): | ||
''' | ||
Return hook_url from minion/master config file | ||
or from pillar | ||
''' | ||
hook_url = __salt__['config.get']('msteams.hook_url') or \ | ||
__salt__['config.get']('msteams:hook_url') | ||
|
||
if not hook_url: | ||
raise SaltInvocationError('No MS Teams hook_url found.') | ||
|
||
return hook_url | ||
|
||
|
||
def post_card(message, | ||
hook_url=None, | ||
title=None, | ||
theme_color=None): | ||
''' | ||
Send a message to an MS Teams channel. | ||
:param message: The message to send to the MS Teams channel. | ||
:param hook_url: The Teams webhook URL, if not specified in the configuration. | ||
:param title: Optional title for the posted card | ||
:param theme_color: Optional hex color highlight for the posted card | ||
:return: Boolean if message was sent successfully. | ||
CLI Example: | ||
.. code-block:: bash | ||
salt '*' msteams.post_card message="Build is done" | ||
''' | ||
|
||
if not hook_url: | ||
hook_url = _get_hook_url() | ||
|
||
if not message: | ||
log.error('message is a required option.') | ||
|
||
payload = { | ||
"text": message, | ||
"title": title, | ||
"theme_color": theme_color | ||
} | ||
|
||
result = salt.utils.http.query(hook_url, method='POST', data=json.dumps(payload), status=True) | ||
|
||
if result['status'] <= 201: | ||
return True | ||
else: | ||
return { | ||
'res': False, | ||
'message': result.get('body', result['status']) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# -*- coding: utf-8 -*- | ||
''' | ||
Send a message card to Microsoft Teams | ||
======================= | ||
This state is useful for sending messages to Teams during state runs. | ||
.. versionadded:: Nitrogen | ||
.. code-block:: yaml | ||
teams-message: | ||
msteams.post_card: | ||
- message: 'This state was executed successfully.' | ||
- hook_url: https://outlook.office.com/webhook/837 | ||
The hook_url can be specified in the master or minion configuration like below: | ||
.. code-block:: yaml | ||
msteams: | ||
hook_url: https://outlook.office.com/webhook/837 | ||
''' | ||
|
||
# Import Python libs | ||
from __future__ import absolute_import | ||
|
||
# Import Salt libs | ||
from salt.exceptions import SaltInvocationError | ||
|
||
|
||
def __virtual__(): | ||
''' | ||
Only load if the msteams module is available in __salt__ | ||
''' | ||
return 'msteams' if 'msteams.post_card' in __salt__ else False | ||
|
||
|
||
def post_card(name, | ||
message, | ||
hook_url=None, | ||
title=None, | ||
theme_color=None): | ||
''' | ||
Send a message to a Microsft Teams channel. | ||
.. code-block:: yaml | ||
send-msteams-message: | ||
msteams.post_card: | ||
- message: 'This state was executed successfully.' | ||
- hook_url: https://outlook.office.com/webhook/837 | ||
The following parameters are required: | ||
message | ||
The message that is to be sent to the MS Teams channel. | ||
The following parameters are optional: | ||
hook_url | ||
The webhook URL given configured in Teams interface, | ||
if not specified in the configuration options of master or minion. | ||
title | ||
The title for the card posted to the channel | ||
theme_color | ||
A hex code for the desired highlight color | ||
''' | ||
ret = {'name': name, | ||
'changes': {}, | ||
'result': False, | ||
'comment': ''} | ||
|
||
if __opts__['test']: | ||
ret['comment'] = 'The following message is to be sent to Teams: {0}'.format(message) | ||
ret['result'] = None | ||
return ret | ||
|
||
if not message: | ||
ret['comment'] = 'Teams message is missing: {0}'.format(message) | ||
return ret | ||
|
||
try: | ||
result = __salt__['msteams.post_card']( | ||
message=message, | ||
hook_url=hook_url, | ||
title=title, | ||
theme_color=theme_color, | ||
) | ||
except SaltInvocationError as sie: | ||
ret['comment'] = 'Failed to send message ({0}): {1}'.format(sie, name) | ||
else: | ||
if isinstance(result, bool) and result: | ||
ret['result'] = True | ||
ret['comment'] = 'Sent message: {0}'.format(name) | ||
else: | ||
ret['comment'] = 'Failed to send message ({0}): {1}'.format(result['message'], name) | ||
|
||
return ret |