Beispiel #1
0
def PutOPTIONSMethod(client, api_id, resource_id):
    logger.runTrace('Create OPTIONS Method for resource', resource_id)

    response_put_option = client.put_method(
        restApiId=api_id,
        resourceId=resource_id,
        httpMethod='OPTIONS',
        authorizationType=
        'NONE'  #NONE for open access, COGNITO_USER_POOLS for cognito
    )
    logger.generatedDebug('OPTIONS Method created',
                          json.dumps(response_put_option))

    response_put_integration = client.put_integration(
        restApiId=api_id,
        resourceId=resource_id,
        httpMethod='OPTIONS',
        type='MOCK',
        requestTemplates={'application/json': '{"statusCode": 200}'
                          }  #this is needed so options will return 200
    )
    logger.generatedDebug('OPTIONS Integration set type', 'MOCK')

    response_put_method_response = client.put_method_response(
        restApiId=api_id,
        resourceId=resource_id,
        httpMethod='OPTIONS',
        statusCode='200')
    logger.generatedDebug('OPTIONS Method Response set status Code', '200')
def SetIntegrationType(client, api_id, resource_id, method, integration_type,
                       lambda_func, requestTemplates):
    if method.upper() == 'OPTIONS':  # for OPTIONS methods set to MOCK
        integration_type = 'MOCK'
        logger.runTrace('integration type', integration_type)

        response = client.put_integration(
            restApiId=api_id,
            resourceId=resource_id,
            httpMethod=method,
            type=integration_type,
            requestTemplates={'application/json': '{"statusCode": 200}'})
    else:
        uri = 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:061431082068:function:${}/invocations'
        uri = uri.replace('${}', lambda_func)
        response = client.put_integration(
            restApiId=api_id,
            resourceId=resource_id,
            httpMethod=method,
            type=integration_type,
            integrationHttpMethod=
            'POST',  # ! looks like integrationHttpMethod can only be POST for lambda
            uri=uri,
            requestTemplates=requestTemplates)
    print(json.dumps(response))
def main():
    #* set logger
    logger.setLogger('api_gateway_intergration_set_stage_variable.log')
    #* get client
    client = boto3.client('apigateway')
    #* get api_id
    api_id = GetAPIId()
    #* get a dict of resources for the API {resource_name:resource_id,[methods]}
    resources_dict = GetResources(client, api_id)
    #* set integration type as lambda
    integration_type = 'AWS'

    requestTemplates = {
        'application/json':
        '{\n  "body" : $input.json("$"),\n  "headers": {\n    #foreach($header in $input.params().header.keySet())\n    "$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end\n\n    #end\n  },\n  "method": "$context.httpMethod",\n  "params": {\n    #foreach($param in $input.params().path.keySet())\n    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end\n\n    #end\n  },\n  "query": {\n    #foreach($queryParam in $input.params().querystring.keySet())\n    "$queryParam": "$util.escapeJavaScript($input.params().querystring.get($queryParam))" #if($foreach.hasNext),#end\n\n    #end\n  }  \n}'
    }

    for name, value in resources_dict.items():
        logger.runTrace('For resource ', name)
        resource_id = value[0]
        logger.runTrace('with id', resource_id)
        methods = value[1]
        for method in methods:
            logger.runTrace('on method', method)

            lambda_func = '${stageVariables.' + name + '_' + method.upper(
            ) + '}'
            logger.runTrace('stage varialbe is', lambda_func)
            #set integration with lambda function

            SetIntegrationType(client, api_id, resource_id, method,
                               integration_type, lambda_func, requestTemplates)
def GetFunctionName(client_api, api_id, resource_id, http_method):
  logger.runTrace('for resource_method', resource_id + '_' + http_method)
  response = client_api.get_integration(
    restApiId = api_id,
    resourceId = resource_id,
    httpMethod = http_method
  )
  logger.runTrace('get integration', json.dumps(response))
  
  function_name =''
  # avoid errors with option methods
  if response['type'] == 'AWS':
    function_name = response['uri'].rsplit('/', 1)[0]
    function_name = function_name.split('arn:')[2]
    function_name = 'arn:' + function_name
  logger.generatedDebug('Raw Function Name', function_name)
  return(function_name)
def GetResourcesDict(resources, client_api, api_id):
  
  resources_dict = {}
  for resource in resources:
    #print(resource)
    resource_id = resource['id']
    resource_path = resource['path']

    methods = []
    # this gives a dict {resource_id:[[method, statement_id, resource_path],...]}
    if resource_path != '/': # avoid root path, which don't have methods
      resource_methods = resource['resourceMethods']
      for method in resource_methods:
        method_statement_id = []
        method_statement_id.append(method)
        #T generate pesudo statement id based on the method 
        statement_id = resource_path.replace('/{', '-')
        statement_id = statement_id.replace('}/', '-')
        statement_id = statement_id.replace('}', '-')
        statement_id = statement_id.replace('_', '-')
        statement_id = statement_id.replace('/', '')
        statement_id = statement_id + '-' + method.lower()
        method_statement_id.append(statement_id)
        method_statement_id.append(resource_path)
        
        methods.append(method_statement_id)
      resources_dict[resource_id] = methods
  logger.generatedDebug('Resource Dictionary', json.dumps(resources_dict))
  
  for id, methods in resources_dict.items():
    value_sets = []
    for method in methods:
      if method[0] != 'OPTIONS':
        value_set = []
        method_function_pair = {}
        function_name = GetFunctionName(client_api, api_id, id, method[0])
        method_function_pair[method[0]] = function_name
        value_set.append(method_function_pair)
        value_set.append(method[1])
        source_arn = GetSourceArn(api_id, function_name, method[0], method[2])
        value_set.append(source_arn)
        value_sets.append(value_set)
      logger.runTrace('value set', json.dumps(value_set))
      resources_dict[id] = value_sets
  return (resources_dict)
Beispiel #6
0
def PutCORSResponds(client, api_id, resources_dict, method_respPara,
                    resp_headers_methods, headers_vals, status_code_pattern,
                    responseTemplates):
    for resource in resources_dict:
        logger.runTrace('for resource', resource)
        resource_id = resources_dict[resource][0]
        logger.runTrace('resource', resource)

        methods = resources_dict[resource][1]
        methods_str = ','.join(methods)
        methods_str = "'" + methods_str + "'"
        logger.runTrace('with methods', methods_str)

        integration_mapping = []
        for header_val in headers_vals:
            integration_mapping.append(header_val)
        integration_mapping.append(methods_str)
        logger.generatedDebug('Integration Mapping',
                              json.dumps(integration_mapping))

        integration_respPara = {}
        integration_respPara = dict(
            zip(resp_headers_methods, integration_mapping))
        logger.generatedDebug('Integration Parameters',
                              json.dumps(integration_respPara))

        for method in methods:
            logger.runTrace('for method', method)

            #* Get status codes
            response_get_method = client.get_method(restApiId=api_id,
                                                    resourceId=resource_id,
                                                    httpMethod=method)
            logger.generatedDebug('Method Detail',
                                  json.dumps(response_get_method))
            method_responses = response_get_method['methodResponses']
            logger.runTrace('Method Responses', json.dumps(method_responses))
            status_codes = list(method_responses.keys())
            logger.runTrace('Status Codes', json.dumps(status_codes))

            #* if status codes not include 200 add 200, as long as it is not OPTIONS
            if '200' not in status_codes and method != 'OPTIONS':
                status_codes.append('200')

            for status_code in status_codes:
                logger.runTrace('for status code', status_code)
                logger.runTrace('pattern', status_code_pattern[status_code])

                #! delete Method Response Headers if there is one
                try:
                    response_delete_method = client.delete_method_response(
                        restApiId=api_id,
                        resourceId=resource_id,
                        httpMethod=method,
                        statusCode=status_code)
                    logger.runTrace('Method deletion',
                                    json.dumps(response_delete_method))
                except:
                    logger.runTrace('Method deletion failed',
                                    'Method does not exist')

                #! delete Integration Response Headers if there is one
                try:
                    response_delete_integration = client.delete_integration_response(
                        restApiId=api_id,
                        resourceId=resource_id,
                        httpMethod=method,
                        statusCode=status_code)
                    logger.runTrace('Integration deletion',
                                    json.dumps(response_delete_integration))
                except:
                    logger.runTrace('Integration deletion failed',
                                    'Integration does not exist')

                #* put Method Response Headers
                response_put_method = client.put_method_response(
                    restApiId=api_id,
                    resourceId=resource_id,
                    httpMethod=method,
                    statusCode=status_code,
                    responseParameters=method_respPara)
                print(response_put_method)
                logger.createInfo('Method Response',
                                  json.dumps(response_put_method))

                #* put Integration Responses Header Mappings
                if status_code_pattern[status_code].lower() == 'default':
                    response_put_integration = client.put_integration_response(
                        restApiId=api_id,
                        resourceId=resource_id,
                        httpMethod=method,
                        statusCode=status_code,
                        responseParameters=integration_respPara,
                        responseTemplates=responseTemplates)
                else:
                    response_put_integration = client.put_integration_response(
                        restApiId=api_id,
                        resourceId=resource_id,
                        httpMethod=method,
                        statusCode=status_code,
                        selectionPattern=status_code_pattern[status_code],
                        responseParameters=integration_respPara)
                print(response_put_integration)
def main():
  #constant
  stg_var_name_lst = ['keybundle_GET',
                    'keybundle_id_DELETE',
                    'keybundle_id_GET',
                    'keybundle_id_PUT',
                    'keyholder_GET',
                    'keyholder_POST',
                    'keyholder_id_DELETE',
                    'keyholder_id_GET',
                    'keyholder_id_PUT',
                    'property_GET',
                    'property_POST',
                    'property_id_DELETE',
                    'property_id_GET',
                    'property_id_PUT',
                    'property_id_keybundle_GET',
                    'property_id_keybundle_POST'
                    ]
  
  #set logger
  logger.setLogger('api_gateway_lambda_stage_variable_enable.log')
  #set client for api
  client_api = boto3.client('apigateway')
  
  #get API
  api_id = GetAPIId()
  #get feature stage
  isFeature = input('Is this for the feature stage?(y/n) ')
  logger.inputTrace('Is Feature', isFeature)
  if isFeature.lower() ==  'y' or isFeature.lower() ==  'yes':
    feature_funcs = GetFeatureStageFuncs(stg_var_name_lst)
    isFeature = True
  else:
    isFeature = False
  
  response_get_resources = client_api.get_resources(
    restApiId=api_id
  )
  resources = response_get_resources['items']
  logger.generatedDebug('Resources of API', json.dumps(resources))
  # this gives {resource_id:[{method:functionName}, statement_id, source_arn],[]...}
  resources_dict = GetResourcesDict(resources, client_api, api_id)
  logger.generatedDebug('Resource Dictionary with Function Names', json.dumps(resources_dict))

  #  get boto3 clinet for lambda
  client_lambda = boto3.client('lambda')
  
  # lambda add permission
  isPandD= input('Is this also for the production and development stages?(y/n) ')
  logger.inputTrace('Is production and development', isPandD)
  function_name = ''
  if isPandD.lower() ==  'y' or isPandD.lower() ==  'yes':
    dev_prod_funcs = GetDevProdStageFunc(stg_var_name_lst)
    
    for method_set in resources_dict.values():
      # print(method_set)
      for method in method_set:
        # print(method)
        logger.runTrace('for method', json.dumps(method))
        for k in method[0].values():
          function_name = k
        # print(function_name)
        logger.runTrace('with stage variable', json.dumps(function_name))
        statement_id = method[1]
        source_arn = method[2]
        
        function_name_part = function_name.split('${stageVariables.')
        # print(function_name_part)
        function_name_part[1] = function_name_part[1].replace('}', '')
        
        # print(dev_prod_funcs.keys())
        if function_name_part[1] in dev_prod_funcs.keys():
          
          for val in dev_prod_funcs[function_name_part[1]]:
            function_name = function_name_part[0] + val.replace('id_','id-')
            logger.runTrace('invoke function', function_name)
            try:
              LambdaRemovePermission(client_lambda, function_name, statement_id) 
            except:
              logger.runTrace('Permission Removal', 'permission not exist')           
            try:
              LambdaAddPermission(client_lambda, api_id, function_name, statement_id, source_arn)
            except:
              print('AddPermission failed for', function_name)
            else:
              print('Development and Production permission successfully added!')
  if isFeature:
    for method_set in resources_dict.values():
      # print(method_set)
      for method in method_set:
        logger.runTrace('for method', json.dumps(method))
        for k in method[0].values():
          function_name = k
        # logger.runTrace('with stage variable', json.dumps(function_name))
        statement_id = method[1]
        source_arn = method[2]
        
        function_name_part = function_name.split('${stageVariables.')
        function_name_part[1] = function_name_part[1].replace('}', '')
        # print(function_name_part)
        # print(feature_funcs.keys())
        if function_name_part[1] in feature_funcs.keys():
          function_name = function_name_part[0] + feature_funcs[function_name_part[1]].replace('-id','_id')
          print(function_name)
          logger.runTrace('invoke function', function_name)
          try:
              LambdaRemovePermission(client_lambda, function_name, statement_id) 
          except:
            logger.runTrace('Permission Removal', 'permission not exist')  
          try:
            LambdaAddPermission(client_lambda, api_id, function_name, statement_id, source_arn)
          except:
            print('AddPermission failed for', function_name)
          else:
            print('Feature permission successfully added!')