Skip to content

Instantly share code, notes, and snippets.

@bageljp
Created July 9, 2016 17:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bageljp/fdbe72a34b20caeec170f00208a19639 to your computer and use it in GitHub Desktop.
Save bageljp/fdbe72a34b20caeec170f00208a19639 to your computer and use it in GitHub Desktop.
Add permissions AWS Lambda Function with API Gateway
# encoding=utf-8
import argparse
import boto3
import os
import sys
import json
from datetime import datetime
import re
import uuid
'''
指定したAPI Gatewayから実行されるLambda FunctionすべてにaddPermissionで実行権限を付与する
Usage:
python add_permission.py --api {api-gateway-id} --alias {alias-name} [--profile default]
'''
cwd = os.getcwd()
parser = argparse.ArgumentParser()
parser.add_argument("--profile", help="set profile")
parser.add_argument("--api", help="api gateway id", required=True)
parser.add_argument("--alias", help="lambda function Alias name", required=True)
args = parser.parse_args()
if args.profile:
session = boto3.session.Session(profile_name = args.profile)
apigw = session.client('apigateway')
l = session.client('lambda')
else:
apigw = boto3.client('apigateway')
l = boto3.client('lambda')
def serialize(data):
ret = {}
if isinstance(data, dict):
for k, v in data.iteritems():
if isinstance(v, datetime):
ret[k] = v.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(v, dict):
ret[k] = serialize(v)
elif isinstance(v, list):
ret[k] = [serialize(sub) for sub in v]
else:
ret[k] = v
elif isinstance(data, list):
ret = [serialize(v) for v in data]
return ret
alias = args.alias
if args.api:
apis = [serialize(apigw.get_rest_api(restApiId=args.api))]
#else:
#apis = [serialize(api) for api in apigw.get_rest_apis()['items']]
#apis = [{'name': api['name']} for api in apigw.get_rest_apis()['items']]
print 'apis: {}, alias: {}'.format(apis, alias)
for api in apis:
api['resources'] = apigw.get_resources(restApiId=api['id'], limit=200)['items']
print 'resource is {}'.format(len(api['resources']))
for resource in api['resources']:
print '----------------------------------------------------------------------------------------'
print 'resource: {}, path: {}'.format(resource['id'], resource['path'])
#if 'resourceMethods' in resource and resource['path'] == '/users/{user_id}/test':
if 'resourceMethods' in resource:
for method, v in resource['resourceMethods'].iteritems():
print ' resource: {}, path: {}, method: {}'.format(resource['id'], resource['path'], method)
method_info = apigw.get_method(restApiId=api['id'], resourceId=resource['id'], httpMethod=method)
# is lambda ?
if method_info['methodIntegration']['type'] == 'AWS':
# "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:123456789012:function:getUser:${stageVariables.env}/invocations"
re_fn = re.compile('.*(arn:aws:lambda:(.*):function:(.*)):.*')
function_arn = re_fn.match(method_info['methodIntegration']['uri']).group(1)
function_name = re_fn.match(method_info['methodIntegration']['uri']).group(3)
source_arn = 'arn:aws:execute-api:{}:{}/*/{}{}'.format(re_fn.match(method_info['methodIntegration']['uri']).group(2), args.api, method, re.sub('{.*?}', '*', resource['path']))
if function_name is not None:
statement_id = '{}_{}_{}'.format(function_name, alias, uuid.uuid4())
# add permission
res = l.add_permission(
FunctionName=function_arn,
StatementId=statement_id,
Action='lambda:InvokeFunction',
Principal='apigateway.amazonaws.com',
SourceArn=source_arn,
Qualifier=alias
)
print ' l.add_permision(FunctionName={}, StatementId={}, Action="lambda:InvokeFunction", Principal="apigateway.amazonaws.com", SourceArn={}, Qualifier={})'.format(function_arn, statement_id, source_arn, alias)
print res
else:
print ' {} is not extract function_name(None)'.format(method_info['methodIntegration']['uri'])
else:
print ' not Lambda Function(type: {})'.format(method_info['methodIntegration']['type'])
else:
print ' no method'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment