import boto3, os, json, time | |
from base64 import b64decode | |
from urllib2 import Request, urlopen | |
encrypted_mackerel_api_key = "ENCRYPTED_MACKEREL_API_KEY" | |
org_id = "ORGANIZATION_ID" | |
lambda_client = boto3.client('lambda', region_name='ap-northeast-1') | |
kms_client = boto3.client('kms') | |
api_key = kms_client.decrypt(CiphertextBlob=b64decode(encrypted_mackerel_api_key))['Plaintext'] | |
os.environ['TZ'] = 'Asia/Tokyo' | |
mackerel_url = "https://mackerel.io/api/v0/hosts/" | |
def validation_event(event): | |
if len(event) == 0: | |
print 'There is no Evnet source.' | |
return False | |
if not event.has_key("body"): | |
print "There is no body." | |
return False | |
# Check OrgID | |
body = event["body"] | |
if body["orgId"] != org_id: | |
print "Invalid orgId." | |
return False | |
# Check host information | |
if not body.has_key("host"): | |
print "There is no host infomation." | |
return False | |
# Check alert information | |
if not body.has_key("alert"): | |
print "There is no alert infomation." | |
return False | |
alert = body["alert"] | |
if alert["status"] == "ok" or alert["status"] == "unknown": | |
print "This alert status is ok or unknown." | |
return False | |
if alert["metricLabel"] != "custom.ec2.status_check_failed.total": | |
print "This alert is not status_check_failed.total." | |
return False | |
return True | |
def get_host_id(event): | |
return event["body"]["host"]["id"] | |
def request_mackerel(url, method, api_key, params="{}", retry=5, wait=5): | |
retry_count = 0 | |
response = None | |
while True: | |
try: | |
if method == "GET": | |
req = Request(url) | |
else: | |
req = Request(url, params) | |
req.add_header("X-Api-Key", api_key) | |
req.add_header("Content-Type", "application/json") | |
req.get_method = lambda: method | |
response = urlopen(req) | |
except Exception, e: | |
print e | |
finally: | |
if response is not None: | |
if response.getcode() == 200: | |
return response.read() | |
if e.getcode() == 404: | |
return False | |
retry_count += 1 | |
if retry_count >= retry: | |
raise Exception('500: Internal Server Error') | |
time.sleep(wait) | |
def lambda_handler(event, context): | |
if validation_event(event) is False: | |
print event | |
raise Exception('400: Bad Request') | |
host_id = get_host_id(event) | |
if host_id is False: | |
print event | |
raise Exception('400: Bad Request') | |
url = mackerel_url + host_id | |
result = request_mackerel(url, "GET", api_key) | |
if result is False: | |
raise Exception('400: Bad Request') | |
root = json.loads(result) | |
instance_id = root[u'host'][u'meta'][u'cloud'][u'metadata'][u'instance-id'] | |
print instance_id | |
input = { | |
"instance_id": instance_id, | |
"command": "stop" | |
} | |
try: | |
response = lambda_client.invoke( | |
FunctionName='Mackerel-Webhook-Restart-Instance', | |
InvocationType='Event', | |
Payload=json.dumps(input) | |
) | |
except Exception, e: | |
print e | |
raise Exception('500: Internal Server Error') | |
if response[u'StatusCode'] != 202: | |
raise Exception('500: Internal Server Error') | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment