Esempio n. 1
0
def deploy_resource(resource_id, resources, stack_name):
    resource = resources[resource_id]
    client = get_client(resource)
    if not client:
        return False
    resource_type = get_resource_type(resource)
    func_details = RESOURCE_TO_FUNCTION.get(resource_type)
    if not func_details:
        LOGGER.warning('Resource type not yet implemented: %s' %
                       resource['Type'])
        return
    func_details = func_details[ACTION_CREATE]
    function = getattr(client, func_details['function'])
    params = dict(func_details['parameters'])
    defaults = func_details.get('defaults', {})
    if 'Properties' not in resource:
        resource['Properties'] = {}
    # print('deploying', resource_id, resource_type)
    for param_key, prop_keys in iteritems(dict(params)):
        params.pop(param_key, None)
        if not isinstance(prop_keys, list):
            prop_keys = [prop_keys]
        for prop_key in prop_keys:
            if prop_key == PLACEHOLDER_RESOURCE_NAME:
                # obtain physical resource name from stack resources
                params[param_key] = resolve_ref(stack_name,
                                                resource_id,
                                                resources,
                                                attribute='PhysicalResourceId')
            else:
                prop_value = resource['Properties'].get(prop_key)
                if prop_value is not None:
                    params[param_key] = prop_value
            tmp_value = params.get(param_key)
            if tmp_value is not None:
                params[param_key] = resolve_refs_recursively(
                    stack_name, tmp_value, resources)
                break
        # hack: convert to boolean
        if params.get(param_key) in ['True', 'False']:
            params[param_key] = params.get(param_key) == 'True'
    # assign default value if empty
    params = common.merge_recursive(defaults, params)
    # invoke function
    try:
        result = function(**params)
    except Exception as e:
        LOGGER.warning('Error calling %s with params: %s for resource: %s' %
                       (function, params, resource))
        raise e
    # update status
    set_status_deployed(resource_id, resource, stack_name)
    return result
Esempio n. 2
0
    def on_get(self, request):
        path = request.path

        reload = "reload" in path

        # get service state
        if reload:
            self.service_manager.check_all()
        services = {
            service: state.value
            for service, state in self.service_manager.get_states().items()
        }

        # build state dict from internal state and merge into it the service states
        result = dict(self.state)
        result = merge_recursive({"services": services}, result)
        return result
Esempio n. 3
0
    def on_put(self, request):
        data = json.loads(to_str(request.data or "{}"))

        # keys like "features:initScripts" should be interpreted as ['features']['initScripts']
        state = defaultdict(dict)
        for k, v in data.items():
            if ":" in k:
                path = k.split(":")
            else:
                path = [k]

            d = state
            for p in path[:-1]:
                d = state[p]
            d[path[-1]] = v

        self.state = merge_recursive(state, self.state, overwrite=True)
        return {"status": "OK"}
Esempio n. 4
0
def deploy_resource(resource_id, resources, stack_name):
    resource = resources[resource_id]
    client = get_client(resource)
    if not client:
        return False
    resource_type = get_resource_type(resource)
    func_details = RESOURCE_TO_FUNCTION.get(resource_type)
    if not func_details:
        LOGGER.warning('Resource type not yet implemented: %s' %
                       resource['Type'])
        return
    LOGGER.debug('Deploying resource type "%s" id "%s"' %
                 (resource_type, resource_id))
    func_details = func_details[ACTION_CREATE]
    function = getattr(client, func_details['function'])
    params = dict(func_details['parameters'])
    defaults = func_details.get('defaults', {})
    if 'Properties' not in resource:
        resource['Properties'] = {}
    resource_props = resource['Properties']
    for param_key, prop_keys in iteritems(dict(params)):
        params.pop(param_key, None)
        if not isinstance(prop_keys, list):
            prop_keys = [prop_keys]
        for prop_key in prop_keys:
            if prop_key == PLACEHOLDER_RESOURCE_NAME:
                # obtain physical resource name from stack resources
                params[param_key] = resolve_ref(stack_name,
                                                resource_id,
                                                resources,
                                                attribute='PhysicalResourceId')
            else:
                prop_value = resource_props.get(prop_key)
                if prop_value is not None:
                    params[param_key] = prop_value
            tmp_value = params.get(param_key)
            if tmp_value is not None:
                params[param_key] = resolve_refs_recursively(
                    stack_name, tmp_value, resources)
                break
        # hack: convert to boolean
        if params.get(param_key) in ['True', 'False']:
            params[param_key] = params.get(param_key) == 'True'
    # assign default value if empty
    params = common.merge_recursive(defaults, params)
    # invoke function
    try:
        result = function(**params)
    except Exception as e:
        LOGGER.warning('Error calling %s with params: %s for resource: %s' %
                       (function, params, resource))
        raise e
    # some resources have attached/nested resources which we need to create recursively now
    if resource_type == 'ApiGateway::Method':
        integration = resource_props.get('Integration')
        if integration:
            api_id = resolve_refs_recursively(stack_name,
                                              resource_props['RestApiId'],
                                              resources)
            res_id = resolve_refs_recursively(stack_name,
                                              resource_props['ResourceId'],
                                              resources)
            uri = integration.get('Uri')
            if uri:
                uri = resolve_refs_recursively(stack_name, uri, resources)
                aws_stack.connect_to_service('apigateway').put_integration(
                    restApiId=api_id,
                    resourceId=res_id,
                    httpMethod=resource_props['HttpMethod'],
                    type=integration['Type'],
                    integrationHttpMethod=integration['IntegrationHttpMethod'],
                    uri=uri)
    # update status
    set_status_deployed(resource_id, resource, stack_name)
    return result
Esempio n. 5
0
def configure_resource_via_sdk(resource_id, resources, resource_type,
                               func_details, stack_name):
    resource = resources[resource_id]
    client = get_client(resource, func_details)
    function = getattr(client, func_details['function'])
    params = func_details.get('parameters') or lambda_get_params()
    defaults = func_details.get('defaults', {})
    if 'Properties' not in resource:
        resource['Properties'] = {}
    resource_props = resource['Properties']

    if callable(params):
        params = params(resource_props,
                        stack_name=stack_name,
                        resources=resources)
    else:
        params = dict(params)
        for param_key, prop_keys in dict(params).items():
            params.pop(param_key, None)
            if not isinstance(prop_keys, list):
                prop_keys = [prop_keys]
            for prop_key in prop_keys:
                if prop_key == PLACEHOLDER_RESOURCE_NAME:
                    params[param_key] = resource_id
                    resource_name = get_resource_name(resource)
                    if resource_name:
                        params[param_key] = resource_name
                    else:
                        # try to obtain physical resource name from stack resources
                        try:
                            return resolve_ref(stack_name,
                                               resource_id,
                                               resources,
                                               attribute='PhysicalResourceId')
                        except Exception as e:
                            LOG.debug(
                                'Unable to extract physical id for resource %s: %s'
                                % (resource_id, e))

                else:
                    if callable(prop_key):
                        prop_value = prop_key(resource_props,
                                              stack_name=stack_name,
                                              resources=resources)
                    else:
                        prop_value = resource_props.get(prop_key)
                    if prop_value is not None:
                        params[param_key] = prop_value

    # assign default value if empty
    params = common.merge_recursive(defaults, params)

    # convert refs and boolean strings
    for param_key, param_value in dict(params).items():
        if param_value is not None:
            param_value = params[param_key] = resolve_refs_recursively(
                stack_name, param_value, resources)
        # Convert to boolean (TODO: do this recursively?)
        if str(param_value).lower() in ['true', 'false']:
            params[param_key] = str(param_value).lower() == 'true'

    # convert any moto account IDs (123456789012) in ARNs to our format (000000000000)
    params = fix_account_id_in_arns(params)
    # convert data types (e.g., boolean strings to bool)
    params = convert_data_types(func_details, params)
    # remove None values, as they usually raise boto3 errors
    params = remove_none_values(params)

    # invoke function
    try:
        LOG.debug('Request for resource type "%s" in region %s: %s %s' %
                  (resource_type, aws_stack.get_region(),
                   func_details['function'], params))
        result = function(**params)
    except Exception as e:
        LOG.warning('Error calling %s with params: %s for resource: %s' %
                    (function, params, resource))
        raise e

    # some resources have attached/nested resources which we need to create recursively now
    if resource_type == 'ApiGateway::Method':
        integration = resource_props.get('Integration')
        if integration:
            api_id = resolve_refs_recursively(stack_name,
                                              resource_props['RestApiId'],
                                              resources)
            res_id = resolve_refs_recursively(stack_name,
                                              resource_props['ResourceId'],
                                              resources)
            uri = integration.get('Uri')
            if uri:
                uri = resolve_refs_recursively(stack_name, uri, resources)
                aws_stack.connect_to_service('apigateway').put_integration(
                    restApiId=api_id,
                    resourceId=res_id,
                    httpMethod=resource_props['HttpMethod'],
                    type=integration['Type'],
                    integrationHttpMethod=integration['IntegrationHttpMethod'],
                    uri=uri)
    elif resource_type == 'SNS::Topic':
        subscriptions = resource_props.get('Subscription', [])
        for subscription in subscriptions:
            endpoint = resolve_refs_recursively(stack_name,
                                                subscription['Endpoint'],
                                                resources)
            topic_arn = retrieve_topic_arn(params['Name'])
            aws_stack.connect_to_service('sns').subscribe(
                TopicArn=topic_arn,
                Protocol=subscription['Protocol'],
                Endpoint=endpoint)
    elif resource_type == 'S3::Bucket':
        tags = resource_props.get('Tags')
        if tags:
            aws_stack.connect_to_service('s3').put_bucket_tagging(
                Bucket=params['Bucket'], Tagging={'TagSet': tags})

    return result
Esempio n. 6
0
def deploy_resource(resource_id, resources, stack_name):
    resource = resources[resource_id]
    client = get_client(resource)
    if not client:
        return False
    resource_type = get_resource_type(resource)
    func_details = RESOURCE_TO_FUNCTION.get(resource_type)
    if not func_details:
        LOG.warning('Resource type not yet implemented: %s' % resource_type)
        return

    LOG.debug('Deploying resource type "%s" id "%s"' %
              (resource_type, resource_id))
    func_details = func_details[ACTION_CREATE]
    function = getattr(client, func_details['function'])
    params = dict(func_details['parameters'])
    defaults = func_details.get('defaults', {})
    if 'Properties' not in resource:
        resource['Properties'] = {}
    resource_props = resource['Properties']

    for param_key, prop_keys in iteritems(dict(params)):
        params.pop(param_key, None)
        if not isinstance(prop_keys, list):
            prop_keys = [prop_keys]
        for prop_key in prop_keys:
            if prop_key == PLACEHOLDER_RESOURCE_NAME:
                params[param_key] = resource_id
                resource_name = get_resource_name(resource)
                if resource_name:
                    params[param_key] = resource_name
                else:
                    # try to obtain physical resource name from stack resources
                    try:
                        return resolve_ref(stack_name,
                                           resource_id,
                                           resources,
                                           attribute='PhysicalResourceId')
                    except Exception as e:
                        LOG.debug(
                            'Unable to extract physical id for resource %s: %s'
                            % (resource_id, e))

            else:
                if callable(prop_key):
                    prop_value = prop_key(resource_props,
                                          stack_name=stack_name,
                                          resources=resources)
                else:
                    prop_value = resource_props.get(prop_key)
                if prop_value is not None:
                    params[param_key] = prop_value
            tmp_value = params.get(param_key)
            if tmp_value is not None:
                params[param_key] = resolve_refs_recursively(
                    stack_name, tmp_value, resources)
                break
        # hack: convert to boolean
        if params.get(param_key) in ['True', 'False']:
            params[param_key] = params.get(param_key) == 'True'
    # assign default value if empty
    params = common.merge_recursive(defaults, params)
    # convert data types (e.g., boolean strings to bool)
    params = convert_data_types(func_details, params)

    # invoke function
    try:
        LOG.debug('Request for creating resource type "%s": %s' %
                  (resource_type, params))
        result = function(**params)
    except Exception as e:
        LOG.warning('Error calling %s with params: %s for resource: %s' %
                    (function, params, resource))
        raise e

    # some resources have attached/nested resources which we need to create recursively now
    if resource_type == 'ApiGateway::Method':
        integration = resource_props.get('Integration')
        if integration:
            api_id = resolve_refs_recursively(stack_name,
                                              resource_props['RestApiId'],
                                              resources)
            res_id = resolve_refs_recursively(stack_name,
                                              resource_props['ResourceId'],
                                              resources)
            uri = integration.get('Uri')
            if uri:
                uri = resolve_refs_recursively(stack_name, uri, resources)
                aws_stack.connect_to_service('apigateway').put_integration(
                    restApiId=api_id,
                    resourceId=res_id,
                    httpMethod=resource_props['HttpMethod'],
                    type=integration['Type'],
                    integrationHttpMethod=integration['IntegrationHttpMethod'],
                    uri=uri)
    elif resource_type == 'SNS::Topic':
        subscriptions = resource_props.get('Subscription', [])
        for subscription in subscriptions:
            endpoint = resolve_refs_recursively(stack_name,
                                                subscription['Endpoint'],
                                                resources)
            topic_arn = retrieve_topic_arn(params['Name'])
            aws_stack.connect_to_service('sns').subscribe(
                TopicArn=topic_arn,
                Protocol=subscription['Protocol'],
                Endpoint=endpoint)
    elif resource_type == 'S3::Bucket':
        tags = resource_props.get('Tags')
        if tags:
            aws_stack.connect_to_service('s3').put_bucket_tagging(
                Bucket=params['Bucket'], Tagging={'TagSet': tags})

    return result
Esempio n. 7
0
def deploy_resource(resource_id, resources, stack_name):
    resource = resources[resource_id]
    client = get_client(resource)
    if not client:
        return False
    resource_type = get_resource_type(resource)
    func_details = RESOURCE_TO_FUNCTION.get(resource_type)
    if not func_details:
        LOGGER.warning('Resource type not yet implemented: %s' % resource['Type'])
        return
    LOGGER.debug('Deploying resource type "%s" id "%s"' % (resource_type, resource_id))
    func_details = func_details[ACTION_CREATE]
    function = getattr(client, func_details['function'])
    params = dict(func_details['parameters'])
    defaults = func_details.get('defaults', {})
    if 'Properties' not in resource:
        resource['Properties'] = {}
    resource_props = resource['Properties']
    for param_key, prop_keys in iteritems(dict(params)):
        params.pop(param_key, None)
        if not isinstance(prop_keys, list):
            prop_keys = [prop_keys]
        for prop_key in prop_keys:
            if prop_key == PLACEHOLDER_RESOURCE_NAME:
                # obtain physical resource name from stack resources
                params[param_key] = resolve_ref(stack_name, resource_id, resources,
                    attribute='PhysicalResourceId')
            else:
                if callable(prop_key):
                    prop_value = prop_key(resource_props)
                else:
                    prop_value = resource_props.get(prop_key)
                if prop_value is not None:
                    params[param_key] = prop_value
            tmp_value = params.get(param_key)
            if tmp_value is not None:
                params[param_key] = resolve_refs_recursively(stack_name, tmp_value, resources)
                break
        # hack: convert to boolean
        if params.get(param_key) in ['True', 'False']:
            params[param_key] = params.get(param_key) == 'True'
    # assign default value if empty
    params = common.merge_recursive(defaults, params)
    # invoke function
    try:
        result = function(**params)
    except Exception as e:
        LOGGER.warning('Error calling %s with params: %s for resource: %s' % (function, params, resource))
        raise e
    # some resources have attached/nested resources which we need to create recursively now
    if resource_type == 'ApiGateway::Method':
        integration = resource_props.get('Integration')
        if integration:
            api_id = resolve_refs_recursively(stack_name, resource_props['RestApiId'], resources)
            res_id = resolve_refs_recursively(stack_name, resource_props['ResourceId'], resources)
            uri = integration.get('Uri')
            if uri:
                uri = resolve_refs_recursively(stack_name, uri, resources)
                aws_stack.connect_to_service('apigateway').put_integration(restApiId=api_id, resourceId=res_id,
                    httpMethod=resource_props['HttpMethod'], type=integration['Type'],
                    integrationHttpMethod=integration['IntegrationHttpMethod'], uri=uri
                )
    # update status
    set_status_deployed(resource_id, resource, stack_name)
    return result