mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #38531 from rallytime/bp-33601
Back-port #33601 to 2016.3
This commit is contained in:
commit
0056620a53
1 changed files with 66 additions and 33 deletions
|
@ -20,18 +20,26 @@ prefaced with a ``!``.
|
|||
valid_commands:
|
||||
- test.ping
|
||||
- cmd.run
|
||||
- list_jobs
|
||||
- list_commands
|
||||
aliases:
|
||||
list_jobs:
|
||||
type: runner
|
||||
cmd: jobs.list_jobs
|
||||
list_commands:
|
||||
cmd: pillar.get salt:engines:slack:valid_commands target=saltmaster
|
||||
|
||||
:depends: slackclient
|
||||
'''
|
||||
|
||||
# Import python libraries
|
||||
from __future__ import absolute_import
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
import pprint
|
||||
import time
|
||||
import re
|
||||
import yaml
|
||||
|
||||
try:
|
||||
import slackclient
|
||||
HAS_SLACKCLIENT = True
|
||||
|
@ -49,10 +57,7 @@ import salt.utils.slack
|
|||
|
||||
|
||||
def __virtual__():
|
||||
if not HAS_SLACKCLIENT:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
return HAS_SLACKCLIENT
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -62,16 +67,16 @@ def _get_users(token):
|
|||
Get all users from Slack
|
||||
'''
|
||||
|
||||
log.debug('running _get_users')
|
||||
ret = salt.utils.slack.query(function='users',
|
||||
api_key=token,
|
||||
opts=__opts__)
|
||||
users = {}
|
||||
if 'message' in ret:
|
||||
for item in ret['message']:
|
||||
if not item['is_bot']:
|
||||
users[item['name']] = item['id']
|
||||
users[item['id']] = item['name']
|
||||
if 'is_bot' in item:
|
||||
if not item['is_bot']:
|
||||
users[item['name']] = item['id']
|
||||
users[item['id']] = item['name']
|
||||
return users
|
||||
|
||||
|
||||
|
@ -92,18 +97,22 @@ def start(token,
|
|||
fire_master = None
|
||||
|
||||
def fire(tag, msg):
|
||||
'''
|
||||
Fire event to salt bus
|
||||
'''
|
||||
if fire_master:
|
||||
fire_master(msg, tag)
|
||||
else:
|
||||
__salt__['event.send'](tag, msg)
|
||||
|
||||
if not token:
|
||||
log.debug('Slack Bot token not found')
|
||||
return
|
||||
raise UserWarning('Slack Bot token not found')
|
||||
|
||||
all_users = _get_users(token)
|
||||
|
||||
sc = slackclient.SlackClient(token)
|
||||
slack_connect = sc.rtm_connect()
|
||||
log.debug('connected to slack')
|
||||
|
||||
runner_functions = sorted(salt.runner.Runner(__opts__).functions)
|
||||
|
||||
|
@ -118,6 +127,11 @@ def start(token,
|
|||
|
||||
# Edited messages have text in message
|
||||
_text = _m.get('text', None) or _m.get('message', {}).get('text', None)
|
||||
|
||||
# Convert UTF to string
|
||||
_text = json.dumps(_text)
|
||||
_text = yaml.safe_load(_text)
|
||||
|
||||
if _text:
|
||||
if _text.startswith('!') and control:
|
||||
|
||||
|
@ -131,6 +145,21 @@ def start(token,
|
|||
# Trim the ! from the front
|
||||
# cmdline = _text[1:].split(' ', 1)
|
||||
cmdline = salt.utils.shlex_split(_text[1:])
|
||||
|
||||
# Remove slack url parsing
|
||||
# Translate target=<http://host.domain.net|host.domain.net>
|
||||
# to target=host.domain.net
|
||||
cmdlist = []
|
||||
for cmditem in cmdline:
|
||||
pattern = r'(?P<begin>.*)(<.*\|)(?P<url>.*)(>)(?P<remainder>.*)'
|
||||
m = re.match(pattern, cmditem)
|
||||
if m:
|
||||
origtext = m.group('begin') + m.group('url') + m.group('remainder')
|
||||
cmdlist.append(origtext)
|
||||
else:
|
||||
cmdlist.append(cmditem)
|
||||
cmdline = cmdlist
|
||||
|
||||
cmd = cmdline[0]
|
||||
args = []
|
||||
kwargs = {}
|
||||
|
@ -141,6 +170,13 @@ def start(token,
|
|||
channel.send_message('Using {0} is not allowed.'.format(cmd))
|
||||
return
|
||||
|
||||
# Evaluate aliases
|
||||
if aliases and isinstance(aliases, dict) and cmd in aliases.keys():
|
||||
cmdline = aliases[cmd].get('cmd')
|
||||
cmdline = salt.utils.shlex_split(cmdline)
|
||||
cmd = cmdline[0]
|
||||
|
||||
# Parse args and kwargs
|
||||
if len(cmdline) > 1:
|
||||
for item in cmdline[1:]:
|
||||
if '=' in item:
|
||||
|
@ -149,6 +185,7 @@ def start(token,
|
|||
else:
|
||||
args.append(item)
|
||||
|
||||
# Check for target. Otherwise assume *
|
||||
if 'target' not in kwargs:
|
||||
target = '*'
|
||||
else:
|
||||
|
@ -156,39 +193,35 @@ def start(token,
|
|||
del kwargs['target']
|
||||
|
||||
ret = {}
|
||||
if aliases and isinstance(aliases, dict) and cmd in aliases.keys():
|
||||
salt_cmd = aliases[cmd].get('cmd')
|
||||
|
||||
if 'type' in aliases[cmd]:
|
||||
if aliases[cmd]['type'] == 'runner':
|
||||
runner = salt.runner.RunnerClient(__opts__)
|
||||
ret = runner.cmd(salt_cmd, arg=args, kwarg=kwargs)
|
||||
else:
|
||||
local = salt.client.LocalClient()
|
||||
ret = local.cmd('{0}'.format(target), salt_cmd, args, kwargs)
|
||||
|
||||
elif cmd in runner_functions:
|
||||
if cmd in runner_functions:
|
||||
runner = salt.runner.RunnerClient(__opts__)
|
||||
ret = runner.cmd(cmd, arg=args, kwarg=kwargs)
|
||||
|
||||
# default to trying to run as a client module.
|
||||
# Default to trying to run as a client module.
|
||||
else:
|
||||
local = salt.client.LocalClient()
|
||||
ret = local.cmd('{0}'.format(target), cmd, args, kwargs)
|
||||
|
||||
if ret:
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
return_text = pp.pformat(ret)
|
||||
# Slack messages need to be under 4000 characters.
|
||||
length = 4000
|
||||
if len(return_text) >= length:
|
||||
channel.send_message(return_text[0:3999])
|
||||
channel.send_message('Returned first 4k characters.')
|
||||
else:
|
||||
channel.send_message(return_text)
|
||||
return_text = json.dumps(ret, sort_keys=True, indent=1)
|
||||
ts = time.time()
|
||||
st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d%H%M%S%f')
|
||||
filename = 'salt-results-{0}.yaml'.format(st)
|
||||
result = sc.api_call(
|
||||
"files.upload", channels=_m['channel'], filename=filename,
|
||||
content=return_text
|
||||
)
|
||||
# Handle unicode return
|
||||
result = json.dumps(result)
|
||||
result = yaml.safe_load(result)
|
||||
if 'ok' in result and result['ok'] is False:
|
||||
channel.send_message('Error: {0}'.format(result['error']))
|
||||
else:
|
||||
# Fire event to event bus
|
||||
fire('{0}/{1}'.format(tag, _m['type']), _m)
|
||||
else:
|
||||
# Fire event to event bus
|
||||
fire('{0}/{1}'.format(tag, _m['type']), _m)
|
||||
else:
|
||||
raise UserWarning("Could not connect to slack")
|
||||
|
|
Loading…
Add table
Reference in a new issue