mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #47107 from twangboy/fix_46932
Fix issues with reg state, add tests
This commit is contained in:
commit
50bd885ec7
4 changed files with 341 additions and 28 deletions
|
@ -192,11 +192,8 @@ def present(name,
|
|||
salt.utils.stringutils.to_unicode(name, 'utf-8'))
|
||||
return ret
|
||||
|
||||
try:
|
||||
vdata_decoded = salt.utils.stringutils.to_unicode(vdata, 'utf-8')
|
||||
except UnicodeDecodeError:
|
||||
# vdata contains binary data that can't be decoded
|
||||
vdata_decoded = vdata
|
||||
vdata_decoded = __utils__['reg.cast_vdata'](vdata=vdata, vtype=vtype)
|
||||
|
||||
add_change = {'Key': r'{0}\{1}'.format(hive, key),
|
||||
'Entry': '{0}'.format(salt.utils.stringutils.to_unicode(vname, 'utf-8') if vname else '(Default)'),
|
||||
'Value': vdata_decoded}
|
||||
|
|
|
@ -45,6 +45,7 @@ except ImportError:
|
|||
import salt.utils.platform
|
||||
import salt.utils.stringutils
|
||||
from salt.exceptions import CommandExecutionError
|
||||
from salt.ext import six
|
||||
|
||||
PY2 = sys.version_info[0] == 2
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -169,7 +170,10 @@ def key_exists(hive, key, use_32bit_registry=False):
|
|||
local_key = _to_unicode(key)
|
||||
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
access_mask = registry.registry_32[use_32bit_registry]
|
||||
|
||||
try:
|
||||
|
@ -231,7 +235,10 @@ def list_keys(hive, key=None, use_32bit_registry=False):
|
|||
local_key = _to_unicode(key)
|
||||
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
access_mask = registry.registry_32[use_32bit_registry]
|
||||
|
||||
subkeys = []
|
||||
|
@ -287,7 +294,10 @@ def list_values(hive, key=None, use_32bit_registry=False, include_default=True):
|
|||
local_key = _to_unicode(key)
|
||||
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
access_mask = registry.registry_32[use_32bit_registry]
|
||||
handle = None
|
||||
values = list()
|
||||
|
@ -378,7 +388,10 @@ def read_value(hive, key, vname=None, use_32bit_registry=False):
|
|||
ret['vname'] = '(Default)'
|
||||
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
access_mask = registry.registry_32[use_32bit_registry]
|
||||
|
||||
try:
|
||||
|
@ -524,26 +537,14 @@ def set_value(hive,
|
|||
local_vtype = _to_unicode(vtype)
|
||||
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
vtype_value = registry.vtype[local_vtype]
|
||||
access_mask = registry.registry_32[use_32bit_registry] | win32con.KEY_ALL_ACCESS
|
||||
|
||||
# Check data type and cast to expected type
|
||||
# int will automatically become long on 64bit numbers
|
||||
# https://www.python.org/dev/peps/pep-0237/
|
||||
|
||||
# String Types to Unicode
|
||||
if vtype_value in [win32con.REG_SZ, win32con.REG_EXPAND_SZ]:
|
||||
local_vdata = _to_unicode(vdata)
|
||||
# Don't touch binary...
|
||||
elif vtype_value == win32con.REG_BINARY:
|
||||
local_vdata = vdata
|
||||
# Make sure REG_MULTI_SZ is a list of strings
|
||||
elif vtype_value == win32con.REG_MULTI_SZ:
|
||||
local_vdata = [_to_unicode(i) for i in vdata]
|
||||
# Everything else is int
|
||||
else:
|
||||
local_vdata = int(vdata)
|
||||
local_vdata = cast_vdata(vdata=vdata, vtype=local_vtype)
|
||||
|
||||
if volatile:
|
||||
create_options = registry.opttype['REG_OPTION_VOLATILE']
|
||||
|
@ -563,6 +564,52 @@ def set_value(hive,
|
|||
return False
|
||||
|
||||
|
||||
def cast_vdata(vdata=None, vtype='REG_SZ'):
|
||||
'''
|
||||
Cast the ``vdata` value to the appropriate data type for the registry type
|
||||
specified in ``vtype``
|
||||
|
||||
Args:
|
||||
|
||||
vdata (str, list, bin): The data to cast
|
||||
|
||||
vtype (str):
|
||||
The type of data to be written to the registry. Must be one of the
|
||||
following:
|
||||
- REG_BINARY
|
||||
- REG_DWORD
|
||||
- REG_EXPAND_SZ
|
||||
- REG_MULTI_SZ
|
||||
- REG_SZ
|
||||
|
||||
Returns:
|
||||
The vdata cast to the appropriate type. Will be unicode string, binary,
|
||||
list of unicode strings, or int
|
||||
'''
|
||||
# Check data type and cast to expected type
|
||||
# int will automatically become long on 64bit numbers
|
||||
# https://www.python.org/dev/peps/pep-0237/
|
||||
|
||||
registry = Registry()
|
||||
vtype_value = registry.vtype[vtype]
|
||||
|
||||
# String Types to Unicode
|
||||
if vtype_value in [win32con.REG_SZ, win32con.REG_EXPAND_SZ]:
|
||||
return _to_unicode(vdata)
|
||||
# Don't touch binary... if it's binary
|
||||
elif vtype_value == win32con.REG_BINARY:
|
||||
if isinstance(vdata, six.text_type):
|
||||
# Unicode data must be encoded
|
||||
return vdata.encode('utf-8')
|
||||
return vdata
|
||||
# Make sure REG_MULTI_SZ is a list of strings
|
||||
elif vtype_value == win32con.REG_MULTI_SZ:
|
||||
return [_to_unicode(i) for i in vdata]
|
||||
# Everything else is int
|
||||
else:
|
||||
return int(vdata)
|
||||
|
||||
|
||||
def delete_key_recursive(hive, key, use_32bit_registry=False):
|
||||
'''
|
||||
.. versionadded:: 2015.5.4
|
||||
|
@ -601,7 +648,10 @@ def delete_key_recursive(hive, key, use_32bit_registry=False):
|
|||
|
||||
# Instantiate the registry object
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
key_path = local_key
|
||||
access_mask = registry.registry_32[use_32bit_registry] | win32con.KEY_ALL_ACCESS
|
||||
|
||||
|
@ -699,7 +749,10 @@ def delete_value(hive, key, vname=None, use_32bit_registry=False):
|
|||
local_vname = _to_unicode(vname)
|
||||
|
||||
registry = Registry()
|
||||
hkey = registry.hkeys[local_hive]
|
||||
try:
|
||||
hkey = registry.hkeys[local_hive]
|
||||
except KeyError:
|
||||
raise CommandExecutionError('Invalid Hive: {0}'.format(local_hive))
|
||||
access_mask = registry.registry_32[use_32bit_registry] | win32con.KEY_ALL_ACCESS
|
||||
|
||||
try:
|
||||
|
|
262
tests/integration/states/test_reg.py
Normal file
262
tests/integration/states/test_reg.py
Normal file
|
@ -0,0 +1,262 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Tests for the Reg State
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
import logging
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.mixins import SaltReturnAssertsMixin
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.helpers import destructiveTest, generate_random_name
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.platform
|
||||
import salt.utils.win_reg as reg
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__testcontext__ = {}
|
||||
|
||||
UNICODE_VALUE_NAME = 'Unicode Key \N{TRADE MARK SIGN}'
|
||||
UNICODE_VALUE = 'Unicode Value ' \
|
||||
'\N{COPYRIGHT SIGN},\N{TRADE MARK SIGN},\N{REGISTERED SIGN}'
|
||||
FAKE_KEY = 'SOFTWARE\\{0}'.format(generate_random_name('SaltTesting-'))
|
||||
|
||||
|
||||
@destructiveTest
|
||||
@skipIf(not salt.utils.platform.is_windows(), 'Windows Specific Test')
|
||||
class RegTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
'''
|
||||
Reg state module tests
|
||||
These tests are destructive as the modify the registry
|
||||
'''
|
||||
def tearDown(self):
|
||||
reg.delete_key_recursive(hive='HKLM',
|
||||
key=FAKE_KEY)
|
||||
reg.delete_key_recursive(hive='HKLM',
|
||||
key=FAKE_KEY,
|
||||
use_32bit_registry=True)
|
||||
|
||||
def test_present_reg_sz(self):
|
||||
'''
|
||||
Testing reg.present with REG_SZ
|
||||
'''
|
||||
log.debug('Testing reg.present with REG_SZ')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vname='test_reg_sz',
|
||||
vdata='fake string data')
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': 'test_reg_sz',
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': 'fake string data'}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM', key=FAKE_KEY, vname='test_reg_sz')
|
||||
expected = {
|
||||
'vtype': 'REG_SZ',
|
||||
'vname': 'test_reg_sz',
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': 'fake string data',
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
||||
|
||||
def test_present_reg_sz_unicode_value(self):
|
||||
'''
|
||||
Testing reg.present with REG_SZ and a unicode value
|
||||
'''
|
||||
log.debug('Testing reg.present with REG_SZ and a unicode value')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vname='test_reg_sz',
|
||||
vdata=UNICODE_VALUE)
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': 'test_reg_sz',
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': UNICODE_VALUE}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM', key=FAKE_KEY, vname='test_reg_sz')
|
||||
expected = {
|
||||
'vtype': 'REG_SZ',
|
||||
'vname': 'test_reg_sz',
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': UNICODE_VALUE,
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
||||
|
||||
def test_present_reg_sz_unicode_default_value(self):
|
||||
'''
|
||||
Testing reg.present with REG_SZ and a unicode default value
|
||||
'''
|
||||
log.debug('Testing reg.present with REG_SZ and a unicode default value')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vdata=UNICODE_VALUE)
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': '(Default)',
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': UNICODE_VALUE}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM', key=FAKE_KEY)
|
||||
|
||||
expected = {
|
||||
'vtype': 'REG_SZ',
|
||||
'vname': '(Default)',
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': UNICODE_VALUE,
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
||||
|
||||
def test_present_reg_sz_unicode_value_name(self):
|
||||
'''
|
||||
Testing reg.present with REG_SZ and a unicode value name
|
||||
'''
|
||||
log.debug('Testing reg.present with REG_SZ and a unicode value name')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vname=UNICODE_VALUE_NAME,
|
||||
vdata='fake string data')
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': UNICODE_VALUE_NAME,
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': 'fake string data'}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM', key=FAKE_KEY, vname=UNICODE_VALUE_NAME)
|
||||
|
||||
expected = {
|
||||
'vtype': 'REG_SZ',
|
||||
'vname': UNICODE_VALUE_NAME,
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': 'fake string data',
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
||||
|
||||
def test_present_reg_binary(self):
|
||||
'''
|
||||
Testing reg.present with REG_BINARY
|
||||
'''
|
||||
test_data = 'Salty Test'
|
||||
log.debug('Testing reg.present with REG_BINARY')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vname='test_reg_binary',
|
||||
vtype='REG_BINARY',
|
||||
vdata=test_data)
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': 'test_reg_binary',
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': test_data}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM', key=FAKE_KEY, vname='test_reg_binary')
|
||||
expected = {
|
||||
'vtype': 'REG_BINARY',
|
||||
'vname': 'test_reg_binary',
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': test_data.encode('utf-8'),
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
||||
|
||||
def test_present_reg_multi_sz(self):
|
||||
'''
|
||||
Testing reg.present with REG_MULTI_SZ
|
||||
'''
|
||||
log.debug('Testing reg.present with REG_MULTI_SZ')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vname='test_reg_multi_sz',
|
||||
vtype='REG_MULTI_SZ',
|
||||
vdata=['item1', 'item2'])
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': 'test_reg_multi_sz',
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': ['item1', 'item2']}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM',
|
||||
key=FAKE_KEY,
|
||||
vname='test_reg_multi_sz')
|
||||
expected = {
|
||||
'vtype': 'REG_MULTI_SZ',
|
||||
'vname': 'test_reg_multi_sz',
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': ['item1', 'item2'],
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
||||
|
||||
def test_present_32_bit(self):
|
||||
'''
|
||||
Testing reg.present with REG_SZ using 32bit registry
|
||||
'''
|
||||
log.debug('Testing reg.present with REG_SZ using 32bit registry')
|
||||
# default type is 'REG_SZ'
|
||||
# Does the state return the correct data
|
||||
ret = self.run_state('reg.present',
|
||||
name='HKLM\\{0}'.format(FAKE_KEY),
|
||||
vname='test_reg_sz',
|
||||
vdata='fake string data',
|
||||
use_32bit_registry=True)
|
||||
|
||||
expected = {
|
||||
'reg': {
|
||||
'Added': {
|
||||
'Entry': 'test_reg_sz',
|
||||
'Key': 'HKLM\\{0}'.format(FAKE_KEY),
|
||||
'Value': 'fake string data'}}}
|
||||
self.assertSaltStateChangesEqual(ret, expected)
|
||||
|
||||
# Is the value actually set
|
||||
ret = reg.read_value(hive='HKLM',
|
||||
key=FAKE_KEY,
|
||||
vname='test_reg_sz',
|
||||
use_32bit_registry=True)
|
||||
expected = {
|
||||
'vtype': 'REG_SZ',
|
||||
'vname': 'test_reg_sz',
|
||||
'success': True,
|
||||
'hive': 'HKLM',
|
||||
'vdata': 'fake string data',
|
||||
'key': FAKE_KEY}
|
||||
self.assertEqual(ret, expected)
|
|
@ -27,6 +27,7 @@ integration.runners.test_jobs
|
|||
integration.runners.test_salt
|
||||
integration.sdb.test_env
|
||||
integration.states.test_host
|
||||
integration.states.test_reg
|
||||
integration.states.test_renderers
|
||||
integration.utils.testprogram
|
||||
integration.wheel.test_client
|
||||
|
|
Loading…
Add table
Reference in a new issue