Ensure the data pipeline exists with matching definition.

    name
        Name of the service to ensure a data pipeline exists for.

    pipeline_objects
        Pipeline objects to use. Will override objects read from pillars.

    pipeline_objects_from_pillars
        The pillar key to use for lookup.

    parameter_objects
        Parameter objects to use. Will override objects read from pillars.

    parameter_objects_from_pillars
        The pillar key to use for lookup.

    parameter_values
        Parameter values to use. Will override values read from pillars.

    parameter_values_from_pillars
        The pillar key to use for lookup.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string)
        that contains a dict with region, key and keyid.

def present(name, pipeline_objects=None,
            pipeline_objects_from_pillars='boto_datapipeline_pipeline_objects',
            parameter_objects=None,
            parameter_objects_from_pillars='boto_datapipeline_parameter_objects',
            parameter_values=None,
            parameter_values_from_pillars='boto_datapipeline_parameter_values',
            region=None,
            key=None, keyid=None, profile=None):
    '''
    Ensure the data pipeline exists with matching definition.

    name
        Name of the service to ensure a data pipeline exists for.

    pipeline_objects
        Pipeline objects to use. Will override objects read from pillars.

    pipeline_objects_from_pillars
        The pillar key to use for lookup.

    parameter_objects
        Parameter objects to use. Will override objects read from pillars.

    parameter_objects_from_pillars
        The pillar key to use for lookup.

    parameter_values
        Parameter values to use. Will override values read from pillars.

    parameter_values_from_pillars
        The pillar key to use for lookup.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string)
        that contains a dict with region, key and keyid.
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}

    pipeline_objects = pipeline_objects or {}
    parameter_objects = parameter_objects or {}
    parameter_values = parameter_values or {}

    present, old_pipeline_definition = _pipeline_present_with_definition(
        name,
        _pipeline_objects(pipeline_objects_from_pillars, pipeline_objects),
        _parameter_objects(parameter_objects_from_pillars, parameter_objects),
        _parameter_values(parameter_values_from_pillars, parameter_values),
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if present:
        ret['comment'] = 'AWS data pipeline {0} present'.format(name)
        return ret

    if __opts__['test']:
        ret['comment'] = 'Data pipeline {0} is set to be created or updated'.format(name)
        ret['result'] = None
        return ret

    result_create_pipeline = __salt__['boto_datapipeline.create_pipeline'](
        name,
        name,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in result_create_pipeline:
        ret['result'] = False
        ret['comment'] = 'Failed to create data pipeline {0}: {1}'.format(
            name, result_create_pipeline['error'])
        return ret

    pipeline_id = result_create_pipeline['result']

    result_pipeline_definition = __salt__['boto_datapipeline.put_pipeline_definition'](
        pipeline_id,
        _pipeline_objects(pipeline_objects_from_pillars, pipeline_objects),
        parameter_objects=_parameter_objects(parameter_objects_from_pillars, parameter_objects),
        parameter_values=_parameter_values(parameter_values_from_pillars, parameter_values),
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in result_pipeline_definition:
        if _immutable_fields_error(result_pipeline_definition):
            # If update not possible, delete and retry
            result_delete_pipeline = __salt__['boto_datapipeline.delete_pipeline'](
                pipeline_id,
                region=region,
                key=key,
                keyid=keyid,
                profile=profile,
            )
            if 'error' in result_delete_pipeline:
                ret['result'] = False
                ret['comment'] = 'Failed to delete data pipeline {0}: {1}'.format(
                    pipeline_id, result_delete_pipeline['error'])
                return ret

            result_create_pipeline = __salt__['boto_datapipeline.create_pipeline'](
                name,
                name,
                region=region,
                key=key,
                keyid=keyid,
                profile=profile,
            )
            if 'error' in result_create_pipeline:
                ret['result'] = False
                ret['comment'] = 'Failed to create data pipeline {0}: {1}'.format(
                    name, result_create_pipeline['error'])
                return ret

            pipeline_id = result_create_pipeline['result']

            result_pipeline_definition = __salt__['boto_datapipeline.put_pipeline_definition'](
                pipeline_id,
                _pipeline_objects(pipeline_objects_from_pillars, pipeline_objects),
                parameter_objects=_parameter_objects(parameter_objects_from_pillars, parameter_objects),
                parameter_values=_parameter_values(parameter_values_from_pillars, parameter_values),
                region=region,
                key=key,
                keyid=keyid,
                profile=profile,
            )

        if 'error' in result_pipeline_definition:
            # Still erroring after possible retry
            ret['result'] = False
            ret['comment'] = 'Failed to create data pipeline {0}: {1}'.format(
                name, result_pipeline_definition['error'])
            return ret

    result_activate_pipeline = __salt__['boto_datapipeline.activate_pipeline'](
        pipeline_id,
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in result_activate_pipeline:
        ret['result'] = False
        ret['comment'] = 'Failed to create data pipeline {0}: {1}'.format(
            name, result_pipeline_definition['error'])
        return ret

    pipeline_definition_result = __salt__['boto_datapipeline.get_pipeline_definition'](
        pipeline_id,
        version='active',
        region=region,
        key=key,
        keyid=keyid,
        profile=profile,
    )
    if 'error' in pipeline_definition_result:
        new_pipeline_definition = {}
    else:
        new_pipeline_definition = _standardize(pipeline_definition_result['result'])

    if not old_pipeline_definition:
        ret['changes']['new'] = 'Pipeline created.'
        ret['comment'] = 'Data pipeline {0} created'.format(name)
    else:
        ret['changes']['diff'] = _diff(old_pipeline_definition, new_pipeline_definition)
        ret['comment'] = 'Data pipeline {0} updated'.format(name)

    return ret