mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
Multiple improvements to reg executionmod and state mod
This commit is contained in:
parent
8e1b5da2e0
commit
787c88a283
@ -1,29 +1,36 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
Manage the registry on Windows.
|
===========================
|
||||||
|
Manage the Windows registry
|
||||||
|
===========================
|
||||||
|
|
||||||
The read_key and set_key functions will be updated in Boron to reflect proper
|
The read_key and set_key functions will be updated in Boron to reflect proper
|
||||||
registry usage. The registry has three main components. Hives, Keys, and Values.
|
registry usage. The registry has three main components. Hives, Keys, and Values.
|
||||||
|
|
||||||
### Hives
|
-----
|
||||||
|
Hives
|
||||||
|
-----
|
||||||
Hives are the main sections of the registry and all begin with the word HKEY.
|
Hives are the main sections of the registry and all begin with the word HKEY.
|
||||||
- HKEY_LOCAL_MACHINE
|
- HKEY_LOCAL_MACHINE
|
||||||
- HKEY_CURRENT_USER
|
- HKEY_CURRENT_USER
|
||||||
- HKEY_USER
|
- HKEY_USER
|
||||||
|
|
||||||
### Keys
|
----
|
||||||
|
Keys
|
||||||
|
----
|
||||||
Keys are the folders in the registry. Keys can have many nested subkeys. Keys
|
Keys are the folders in the registry. Keys can have many nested subkeys. Keys
|
||||||
can have a value assigned to them under the (Default)
|
can have a value assigned to them under the (Default)
|
||||||
|
|
||||||
### Values
|
-----------------
|
||||||
Values are name/data pairs. There can be many values in a key. The (Default)
|
Values or Entries
|
||||||
value corresponds to the Key, the rest are their own value pairs.
|
-----------------
|
||||||
|
Values/Entries are name/data pairs. There can be many values in a key. The
|
||||||
|
(Default) value corresponds to the Key, the rest are their own value pairs.
|
||||||
|
|
||||||
:depends: - winreg Python module
|
:depends: - winreg Python module
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# TODO: Figure out the exceptions _winreg can raise and properly catch
|
# TODO: Figure out the exceptions _winreg can raise and properly catch them
|
||||||
# them instead of a bare except that catches any exception at all
|
|
||||||
|
|
||||||
# Import third party libs
|
# Import third party libs
|
||||||
try:
|
try:
|
||||||
@ -145,45 +152,36 @@ def read_key(hkey, path, key=None):
|
|||||||
key=path,
|
key=path,
|
||||||
vname=key)
|
vname=key)
|
||||||
|
|
||||||
registry = Registry()
|
return read_value(hive=hkey, key=path)
|
||||||
hive = registry.hkeys[hkey]
|
|
||||||
|
|
||||||
try:
|
|
||||||
value = _winreg.QueryValue(hive, path)
|
|
||||||
if value:
|
|
||||||
ret['vdata'] = value
|
|
||||||
else:
|
|
||||||
ret['vdata'] = None
|
|
||||||
ret['comment'] = 'Empty Value'
|
|
||||||
except WindowsError as exc: # pylint: disable=E0602
|
|
||||||
log.debug(exc)
|
|
||||||
ret['comment'] = '{0}'.format(exc)
|
|
||||||
ret['success'] = False
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def read_value(hive, key, vname=None):
|
def read_value(hive, key, vname=None):
|
||||||
r'''
|
r'''
|
||||||
Reads a registry value or the default value for a key.
|
Reads a registry value entry or the default value for a key.
|
||||||
|
|
||||||
:param hive: string
|
:param str hive:
|
||||||
The name of the hive. Can be one of the following
|
The name of the hive. Can be one of the following
|
||||||
- HKEY_LOCAL_MACHINE or HKLM
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
- HKEY_CURRENT_USER or HKCU
|
- HKEY_CURRENT_USER or HKCU
|
||||||
- HKEY_USER or HKU
|
- HKEY_USER or HKU
|
||||||
|
|
||||||
:param key: string
|
:param str key:
|
||||||
The key (looks like a path) to the value name.
|
The key (looks like a path) to the value name.
|
||||||
|
|
||||||
:param vname: string
|
:param str vname:
|
||||||
The value name. These are the individual name/data pairs under the key. If
|
The value name. These are the individual name/data pairs under the key.
|
||||||
not passed, the key (Default) value will be returned
|
If not passed, the key (Default) value will be returned
|
||||||
|
|
||||||
:return: dict
|
:return:
|
||||||
A dictionary containing the passed settings as well as the value_data if
|
A dictionary containing the passed settings as well as the value_data if
|
||||||
successful. If unsuccessful, sets success to False
|
successful. If unsuccessful, sets success to False
|
||||||
|
|
||||||
|
If vname is not passed:
|
||||||
|
- Returns the first unnamed value (Default) as a string.
|
||||||
|
- Returns none if first unnamed value is empty.
|
||||||
|
- Returns False if key not found.
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
@ -208,9 +206,9 @@ def read_value(hive, key, vname=None):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
handle = _winreg.OpenKey(hive, key)
|
handle = _winreg.OpenKey(hive, key)
|
||||||
value, vtype = _winreg.QueryValueEx(handle, vname)
|
vdata, vtype = _winreg.QueryValueEx(handle, vname)
|
||||||
if value:
|
if vdata:
|
||||||
ret['vdata'] = value
|
ret['vdata'] = vdata
|
||||||
ret['vtype'] = registry.vtype_reverse[vtype]
|
ret['vtype'] = registry.vtype_reverse[vtype]
|
||||||
else:
|
else:
|
||||||
ret['comment'] = 'Empty Value'
|
ret['comment'] = 'Empty Value'
|
||||||
@ -260,39 +258,30 @@ def set_key(hkey, path, value, key=None, vtype='REG_DWORD', reflection=True):
|
|||||||
vdata=value,
|
vdata=value,
|
||||||
vtype=vtype)
|
vtype=vtype)
|
||||||
|
|
||||||
registry = Registry()
|
return set_value(hive=hkey, key=path, vdata=value, vtype=vtype)
|
||||||
hive = registry.hkeys[hkey]
|
|
||||||
vtype = registry.vtype['REG_SZ']
|
|
||||||
|
|
||||||
try:
|
|
||||||
_winreg.SetValue(hive, path, vtype, value)
|
|
||||||
return True
|
|
||||||
except WindowsError as exc: # pylint: disable=E0602
|
|
||||||
log.error(exc)
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True):
|
def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True):
|
||||||
'''
|
'''
|
||||||
Sets a registry value.
|
Sets a registry value entry or the default value for a key.
|
||||||
|
|
||||||
:param hive: string
|
:param str hive:
|
||||||
The name of the hive. Can be one of the following
|
The name of the hive. Can be one of the following
|
||||||
- HKEY_LOCAL_MACHINE or HKLM
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
- HKEY_CURRENT_USER or HKCU
|
- HKEY_CURRENT_USER or HKCU
|
||||||
- HKEY_USER or HKU
|
- HKEY_USER or HKU
|
||||||
|
|
||||||
:param key: string
|
:param str key:
|
||||||
The key (looks like a path) to the value name.
|
The key (looks like a path) to the value name.
|
||||||
|
|
||||||
:param vname: string
|
:param str vname:
|
||||||
The value name. These are the individual name/data pairs under the key. If
|
The value name. These are the individual name/data pairs under the key.
|
||||||
not passed, the key (Default) value will be set.
|
If not passed, the key (Default) value will be set.
|
||||||
|
|
||||||
:param vdata: string
|
:param str vdata:
|
||||||
The value data to be set.
|
The value data to be set.
|
||||||
|
|
||||||
:param vtype: string
|
:param str vtype:
|
||||||
The value type. Can be one of the following:
|
The value type. Can be one of the following:
|
||||||
- REG_BINARY
|
- REG_BINARY
|
||||||
- REG_DWORD
|
- REG_DWORD
|
||||||
@ -300,13 +289,14 @@ def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True
|
|||||||
- REG_MULTI_SZ
|
- REG_MULTI_SZ
|
||||||
- REG_SZ
|
- REG_SZ
|
||||||
|
|
||||||
:param reflection: boolean
|
:param bool reflection:
|
||||||
A boolean value indicating that the value should also be set in the
|
A boolean value indicating that the value should also be set in the
|
||||||
Wow6432Node portion of the registry. Only applies to 64 bit Windows. This
|
Wow6432Node portion of the registry. Only applies to 64 bit Windows.
|
||||||
setting is ignored for 32 bit Windows.
|
This setting is ignored for 32 bit Windows.
|
||||||
|
|
||||||
:return: boolean
|
:return:
|
||||||
Returns True if successful, False if not
|
Returns True if successful, False if not
|
||||||
|
:rtype: bool
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
@ -324,7 +314,7 @@ def set_value(hive, key, vname=None, vdata=None, vtype='REG_SZ', reflection=True
|
|||||||
_winreg.SetValueEx(handle, vname, 0, vtype, vdata)
|
_winreg.SetValueEx(handle, vname, 0, vtype, vdata)
|
||||||
_winreg.CloseKey(handle)
|
_winreg.CloseKey(handle)
|
||||||
return True
|
return True
|
||||||
except WindowsError as exc: # pylint: disable=E0602
|
except (WindowsError, ValueError) as exc: # pylint: disable=E0602
|
||||||
log.error(exc)
|
log.error(exc)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -356,7 +346,7 @@ def create_key(hkey, path, key=None, value=None, reflection=True):
|
|||||||
salt '*' reg.create_key HKEY_CURRENT_USER 'SOFTWARE\\Salt' 'version' '0.97'
|
salt '*' reg.create_key HKEY_CURRENT_USER 'SOFTWARE\\Salt' 'version' '0.97'
|
||||||
'''
|
'''
|
||||||
if key: # This if statement will be removed in Boron
|
if key: # This if statement will be removed in Boron
|
||||||
salt.utils.warn_until('Boron', 'Use reg.set_value to set a registry '
|
salt.utils.warn_until('Boron', 'Use reg.set_value to create a registry '
|
||||||
'value. This functionality will be '
|
'value. This functionality will be '
|
||||||
'removed in Salt Boron')
|
'removed in Salt Boron')
|
||||||
return set_value(hive=hkey,
|
return set_value(hive=hkey,
|
||||||
@ -365,21 +355,10 @@ def create_key(hkey, path, key=None, value=None, reflection=True):
|
|||||||
vdata=value,
|
vdata=value,
|
||||||
vtype='REG_SZ')
|
vtype='REG_SZ')
|
||||||
|
|
||||||
registry = Registry()
|
return set_value(hive=hkey, key=path)
|
||||||
hive = registry.hkeys[hkey]
|
|
||||||
key = path
|
|
||||||
access_mask = registry.reflection_mask[reflection]
|
|
||||||
|
|
||||||
try:
|
|
||||||
handle = _winreg.CreateKeyEx(hive, key, 0, access_mask)
|
|
||||||
_winreg.CloseKey(handle)
|
|
||||||
return True
|
|
||||||
except WindowsError as exc: # pylint: disable=E0602
|
|
||||||
log.error(exc)
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def delete_key(hkey, path, key=None, reflection=True):
|
def delete_key(hkey, path, key=None, reflection=True, force=False):
|
||||||
'''
|
'''
|
||||||
*** Incorrect Usage ***
|
*** Incorrect Usage ***
|
||||||
The name of this function is misleading and will be changed to reflect
|
The name of this function is misleading and will be changed to reflect
|
||||||
@ -399,29 +378,62 @@ def delete_key(hkey, path, key=None, reflection=True):
|
|||||||
|
|
||||||
Delete a registry key
|
Delete a registry key
|
||||||
|
|
||||||
Note: This cannot delete a key with subkeys
|
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' reg.delete_key HKEY_CURRENT_USER 'SOFTWARE\\Salt'
|
salt '*' reg.delete_key HKEY_CURRENT_USER 'SOFTWARE\\Salt'
|
||||||
|
|
||||||
|
:param str hkey: (will be changed to hive)
|
||||||
|
The name of the hive. Can be one of the following
|
||||||
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
|
- HKEY_CURRENT_USER or HKCU
|
||||||
|
- HKEY_USER or HKU
|
||||||
|
|
||||||
|
:param str path: (will be changed to key)
|
||||||
|
The key (looks like a path) to remove.
|
||||||
|
|
||||||
|
:param str key: (used incorrectly)
|
||||||
|
Will be removed in Boron
|
||||||
|
|
||||||
|
:param bool reflection:
|
||||||
|
A boolean value indicating that the value should also be removed from
|
||||||
|
the Wow6432Node portion of the registry. Only applies to 64 bit Windows.
|
||||||
|
This setting is ignored for 32 bit Windows.
|
||||||
|
|
||||||
|
Only applies to delete value. If the key parameter is passed, this
|
||||||
|
function calls delete_value instead. Will be changed in Boron.
|
||||||
|
|
||||||
|
:param bool force:
|
||||||
|
A boolean value indicating that all subkeys should be removed as well.
|
||||||
|
If this is set to False (default) and there are subkeys, the delete_key
|
||||||
|
function will fail.
|
||||||
|
|
||||||
|
:return:
|
||||||
|
Returns True if successful, False if not
|
||||||
|
If force=True, the results of delete_key_recursive are returned.
|
||||||
|
:rtype: bool
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if key: # This if statement will be removed in Boron
|
if key: # This if statement will be removed in Boron
|
||||||
salt.utils.warn_until('Boron', 'Use reg.set_value to set a registry '
|
salt.utils.warn_until('Boron',
|
||||||
'value. This functionality will be '
|
'Variable names will be changed to match Windows '
|
||||||
'removed in Salt Boron')
|
'Registry terminology. These changes will be '
|
||||||
|
'made in Boron')
|
||||||
return delete_value(hive=hkey,
|
return delete_value(hive=hkey,
|
||||||
key=path,
|
key=path,
|
||||||
vname=key,
|
vname=key,
|
||||||
reflection=reflection)
|
reflection=reflection)
|
||||||
|
|
||||||
|
if force:
|
||||||
|
return delete_key_recursive(hkey, path)
|
||||||
|
|
||||||
registry = Registry()
|
registry = Registry()
|
||||||
hive = registry.hkeys[hkey]
|
hive = registry.hkeys[hkey]
|
||||||
key = path
|
key = path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Can't use delete_value to delete a key
|
||||||
_winreg.DeleteKey(hive, key)
|
_winreg.DeleteKey(hive, key)
|
||||||
return True
|
return True
|
||||||
except WindowsError as exc: # pylint: disable=E0602
|
except WindowsError as exc: # pylint: disable=E0602
|
||||||
@ -429,30 +441,100 @@ def delete_key(hkey, path, key=None, reflection=True):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def delete_value(hive, key, vname=None, reflection=True):
|
def delete_key_recursive(hive, key):
|
||||||
'''
|
'''
|
||||||
Deletes a registry value.
|
Delete a registry key to include all subkeys.
|
||||||
|
|
||||||
:param hive: string
|
:param hive:
|
||||||
The name of the hive. Can be one of the following
|
The name of the hive. Can be one of the following
|
||||||
- HKEY_LOCAL_MACHINE or HKLM
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
- HKEY_CURRENT_USER or HKCU
|
- HKEY_CURRENT_USER or HKCU
|
||||||
- HKEY_USER or HKU
|
- HKEY_USER or HKU
|
||||||
|
|
||||||
:param key: string
|
:param key:
|
||||||
|
The key to remove (looks like a path)
|
||||||
|
|
||||||
|
:return:
|
||||||
|
A dictionary listing the keys that deleted successfully as well as those
|
||||||
|
that failed to delete.
|
||||||
|
:rtype: dict
|
||||||
|
'''
|
||||||
|
# Functions for traversing the registry tree
|
||||||
|
def subkeys(key):
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
subkey = _winreg.EnumKey(key, i)
|
||||||
|
yield subkey
|
||||||
|
i += 1
|
||||||
|
except WindowsError:
|
||||||
|
break
|
||||||
|
|
||||||
|
def traverse_registry_tree(hkey, keypath, ret):
|
||||||
|
key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ)
|
||||||
|
for subkeyname in subkeys(key):
|
||||||
|
subkeypath = "{0}\{1}".format(keypath, subkeyname)
|
||||||
|
ret = traverse_registry_tree(hkey, subkeypath, ret)
|
||||||
|
ret.append('{0}'.format(subkeypath))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# Instantiate the registry object
|
||||||
|
registry = Registry()
|
||||||
|
hkey = registry.hkeys[hive]
|
||||||
|
keypath = key
|
||||||
|
|
||||||
|
# Get a reverse list of registry keys to be deleted
|
||||||
|
key_list = []
|
||||||
|
key_list = traverse_registry_tree(hkey, keypath, key_list)
|
||||||
|
|
||||||
|
ret = {'Deleted': [],
|
||||||
|
'Failed': []}
|
||||||
|
|
||||||
|
# Delete all subkeys
|
||||||
|
for keypath in key_list:
|
||||||
|
try:
|
||||||
|
_winreg.DeleteKey(hkey, keypath)
|
||||||
|
ret['Deleted'].append('{0}\{1}'.format(hive, keypath))
|
||||||
|
except WindowsError as exc: # pylint: disable=E0602
|
||||||
|
log.error(exc)
|
||||||
|
ret['Failed'].append('{0}\{1} {2}'.format(hive, key, exc))
|
||||||
|
|
||||||
|
# Delete the key now that all the subkeys are deleted
|
||||||
|
try:
|
||||||
|
_winreg.DeleteKey(hkey, key)
|
||||||
|
ret['Deleted'].append('{0}\{1}'.format(hive, key))
|
||||||
|
except WindowsError as exc: # pylint: disable=E0602
|
||||||
|
log.error(exc)
|
||||||
|
ret['Failed'].append('{0}\{1} {2}'.format(hive, key, exc))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def delete_value(hive, key, vname=None, reflection=True):
|
||||||
|
'''
|
||||||
|
Delete a registry value entry or the default value for a key.
|
||||||
|
|
||||||
|
:param str hive:
|
||||||
|
The name of the hive. Can be one of the following
|
||||||
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
|
- HKEY_CURRENT_USER or HKCU
|
||||||
|
- HKEY_USER or HKU
|
||||||
|
|
||||||
|
:param str key:
|
||||||
The key (looks like a path) to the value name.
|
The key (looks like a path) to the value name.
|
||||||
|
|
||||||
:param vname: string
|
:param str vname:
|
||||||
The value name. These are the individual name/data pairs under the key. If
|
The value name. These are the individual name/data pairs under the key.
|
||||||
not passed, the key (Default) value will be deleted.
|
If not passed, the key (Default) value will be deleted.
|
||||||
|
|
||||||
:param reflection: boolean
|
:param bool reflection:
|
||||||
A boolean value indicating that the value should also be set in the
|
A boolean value indicating that the value should also be set in the
|
||||||
Wow6432Node portion of the registry. Only applies to 64 bit Windows. This
|
Wow6432Node portion of the registry. Only applies to 64 bit Windows.
|
||||||
setting is ignored for 32 bit Windows.
|
This setting is ignored for 32 bit Windows.
|
||||||
|
|
||||||
:return: boolean
|
:return:
|
||||||
Returns True if successful, False if not
|
Returns True if successful, False if not
|
||||||
|
:rtype: bool
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
|
@ -1,9 +1,66 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
'''
|
||||||
Manage the registry on Windows
|
===========================
|
||||||
|
Manage the Windows registry
|
||||||
|
===========================
|
||||||
|
Many python developers think of registry keys as if they were python keys in a
|
||||||
|
dictionary which is not the case. The windows registry is broken down into the
|
||||||
|
following components:
|
||||||
|
|
||||||
|
-----
|
||||||
|
Hives
|
||||||
|
-----
|
||||||
|
|
||||||
|
This is the top level of the registry. They all begin with HKEY.
|
||||||
|
- HKEY_CLASSES_ROOT (HKCR)
|
||||||
|
- HKEY_CURRENT_USER(HKCU)
|
||||||
|
- HKEY_LOCAL MACHINE (HKLM)
|
||||||
|
- HKEY_USER (HKU)
|
||||||
|
- HKEY_CURRENT_CONFIG
|
||||||
|
|
||||||
|
----
|
||||||
|
Keys
|
||||||
|
----
|
||||||
|
|
||||||
|
Hives contain keys. These are basically the folders beneath the hives. They can
|
||||||
|
contain any number of subkeys.
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
Values or Entries
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Values or Entries are the name/data pairs beneath the keys and subkeys. All keys
|
||||||
|
have a default name/data pair. It is usually "(Default)"="(value not set)". The
|
||||||
|
actual value for the name and the date is Null. The registry editor will display
|
||||||
|
"(Default)" and "(value not set)".
|
||||||
|
|
||||||
|
-------
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
The following example is taken from the windows startup portion of the registry:
|
||||||
|
```
|
||||||
|
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
|
||||||
|
"RTHDVCPL"="\"C:\\Program Files\\Realtek\\Audio\\HDA\\RtkNGUI64.exe\" -s"
|
||||||
|
"NvBackend"="\"C:\\Program Files (x86)\\NVIDIA Corporation\\Update Core\\NvBackend.exe\""
|
||||||
|
"BTMTrayAgent"="rundll32.exe \"C:\\Program Files (x86)\\Intel\\Bluetooth\\btmshellex.dll\",TrayApp"
|
||||||
|
```
|
||||||
|
In this example these are the values for each:
|
||||||
|
|
||||||
|
Hive: `HKEY_LOCAL_MACHINE`
|
||||||
|
|
||||||
|
Key and subkeys: `SOFTWARE\Microsoft\Windows\CurrentVersion\Run`
|
||||||
|
|
||||||
|
Value:
|
||||||
|
- There are 3 value names: `RTHDVCPL`, `NvBackend`, and `BTMTrayAgent`
|
||||||
|
- Each value name has a corresponding value
|
||||||
'''
|
'''
|
||||||
|
# Import python libs
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
# Import salt libs
|
||||||
|
import salt.utils
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -21,7 +78,7 @@ def _parse_key_value(key):
|
|||||||
splt = key.split("\\")
|
splt = key.split("\\")
|
||||||
hive = splt.pop(0)
|
hive = splt.pop(0)
|
||||||
vname = splt.pop(-1)
|
vname = splt.pop(-1)
|
||||||
key = r'\\'.join(splt)
|
key = '\\'.join(splt)
|
||||||
return hive, key, vname
|
return hive, key, vname
|
||||||
|
|
||||||
|
|
||||||
@ -31,51 +88,128 @@ def _parse_key(key):
|
|||||||
'''
|
'''
|
||||||
splt = key.split("\\")
|
splt = key.split("\\")
|
||||||
hive = splt.pop(0)
|
hive = splt.pop(0)
|
||||||
key = r'\\'.join(splt)
|
key = '\\'.join(splt)
|
||||||
return hive, key
|
return hive, key
|
||||||
|
|
||||||
|
|
||||||
def present(name, value, vtype='REG_SZ', reflection=True):
|
def present(name, value=None, vname=None, vdata=None, vtype='REG_SZ', reflection=True):
|
||||||
'''
|
'''
|
||||||
Set a registry value
|
Ensure a registry key or value is present.
|
||||||
|
|
||||||
Optionally set ``reflection`` to ``False`` to disable reflection.
|
:param str name:
|
||||||
``reflection`` has no effect on a 32-bit OS.
|
A string value representing the full path of the key to include the
|
||||||
|
HIVE, Key, and all Subkeys. For example:
|
||||||
|
|
||||||
In the example below, this will prevent Windows from silently creating
|
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
|
||||||
the key in:
|
|
||||||
``HKEY_CURRENT_USER\\SOFTWARE\\Wow6432Node\\Salt\\version``
|
Valid hive values include:
|
||||||
|
- HKEY_CURRENT_USER or HKCU
|
||||||
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
|
- HKEY_USERS or HKU
|
||||||
|
|
||||||
|
:param str value:
|
||||||
|
Deprecated. Use vname and vdata instead. Included here for backwards
|
||||||
|
compatability.
|
||||||
|
|
||||||
|
:param str vname:
|
||||||
|
The name of the value you'd like to create beneath the Key. If this
|
||||||
|
parameter is not passed it will assume you want to set the (Default)
|
||||||
|
value
|
||||||
|
|
||||||
|
:param str vdata:
|
||||||
|
The value you'd like to set for the Key. If a value name (vname) is
|
||||||
|
passed, this will be the data for that value name. If not, this will be
|
||||||
|
the (Default) value for the key.
|
||||||
|
|
||||||
|
The type for the (Default) value is always REG_SZ and cannot be changed.
|
||||||
|
This parameter is optional. If not passed, the Key will be created with.
|
||||||
|
|
||||||
|
:param str vtype:
|
||||||
|
The value type for the data you wish to store in the registry. Valid
|
||||||
|
values are:
|
||||||
|
|
||||||
|
- REG_BINARY
|
||||||
|
- REG_DWORD
|
||||||
|
- REG_EXPAND_SZ
|
||||||
|
- REG_MULTI_SZ
|
||||||
|
- REG_SZ (Default)
|
||||||
|
|
||||||
|
:param bool reflection:
|
||||||
|
On 64 bit machines a duplicate value will be created in the
|
||||||
|
``Wow6432Node`` for 32bit programs. This only applies to the SOFTWARE
|
||||||
|
key. This option is ignored on 32bit operating systems. This value
|
||||||
|
defaults to True. Set it to False to disable reflection.
|
||||||
|
|
||||||
|
:return:
|
||||||
|
Returns a dictionary showing the results of the registry operation.
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
The following example will set the ``(Default)`` value for the
|
||||||
|
``SOFTWARE\\Salt`` key in the ``HKEY_CURRENT_USER`` hive to ``0.15.3``. The
|
||||||
|
value will not be reflected in ``Wow6432Node``:
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
HKEY_CURRENT_USER\\SOFTWARE\\Salt\\version:
|
HKEY_CURRENT_USER\\SOFTWARE\\Salt:
|
||||||
reg.present:
|
reg.present:
|
||||||
- value: 0.15.3
|
- vdata: 0.15.3
|
||||||
- vtype: REG_SZ
|
|
||||||
- reflection: False
|
- reflection: False
|
||||||
|
|
||||||
|
The following example will set the value for the ``version`` entry under the
|
||||||
|
``SOFTWARE\\Salt`` key in the ``HKEY_CURRENT_USER`` hive to ``0.15.3``. The
|
||||||
|
value will be reflected in ``Wow6432Node``:
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
HKEY_CURRENT_USER\\SOFTWARE\\Salt:
|
||||||
|
reg.present:
|
||||||
|
- vname: version
|
||||||
|
- vdata: 0.15.3
|
||||||
|
|
||||||
In the above example the path is interpreted as follows:
|
In the above example the path is interpreted as follows:
|
||||||
- ``HKEY_CURRENT_USER`` is the hive
|
- ``HKEY_CURRENT_USER`` is the hive
|
||||||
- ``SOFTWARE\\Salt`` is the key
|
- ``SOFTWARE\\Salt`` is the key
|
||||||
- ``version`` is the value name
|
- ``vname`` is the value name ('version') that will be created under the key
|
||||||
So ``version`` will be created in the ``SOFTWARE\\Salt`` key in the
|
- ``vdata`` is the data that will be assigned to 'version'
|
||||||
``HKEY_CURRENT_USER`` hive and given the ``REG_SZ`` value of ``0.15.3``.
|
|
||||||
'''
|
'''
|
||||||
ret = {'name': name,
|
ret = {'name': name,
|
||||||
'result': True,
|
'result': True,
|
||||||
'changes': {},
|
'changes': {},
|
||||||
'comment': ''}
|
'comment': ''}
|
||||||
|
|
||||||
|
# This is for backwards compatibility
|
||||||
|
# If 'value' is passed a value, vdata becomes value and the vname is
|
||||||
|
# obtained from the key path
|
||||||
|
if value:
|
||||||
hive, key, vname = _parse_key_value(name)
|
hive, key, vname = _parse_key_value(name)
|
||||||
|
vdata = value
|
||||||
|
ret['comment'] = 'State file is using deprecated syntax. Please update.'
|
||||||
|
salt.utils.warn_until(
|
||||||
|
'Boron',
|
||||||
|
'The \'value\' argument has been deprecated. '
|
||||||
|
'Please use vdata instead.'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
hive, key = _parse_key(name)
|
||||||
|
|
||||||
# Determine what to do
|
# Determine what to do
|
||||||
if value == __salt__['reg.read_value'](hive, key, vname)['vdata']:
|
reg_current = __salt__['reg.read_value'](hive, key, vname)
|
||||||
ret['comment'] = '{0} is already configured'.format(name)
|
|
||||||
|
if vdata == reg_current['vdata'] and reg_current['success']:
|
||||||
|
ret['comment'] = '{0} in {1} is already configured'.\
|
||||||
|
format(vname if vname else '(Default)', name)
|
||||||
return ret
|
return ret
|
||||||
else:
|
|
||||||
ret['changes'] = {'reg': 'configured to {0}'.format(value)}
|
ret['changes'] = {'reg': {
|
||||||
|
'Added': {
|
||||||
|
'Key': '{0}\{1}'.format(hive, key),
|
||||||
|
'Entry': '{0}'.format(vname if vname else '(Default)'),
|
||||||
|
'Value': '{0}'.format(vdata if vdata else '(Empty String)')
|
||||||
|
}}}
|
||||||
|
|
||||||
# Check for test option
|
# Check for test option
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
@ -83,19 +217,19 @@ def present(name, value, vtype='REG_SZ', reflection=True):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
# Configure the value
|
# Configure the value
|
||||||
ret['result'] = __salt__['reg.set_value'](hive, key, vname, value, vtype,
|
ret['result'] = __salt__['reg.set_value'](hive, key, vname, vdata, vtype,
|
||||||
reflection)
|
reflection)
|
||||||
|
|
||||||
if not ret:
|
if not ret['result']:
|
||||||
ret['changes'] = {}
|
ret['changes'] = {}
|
||||||
ret['comment'] = 'could not configure the registry key'
|
ret['comment'] = 'Could not configure the registry key'
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def absent(name):
|
def absent(name, vname=None):
|
||||||
'''
|
'''
|
||||||
Remove a registry value
|
Ensure a registry value is removed. To remove a key use key_absent.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
@ -114,14 +248,20 @@ def absent(name):
|
|||||||
'changes': {},
|
'changes': {},
|
||||||
'comment': ''}
|
'comment': ''}
|
||||||
|
|
||||||
hive, key, vname = _parse_key_value(name)
|
hive, key = _parse_key(name)
|
||||||
|
|
||||||
# Determine what to do
|
# Determine what to do
|
||||||
|
if not __salt__['reg.read_value'](hive, key, vname)['success']:
|
||||||
|
hive, key, vname = _parse_key_value(name)
|
||||||
if not __salt__['reg.read_value'](hive, key, vname)['success']:
|
if not __salt__['reg.read_value'](hive, key, vname)['success']:
|
||||||
ret['comment'] = '{0} is already absent'.format(name)
|
ret['comment'] = '{0} is already absent'.format(name)
|
||||||
return ret
|
return ret
|
||||||
else:
|
|
||||||
ret['changes'] = {'reg': 'Removed {0}'.format(name)}
|
ret['changes'] = {'reg': {
|
||||||
|
'Removed': {
|
||||||
|
'Key': '{0}\{1}'.format(hive, key),
|
||||||
|
'Entry': '{0}'.format(vname if vname else '(Default)')
|
||||||
|
}}}
|
||||||
|
|
||||||
# Check for test option
|
# Check for test option
|
||||||
if __opts__['test']:
|
if __opts__['test']:
|
||||||
@ -131,6 +271,73 @@ def absent(name):
|
|||||||
# Delete the value
|
# Delete the value
|
||||||
ret['result'] = __salt__['reg.delete_value'](hive, key, vname)
|
ret['result'] = __salt__['reg.delete_value'](hive, key, vname)
|
||||||
if not ret['result']:
|
if not ret['result']:
|
||||||
|
ret['changes'] = {}
|
||||||
|
ret['comment'] = 'failed to remove {0} from {1}\{2}'.format(name, hive,
|
||||||
|
key)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def key_absent(name, force=False):
|
||||||
|
'''
|
||||||
|
Ensure a registry key is removed. This will remove a key and all value
|
||||||
|
entries it contains. It will fail if the key contains subkeys.
|
||||||
|
|
||||||
|
:param str name:
|
||||||
|
A string representing the full path to the key to be removed to include
|
||||||
|
the hive and the keypath. The hive can be any of the following:
|
||||||
|
- HKEY_LOCAL_MACHINE or HKLM
|
||||||
|
- HKEY_CURRENT_USER or HKCU
|
||||||
|
- HKEY_USER or HKU
|
||||||
|
|
||||||
|
:param bool force:
|
||||||
|
A boolean value indicating that all subkeys should be deleted with the
|
||||||
|
key. If force=False and subkeys exists beneath the key you want to
|
||||||
|
delete, key_absent will fail. Use with caution. The default is False.
|
||||||
|
|
||||||
|
:return:
|
||||||
|
Returns a dictionary showing the results of the registry operation.
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
The following example will delete the ``SOFTWARE\Salt`` key and all subkeys
|
||||||
|
under the ``HKEY_CURRENT_USER`` hive.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
'HKEY_CURRENT_USER\SOFTWARE\Salt':
|
||||||
|
reg.key_absent:
|
||||||
|
- force: True
|
||||||
|
|
||||||
|
In the above example the path is interpreted as follows:
|
||||||
|
- ``HKEY_CURRENT_USER`` is the hive
|
||||||
|
- ``SOFTWARE\Salt`` is the key
|
||||||
|
'''
|
||||||
|
ret = {'name': name,
|
||||||
|
'result': True,
|
||||||
|
'changes': {},
|
||||||
|
'comment': ''}
|
||||||
|
|
||||||
|
hive, key = _parse_key(name)
|
||||||
|
|
||||||
|
# Determine what to do
|
||||||
|
if not __salt__['reg.read_value'](hive, key)['success']:
|
||||||
|
ret['comment'] = '{0} is already absent'.format(name)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
ret['changes'] = {'reg': {
|
||||||
|
'Removed': {
|
||||||
|
'Key': '{0}\{1}'.format(hive, key)
|
||||||
|
}}}
|
||||||
|
|
||||||
|
# Check for test option
|
||||||
|
if __opts__['test']:
|
||||||
|
ret['result'] = None
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# Delete the value
|
||||||
|
__salt__['reg.delete_key'](hive, key, force=force)
|
||||||
|
if __salt__['reg.read_value'](hive, key)['success']:
|
||||||
|
ret['result'] = False
|
||||||
ret['changes'] = {}
|
ret['changes'] = {}
|
||||||
ret['comment'] = 'failed to remove registry key {0}'.format(name)
|
ret['comment'] = 'failed to remove registry key {0}'.format(name)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user