mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #47552 from twangboy/fix_46981
Show GPO settings, raise error if trying to set gpo managed settings
This commit is contained in:
commit
799fce979d
3 changed files with 145 additions and 22 deletions
17
doc/topics/releases/2017.7.7.rst
Normal file
17
doc/topics/releases/2017.7.7.rst
Normal file
|
@ -0,0 +1,17 @@
|
|||
===========================
|
||||
In Progress: Salt 2017.7.7 Release Notes
|
||||
===========================
|
||||
|
||||
Version 2017.7.7 is an **unreleased** bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
|
||||
This release is still in progress and has not been released yet.
|
||||
|
||||
New win_snmp behavior
|
||||
---------------------
|
||||
|
||||
`win_snmp.get_community_names` now returns the SNMP settings actually in effect
|
||||
on the box. If settings are managed via GroupPolicy, those settings will be
|
||||
returned. Otherwise, normal settings are returned.
|
||||
|
||||
`win_snmp.set_community_names` now raises a CommandExecutionError when SNMP
|
||||
settings are being managed by GroupPolicy
|
||||
|
|
@ -9,17 +9,21 @@ from __future__ import absolute_import
|
|||
import logging
|
||||
|
||||
# Import salt libs
|
||||
from salt.exceptions import SaltInvocationError
|
||||
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
||||
import salt.utils
|
||||
|
||||
# Import 3rd party libs
|
||||
from salt.ext import six
|
||||
|
||||
_HKEY = 'HKLM'
|
||||
|
||||
_SNMP_KEY = r'SYSTEM\CurrentControlSet\Services\SNMP\Parameters'
|
||||
_AGENT_KEY = r'{0}\RFC1156Agent'.format(_SNMP_KEY)
|
||||
_COMMUNITIES_KEY = r'{0}\ValidCommunities'.format(_SNMP_KEY)
|
||||
|
||||
_SNMP_GPO_KEY = r'SOFTWARE\Policies\SNMP\Parameters'
|
||||
_COMMUNITIES_GPO_KEY = r'{0}\ValidCommunities'.format(_SNMP_GPO_KEY)
|
||||
|
||||
_PERMISSION_TYPES = {'None': 1,
|
||||
'Notify': 2,
|
||||
'Read Only': 4,
|
||||
|
@ -285,6 +289,21 @@ def get_community_names():
|
|||
'''
|
||||
Get the current accepted SNMP community names and their permissions.
|
||||
|
||||
If community names are being managed by Group Policy, those values will be
|
||||
returned instead like this:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
TestCommunity:
|
||||
Managed by GPO
|
||||
|
||||
Community names managed normally will denote the permission instead:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
TestCommunity:
|
||||
Read Only
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of community names and permissions.
|
||||
|
||||
|
@ -295,25 +314,69 @@ def get_community_names():
|
|||
salt '*' win_snmp.get_community_names
|
||||
'''
|
||||
ret = dict()
|
||||
current_values = __salt__['reg.list_values'](
|
||||
_HKEY, _COMMUNITIES_KEY, include_default=False)
|
||||
|
||||
# The communities are stored as the community name with a numeric permission
|
||||
# value. Convert the numeric value to the text equivalent, as present in the
|
||||
# Windows SNMP service GUI.
|
||||
if isinstance(current_values, list):
|
||||
for current_value in current_values:
|
||||
# Look in GPO settings first
|
||||
if __salt__['reg.key_exists'](_HKEY, _COMMUNITIES_GPO_KEY):
|
||||
|
||||
# Ignore error values
|
||||
if not isinstance(current_value, dict):
|
||||
continue
|
||||
_LOG.debug('Loading communities from Group Policy settings')
|
||||
|
||||
permissions = str()
|
||||
for permission_name in _PERMISSION_TYPES:
|
||||
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
|
||||
permissions = permission_name
|
||||
break
|
||||
ret[current_value['vname']] = permissions
|
||||
current_values = __salt__['reg.list_values'](
|
||||
_HKEY, _COMMUNITIES_GPO_KEY, include_default=False)
|
||||
|
||||
# GPO settings are different in that they do not designate permissions
|
||||
# They are a numbered list of communities like so:
|
||||
#
|
||||
# {1: "community 1",
|
||||
# 2: "community 2"}
|
||||
#
|
||||
# Denote that it is being managed by Group Policy.
|
||||
#
|
||||
# community 1:
|
||||
# Managed by GPO
|
||||
# community 2:
|
||||
# Managed by GPO
|
||||
if isinstance(current_values, list):
|
||||
for current_value in current_values:
|
||||
|
||||
# Ignore error values
|
||||
if not isinstance(current_value, dict):
|
||||
continue
|
||||
|
||||
ret[current_value['vdata']] = 'Managed by GPO'
|
||||
|
||||
if not ret:
|
||||
|
||||
_LOG.debug('Loading communities from SNMP settings')
|
||||
|
||||
current_values = __salt__['reg.list_values'](
|
||||
_HKEY, _COMMUNITIES_KEY, include_default=False)
|
||||
|
||||
# The communities are stored as the community name with a numeric
|
||||
# permission value. Like this (4 = Read Only):
|
||||
#
|
||||
# {"community 1": 4,
|
||||
# "community 2": 4}
|
||||
#
|
||||
# Convert the numeric value to the text equivalent, as present in the
|
||||
# Windows SNMP service GUI.
|
||||
#
|
||||
# community 1:
|
||||
# Read Only
|
||||
# community 2:
|
||||
# Read Only
|
||||
if isinstance(current_values, list):
|
||||
for current_value in current_values:
|
||||
|
||||
# Ignore error values
|
||||
if not isinstance(current_value, dict):
|
||||
continue
|
||||
|
||||
permissions = str()
|
||||
for permission_name in _PERMISSION_TYPES:
|
||||
if current_value['vdata'] == _PERMISSION_TYPES[permission_name]:
|
||||
permissions = permission_name
|
||||
break
|
||||
ret[current_value['vname']] = permissions
|
||||
|
||||
if not ret:
|
||||
_LOG.debug('Unable to find existing communities.')
|
||||
|
@ -324,6 +387,11 @@ def set_community_names(communities):
|
|||
'''
|
||||
Manage the SNMP accepted community names and their permissions.
|
||||
|
||||
.. note::
|
||||
Settings managed by Group Policy will always take precedence over those
|
||||
set using the SNMP interface. Therefore if this function finds Group
|
||||
Policy settings it will raise a CommandExecutionError
|
||||
|
||||
Args:
|
||||
communities (dict): A dictionary of SNMP community names and
|
||||
permissions. The possible permissions can be found via
|
||||
|
@ -332,6 +400,10 @@ def set_community_names(communities):
|
|||
Returns:
|
||||
bool: True if successful, otherwise False
|
||||
|
||||
Raises:
|
||||
CommandExecutionError:
|
||||
If SNMP settings are being managed by Group Policy
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -340,6 +412,11 @@ def set_community_names(communities):
|
|||
'''
|
||||
values = dict()
|
||||
|
||||
if __salt__['reg.key_exists'](_HKEY, _COMMUNITIES_GPO_KEY):
|
||||
_LOG.debug('Communities on this system are managed by Group Policy')
|
||||
raise CommandExecutionError(
|
||||
'Communities on this system are managed by Group Policy')
|
||||
|
||||
current_communities = get_community_names()
|
||||
|
||||
if communities == current_communities:
|
||||
|
|
|
@ -11,6 +11,7 @@ from __future__ import absolute_import
|
|||
|
||||
# Import Salt Libs
|
||||
import salt.modules.win_snmp as win_snmp
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
|
@ -70,19 +71,47 @@ class WinSnmpTestCase(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
Test - Get the current accepted SNMP community names and their permissions.
|
||||
'''
|
||||
mock_value = MagicMock(return_value=[{'vdata': 16,
|
||||
'vname': 'TestCommunity'}])
|
||||
with patch.dict(win_snmp.__salt__, {'reg.list_values': mock_value}):
|
||||
mock_ret = MagicMock(return_value=[{'vdata': 16,
|
||||
'vname': 'TestCommunity'}])
|
||||
mock_false = MagicMock(return_value=False)
|
||||
with patch.dict(win_snmp.__salt__, {'reg.list_values': mock_ret,
|
||||
'reg.key_exists': mock_false}):
|
||||
self.assertEqual(win_snmp.get_community_names(),
|
||||
COMMUNITY_NAMES)
|
||||
|
||||
def test_get_community_names_gpo(self):
|
||||
'''
|
||||
Test - Get the current accepted SNMP community names and their permissions.
|
||||
'''
|
||||
mock_ret = MagicMock(return_value=[{'vdata': 'TestCommunity',
|
||||
'vname': 1}])
|
||||
mock_false = MagicMock(return_value=True)
|
||||
with patch.dict(win_snmp.__salt__, {'reg.list_values': mock_ret,
|
||||
'reg.key_exists': mock_false}):
|
||||
self.assertEqual(win_snmp.get_community_names(),
|
||||
{'TestCommunity': 'Managed by GPO'})
|
||||
|
||||
def test_set_community_names(self):
|
||||
'''
|
||||
Test - Manage the SNMP accepted community names and their permissions.
|
||||
'''
|
||||
mock_value = MagicMock(return_value=True)
|
||||
mock_true = MagicMock(return_value=True)
|
||||
kwargs = {'communities': COMMUNITY_NAMES}
|
||||
with patch.dict(win_snmp.__salt__, {'reg.set_value': mock_value}), \
|
||||
mock_false = MagicMock(return_value=False)
|
||||
with patch.dict(win_snmp.__salt__, {'reg.set_value': mock_true,
|
||||
'reg.key_exists': mock_false}), \
|
||||
patch('salt.modules.win_snmp.get_community_names',
|
||||
MagicMock(return_value=COMMUNITY_NAMES)):
|
||||
self.assertTrue(win_snmp.set_community_names(**kwargs))
|
||||
|
||||
def test_set_community_names_gpo(self):
|
||||
'''
|
||||
Test - Manage the SNMP accepted community names and their permissions.
|
||||
'''
|
||||
mock_true = MagicMock(return_value=True)
|
||||
kwargs = {'communities': COMMUNITY_NAMES}
|
||||
with patch.dict(win_snmp.__salt__, {'reg.set_value': mock_true,
|
||||
'reg.key_exists': mock_true}), \
|
||||
patch('salt.modules.win_snmp.get_community_names',
|
||||
MagicMock(return_value=COMMUNITY_NAMES)):
|
||||
self.assertRaises(CommandExecutionError, win_snmp.set_community_names, **kwargs)
|
||||
|
|
Loading…
Add table
Reference in a new issue