def _process_resources_with_dependencies()

in syndicate/core/build/deployment_processor.py [0:0]


def _process_resources_with_dependencies(resources, handlers_mapping,
                                         describe_handlers, pass_context=False,
                                         overall_resources=None, output=None,
                                         current_resource_type=None,
                                         run_count=0):
    overall_resources = overall_resources or resources
    output = output or {}
    resource_type = None
    is_succeeded = True
    errors = []
    try:
        for res_name, res_meta in resources:
            args = []
            resource_type = res_meta['resource_type']

            if res_meta.get('processed'):
                _LOG.debug(f"Processing of '{resource_type}' '{res_name}' "
                           f"skipped. Resource already processed")
                continue

            if run_count >= len(overall_resources):
                raise RecursionError(
                    "An infinite loop detected in resource dependencies")

            run_count += 1

            dependencies = [item['resource_name'] for item in
                            res_meta.get('dependencies', [])]
            _LOG.debug(f"'{resource_type}' '{res_name}' depends on resources: "
                       f"{dependencies}")
            # Order of items in depends_on_resources is important!
            depends_on_resources = []
            for dep_res_name in dependencies:
                for overall_res_name, overall_res_meta in overall_resources:
                    if overall_res_name == dep_res_name:
                        depends_on_resources.append((overall_res_name,
                                                    overall_res_meta))

            if depends_on_resources:
                _LOG.info(
                    f"Processing '{resource_type}' '{res_name}' dependencies "
                    f"{prettify_json(res_meta['dependencies'])}")

                success, output = _process_resources_with_dependencies(
                    resources=depends_on_resources,
                    handlers_mapping=handlers_mapping,
                    describe_handlers=describe_handlers,
                    pass_context=pass_context,
                    overall_resources=overall_resources,
                    output=output,
                    current_resource_type=current_resource_type,
                    run_count=run_count)

                if not success:
                    return False, output

            args.append(_build_args(name=res_name,
                                    meta=res_meta,
                                    context=output,
                                    pass_context=pass_context))
            if current_resource_type != resource_type:
                USER_LOG.info(f'Processing {resource_type} resources')
                current_resource_type = resource_type
            func = handlers_mapping[resource_type]
            response = func(args)
            response_errors = process_response(response=response,
                                               output=output)
            errors.extend(response_errors)

            res_meta['processed'] = True
            overall_res_index = overall_resources.index(
                (res_name, res_meta))
            overall_resources[overall_res_index][-1]['processed'] = True

        if errors:
            is_succeeded = False

    except Exception as e:
        if 'An infinite loop' in str(e):
            USER_LOG.error(e.args[0])
        else:
            USER_LOG.exception(f"Error occurred while '{resource_type}' "
                               f"resource creating: {str(e)}")
        is_succeeded = False

    if not is_succeeded:
        for item in args:
            func = describe_handlers[item['meta']['resource_type']]
            try:
                response = func(item['name'], item['meta'])
            except Exception as e:
                response = ({}, [str(e)])
            if response:
                response_errors = process_response(response=response,
                                                   output=output)
                errors.extend(response_errors)

    return is_succeeded, output