#!/usr/bin/python3 # ============================================================================== # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== import base64 import re import uuid import datetime from optparse import OptionParser import os import sys import cfnbootstrap from cfnbootstrap import util from cfnbootstrap.packages import requests import json parser = OptionParser(usage="usage: %prog [options] [Command Event Message]") parser.add_option_group(util.get_proxy_options(parser)) parser.add_option("", "--event-handle", help="Event Handle URL", type="string", dest="event_handle", default=os.environ.get('EVENT_HANDLE')) parser.add_option("-e", "--event-id", help="An id that uniquely identifies the event for this command and listener", type="string", dest="event_id", default=str(uuid.uuid4())) parser.add_option("-t", "--event-timestamp", help="The time the event occurred, in ISO 8601 form ", type="string", dest="event_timestamp", default=datetime.datetime.utcnow().isoformat()) parser.add_option("-d", "--dispatcher-id", help="The dispatcher ID", type="string", dest="dispatcher_id", default=os.environ.get('DISPATCHER_ID')) parser.add_option("-c", "--command-name", help="The command name", type="string", dest="command_name", default=os.environ.get('CMD_NAME')) parser.add_option("-i", "--invocation-id", help="The invocation ID", type="string", dest="invocation_id", default=os.environ.get('INVOCATION_ID')) parser.add_option("-l", "--listener-id", help="The listener ID", type="string", dest="listener_id", default=os.environ.get('LISTENER_ID')) (options, args) = parser.parse_args() options.event_handle = options.event_handle if re.match(r'https?://.*', options.event_handle) \ else base64.b64decode(options.event_handle) if not re.match(r'https?://.*', options.event_handle): print("Error: Invalid EventHandle URL specified: %s" % options.event_handle, file=sys.stderr) sys.exit(1) def fail_on_unspecified(value, name): if not value: print("Error: You must specify %s" % name, file=sys.stderr) parser.print_help(sys.stderr) sys.exit(1) fail_on_unspecified(options.dispatcher_id, "DispatcherId") fail_on_unspecified(options.command_name, "CommandName") fail_on_unspecified(options.invocation_id, "InvocationId") fail_on_unspecified(options.listener_id, "ListenerId") fail_on_unspecified(options.event_handle, "EventHandle") fail_on_unspecified(options.event_id, "EventId") fail_on_unspecified(options.event_timestamp, "EventTimestamp") result_msg = { 'DispatcherId': options.dispatcher_id, 'CommandName': options.command_name, 'ListenerId': options.listener_id, 'InvocationId': options.invocation_id, 'EventId': options.event_id, 'EventTimestamp': options.event_timestamp, 'Message': ' '.join(args) } cfnbootstrap.configureLogging("DEBUG") @util.retry_on_failure() @util.timeout() def send(url, data): requests.put(url, data=json.dumps(data), headers={"Content-Type": ""}, verify=True, proxies=util.get_proxyinfo(options), timeout=util.REQUEST_TIMEOUT).raise_for_status() try: send(options.event_handle, result_msg) print('Command Event with id {} sent successfully.'.format(options.event_id)) sys.exit(0) except IOError as e: print('Error sending Command Event: {}'.format(str(e)), file=sys.stderr) sys.exit(1)