Manages the configuration of NTP peers and servers on the device, as specified in the state SLS file.
    NTP entities not specified in these lists will be removed whilst entities not configured on the device will be set.

    SLS Example:

    .. code-block:: yaml

        netntp_example:
            netntp.managed:
                 - peers:
                    - 192.168.0.1
                    - 172.17.17.1
                 - servers:
                    - 24.124.0.251
                    - 138.236.128.36

    Output example:

    .. code-block:: python

        {
            'edge01.nrt04': {
                'netntp_|-netntp_example_|-netntp_example_|-managed': {
                    'comment': 'NTP servers already configured as needed.',
                    'name': 'netntp_example',
                    'start_time': '12:45:24.056659',
                    'duration': 2938.857,
                    'changes': {
                        'peers': {
                            'removed': [
                                '192.168.0.2',
                                '192.168.0.3'
                            ],
                            'added': [
                                '192.168.0.1',
                                '172.17.17.1'
                            ]
                        }
                    },
                    'result': None
                }
            }
        }

def managed(name, peers=None, servers=None):

    '''
    Manages the configuration of NTP peers and servers on the device, as specified in the state SLS file.
    NTP entities not specified in these lists will be removed whilst entities not configured on the device will be set.

    SLS Example:

    .. code-block:: yaml

        netntp_example:
            netntp.managed:
                 - peers:
                    - 192.168.0.1
                    - 172.17.17.1
                 - servers:
                    - 24.124.0.251
                    - 138.236.128.36

    Output example:

    .. code-block:: python

        {
            'edge01.nrt04': {
                'netntp_|-netntp_example_|-netntp_example_|-managed': {
                    'comment': 'NTP servers already configured as needed.',
                    'name': 'netntp_example',
                    'start_time': '12:45:24.056659',
                    'duration': 2938.857,
                    'changes': {
                        'peers': {
                            'removed': [
                                '192.168.0.2',
                                '192.168.0.3'
                            ],
                            'added': [
                                '192.168.0.1',
                                '172.17.17.1'
                            ]
                        }
                    },
                    'result': None
                }
            }
        }
    '''

    ret = _default_ret(name)
    result = ret.get('result', False)
    comment = ret.get('comment', '')
    changes = ret.get('changes', {})

    if not(isinstance(peers, list) or isinstance(servers, list)):  # none of the is a list
        return ret  # just exit

    if isinstance(peers, list) and not _check(peers):  # check and clean peers
        ret['comment'] = 'NTP peers must be a list of valid IP Addresses or Domain Names'
        return ret

    if isinstance(servers, list) and not _check(servers):  # check and clean servers
        ret['comment'] = 'NTP servers must be a list of valid IP Addresses or Domain Names'
        return ret

    # ----- Retrieve existing NTP peers and determine peers to be added/removed --------------------------------------->

    successfully_changed = True
    expected_config_change = False

    if isinstance(peers, list):
        _peers_ret = _check_diff_and_configure(name, peers, name='peers')
        expected_config_change = _peers_ret.get('expected_config_change', False)
        successfully_changed = _peers_ret.get('successfully_changed', True)
        result = result and _peers_ret.get('result', False)
        comment += ('\n' + _peers_ret.get('comment', ''))
        _changed_peers = _peers_ret.get('changes', {})
        if _changed_peers:
            changes['peers'] = _changed_peers
    if isinstance(servers, list):
        _servers_ret = _check_diff_and_configure(name, servers, name='servers')
        expected_config_change = expected_config_change or _servers_ret.get('expected_config_change', False)
        successfully_changed = successfully_changed and _servers_ret.get('successfully_changed', True)
        result = result and _servers_ret.get('result', False)
        comment += ('\n' + _servers_ret.get('comment', ''))
        _changed_servers = _servers_ret.get('changes', {})
        if _changed_servers:
            changes['servers'] = _changed_servers

    ret.update({
        'changes': changes
    })

    if not (changes or expected_config_change):
        ret.update({
            'result': True,
            'comment': 'Device configured properly.'
        })
        return ret

    if __opts__['test'] is True:
        ret.update({
            'result': None,
            'comment': 'This is in testing mode, the device configuration was not changed!'
        })
        return ret

    # <---- Call _set_ntp_peers and _delete_ntp_peers as needed --------------------------------------------------------

    # ----- Try to commit changes ------------------------------------------------------------------------------------->

    if expected_config_change:  # commit only in case there's something to update
        config_result, config_comment = __salt__['net.config_control']()
        result = config_result and successfully_changed
        comment += config_comment

    # <---- Try to commit changes --------------------------------------------------------------------------------------

    ret.update({
        'result': result,
        'comment': comment
    })

    return ret