I’ve been working towards making things simpler when managing distributed resources at work. And since we spend most of our day in the chat room (was Slack, now Mattermost) I thought it’s best to get started with ChatOps
It’s just a fancy word for doing stuff right from the chat window. And there’s so much one can do, especially with simple Slash Commands.
Here’s a lambda function I setup yesterday for invalidating CloudFront distributions.
from time import time import boto3 import json import os import re EXPECTED_TOKEN = os.environ['mmToken'] ALLOWED_USERS = re.split('[, ]', os.environ['allowedUsers']) DISTRIBUTIONS = { 'site-name': 'DISTRIBUTIONID', 'another.site': 'DISTRIBUTIONID05' } def parse_command_text(command_text): pattern = r"({})\s+(.*)".format('|'.join(DISTRIBUTIONS.keys())) m = re.match(pattern, command_text) if m: return { 'site': m.group(1), 'path': path} else: return False def lambda_handler(event, context): # Parse the request try: request_data = event["queryStringParameters"] except: return { "statusCode": 400, "headers": {"Content-Type": "application/json"}, "body": '{ "message": "Use GET for setting up mattermost slash command" }' } # Check the token matches. if request_data.get("token", "") != EXPECTED_TOKEN: print('Wrong Token!') return { "statusCode": 401, "headers": {"Content-Type": "application/json"}, "body": '{ "message": "Mattermost token does not match" }' } # Check the user is allowed to run the command if request_data.get("user_name", "") not in ALLOWED_USERS: print('Wrong User! {} not in {}'.format(request_data['user_name'], ALLOWED_USERS)) return { "statusCode": 401, "headers": {"Content-Type": "application/json"}, "body": '{ "message": "User not allowed to perform action" }' } # parse the command command_text = request_data.get("text", "") if not command_text: print('Nothing to do, bailing out') return { "statusCode": 404, "headers": {"Content-Type": "application/json"}, "body": '{ "message": "No command text sent" }' } parts = parse_command_text(command_text) if not parts: print('Bad formatting - command: {}'.format(command_text)) return { "statusCode": 402, "headers": {"Content-Type": "application/json"}, "body": '{ "message": "Wrong pattern" }' } # Do the actual work cf_client = boto3.client('cloudfront') # Invalidate boto_response = cf_client.create_invalidation( DistributionId=DISTRIBUTIONS[parts['site']], InvalidationBatch={ 'Paths': { 'Quantity': len(parts['path']), 'Items': parts['path'] }, 'CallerReference': str(time()).replace(".", "") } )['Invalidation'] # Build the response message text. text = """##### Executing invalidation | Key | Info | | --- | ---- | | Site | {} | | Path | {} | | ID | {} | | Status | {} |""".format( parts['site'], parts['path'], boto_response['Id'], boto_response['Status'] ) # Build the response object. response = { "response_type": "in_channel", "text": text, } # Return the response as JSON return { "body": json.dumps(response), "headers": {"Content-Type": "application/json"}, "statusCode": 200, }
Note that you need to hook that up with an API Gateway in AWS. Once that’s done, you will have a URL endpoint ready for deployment.
Next, I created the slash command in

That’s pretty much it. Rinse and repeat for a different command, different usage.
On my list next is to have more interaction with the user in mattermost per https://docs.mattermost.com/developer/interactive-messages.html
Weekend Project, Yay!
No Comments
You can leave the first : )