Modify an existing beacon.

    Args:

        name (str):
            Name of the beacon to configure.

        beacon_data (dict):
            Dictionary or list containing updated configuration for beacon.

    Returns:
        dict: Boolean and status message on success or failure of modify.

    CLI Example:

    .. code-block:: bash

        salt '*' beacons.modify ps "[{'salt-master': 'stopped'}, {'apache2': 'stopped'}]"

def modify(name, beacon_data, **kwargs):
    '''
    Modify an existing beacon.

    Args:

        name (str):
            Name of the beacon to configure.

        beacon_data (dict):
            Dictionary or list containing updated configuration for beacon.

    Returns:
        dict: Boolean and status message on success or failure of modify.

    CLI Example:

    .. code-block:: bash

        salt '*' beacons.modify ps "[{'salt-master': 'stopped'}, {'apache2': 'stopped'}]"
    '''

    ret = {'comment': '',
           'result': True}

    current_beacons = list_(return_yaml=False, **kwargs)
    if name not in current_beacons:
        ret['comment'] = 'Beacon {0} is not configured.'.format(name)
        return ret

    if 'test' in kwargs and kwargs['test']:
        ret['result'] = True
        ret['comment'] = 'Beacon: {0} would be modified.'.format(name)
    else:
        try:
            # Attempt to load the beacon module so we have access to the
            # validate function
            eventer = salt.utils.event.get_event('minion', opts=__opts__)
            res = __salt__['event.fire']({'name': name,
                                          'beacon_data': beacon_data,
                                          'func': 'validate_beacon'},
                                         'manage_beacons')
            if res:
                event_ret = eventer.get_event(
                    tag='/salt/minion/minion_beacon_validation_complete',
                    wait=kwargs.get('timeout', 30))
                valid = event_ret['valid']
                vcomment = event_ret['vcomment']

            if not valid:
                ret['result'] = False
                ret['comment'] = ('Beacon {0} configuration invalid, '
                                  'not modifying.\n{1}'.format(name, vcomment))
                return ret

        except KeyError:
            # Effectively a no-op, since we can't really return without an event
            # system
            ret['result'] = False
            ret['comment'] = 'Event module not available. Beacon modify failed.'
            return ret

        if not valid:
            ret['result'] = False
            ret['comment'] = ('Beacon {0} configuration invalid, '
                              'not modifying.\n{1}'.format(name, vcomment))
            return ret

        _current = current_beacons[name]
        _new = beacon_data

        if _new == _current:
            ret['comment'] = 'Job {0} in correct state'.format(name)
            return ret

        _current_lines = []
        for _item in _current:
            _current_lines.extend(['{0}:{1}\n'.format(key, value)
                                  for (key, value) in six.iteritems(_item)])
        _new_lines = []
        for _item in _new:
            _new_lines.extend(['{0}:{1}\n'.format(key, value)
                              for (key, value) in six.iteritems(_item)])
        _diff = difflib.unified_diff(_current_lines, _new_lines)

        ret['changes'] = {}
        ret['changes']['diff'] = ''.join(_diff)

        try:
            eventer = salt.utils.event.get_event('minion', opts=__opts__)
            res = __salt__['event.fire']({'name': name,
                                          'beacon_data': beacon_data,
                                          'func': 'modify'},
                                         'manage_beacons')
            if res:
                event_ret = eventer.get_event(
                    tag='/salt/minion/minion_beacon_modify_complete',
                    wait=kwargs.get('timeout', 30))
                if event_ret and event_ret['complete']:
                    beacons = event_ret['beacons']
                    if name in beacons and beacons[name] == beacon_data:
                        ret['result'] = True
                        ret['comment'] = 'Modified beacon: {0}.'.format(name)
                elif event_ret:
                    ret['result'] = False
                    ret['comment'] = event_ret['comment']
                else:
                    ret['result'] = False
                    ret['comment'] = 'Did not receive the manage event ' \
                                     'before the timeout of {0}s' \
                                     ''.format(kwargs.get('timeout', 30))
                return ret
        except KeyError:
            # Effectively a no-op, since we can't really return without an event
            # system
            ret['result'] = False
            ret['comment'] = 'Event module not available. Beacon modify failed.'
    return ret