Ensure resource exists with provided properties

    name : string
        name of the zone
    resource_type : string
        type of resource
    resource_selector_property : string
        unique resource identifier
    resource_selector_value : string
        value for resource selection
    kwargs : string|int|...
        resource properties

    .. warning::
        Both resource_selector_property and resource_selector_value must be
        provided, some properties like ``name`` are already reserved by salt in
        states.

    .. note::
        You can set both resource_selector_property and resource_selector_value
        to None for resources that do not require them.

def resource_present(name, resource_type, resource_selector_property, resource_selector_value, **kwargs):
    '''
    Ensure resource exists with provided properties

    name : string
        name of the zone
    resource_type : string
        type of resource
    resource_selector_property : string
        unique resource identifier
    resource_selector_value : string
        value for resource selection
    kwargs : string|int|...
        resource properties

    .. warning::
        Both resource_selector_property and resource_selector_value must be
        provided, some properties like ``name`` are already reserved by salt in
        states.

    .. note::
        You can set both resource_selector_property and resource_selector_value
        to None for resources that do not require them.

    '''
    ret = {'name': name,
           'changes': {},
           'result': None,
           'comment': ''}

    # sanitize input
    kwargs = salt.utils.args.clean_kwargs(**kwargs)
    resource_selector_value = _parse_value(resource_selector_value)
    for k, v in kwargs.items():
        kwargs[k] = _parse_value(kwargs[k])

    zones = __salt__['zoneadm.list'](installed=True, configured=True)
    if name in zones:
        ## zone exists
        zonecfg = __salt__['zonecfg.info'](name, show_all=True)

        ## update kwargs
        zonecfg_kwargs = {}
        zonecfg_kwargs.update(kwargs)
        zonecfg_kwargs['zone'] = name
        zonecfg_kwargs['resource_type'] = resource_type
        zonecfg_kwargs['resource_selector'] = resource_selector_property
        if resource_selector_property:
            zonecfg_kwargs[resource_selector_property] = resource_selector_value

        ## check update or add
        if resource_type in zonecfg:
            for resource in zonecfg[resource_type]:
                if not resource_selector_property or resource[resource_selector_property] == resource_selector_value:
                    ret['result'] = True
                    if resource_selector_property:
                        ret['comment'] = 'the {0} resource {1} is up to date.'.format(
                            resource_type,
                            resource_selector_value,
                        )
                    else:
                        ret['comment'] = 'the {0} resource is up to date.'.format(
                            resource_type,
                        )

                    ## check if update reauired
                    for key in kwargs:
                        log.debug('zone.resource_preent - key=%s value=%s current_value=%s',
                            key,
                            resource[key] if key in resource else None,
                            _parse_value(kwargs[key]),
                        )
                        # note: something odd with ncpus property, we fix it here for now
                        if key == 'ncpus' and key in kwargs:
                            kwargs[key] = '{0:.2f}'.format(float(kwargs[key]))

                        if key not in resource:
                            ret['result'] = None
                        elif resource[key] != _parse_value(kwargs[key]):
                            ret['result'] = None

                    ## do update
                    if ret['result'] is None:
                        if __opts__['test']:
                            ret['result'] = True
                        else:
                            ## update resource
                            zonecfg_res = __salt__['zonecfg.update_resource'](**zonecfg_kwargs)
                            ret['result'] = zonecfg_res['status']
                            if 'message' in zonecfg_res:
                                ret['comment'] = zonecfg_res['message']

                        if ret['result']:
                            ret['changes'][resource_type] = {}
                            if resource_selector_property:
                                ret['changes'][resource_type][resource_selector_value] = {}
                            for key in kwargs if ret['result'] else []:
                                if resource_selector_property:
                                    ret['changes'][resource_type][resource_selector_value][key] = _parse_value(kwargs[key])
                                else:
                                    ret['changes'][resource_type][key] = _parse_value(kwargs[key])
                            if ret['comment'] == '':
                                if resource_selector_property:
                                    ret['comment'] = 'The {0} resource {1} was updated.'.format(
                                        resource_type,
                                        resource_selector_value,
                                    )
                                else:
                                    ret['comment'] = 'The {0} resource was updated.'.format(
                                        resource_type,
                                    )
                        elif ret['comment'] == '':
                            if resource_selector_property:
                                ret['comment'] = 'The {0} resource {1} was not updated.'.format(
                                    resource_type,
                                    resource_selector_value,
                                )
                            else:
                                ret['comment'] = 'The {0} resource was not updated.'.format(
                                    resource_type,
                                )
        if ret['result'] is None:
            ## add
            if __opts__['test']:
                ret['result'] = True
            else:
                ## add resource
                if 'resource_selector' in zonecfg_kwargs:
                    del zonecfg_kwargs['resource_selector']
                zonecfg_res = __salt__['zonecfg.add_resource'](**zonecfg_kwargs)
                ret['result'] = zonecfg_res['status']
                if 'message' in zonecfg_res:
                    ret['comment'] = zonecfg_res['message']

            if ret['result']:
                ret['changes'][resource_type] = {}
                if resource_selector_property:
                    ret['changes'][resource_type][resource_selector_value] = {}
                for key in kwargs if ret['result'] else []:
                    if resource_selector_property:
                        ret['changes'][resource_type][resource_selector_value][key] = _parse_value(kwargs[key])
                    else:
                        ret['changes'][resource_type][key] = _parse_value(kwargs[key])
                if ret['comment'] == '':
                    ret['comment'] = 'The {0} resource {1} was added.'.format(
                        resource_type,
                        resource_selector_value,
                    )
            elif ret['comment'] == '':
                ret['comment'] = 'The {0} resource {1} was not added.'.format(
                    resource_type,
                    resource_selector_value,
                )
    else:
        ## zone does not exist
        ret['result'] = False
        ret['comment'] = 'The zone {0} is not in the configured, installed, or booted state.'.format(name)

    return ret