Add Win WUSA management, to install Windows Update files (.msu).

Fixes #46292
This commit is contained in:
Thomas Lemarchand 2018-11-06 18:02:20 +01:00 committed by Gareth J. Greenaway
parent 12e0d80271
commit 16525e4312
No known key found for this signature in database
GPG key ID: 10B62F8A7CAD7A41
2 changed files with 167 additions and 0 deletions

52
salt/modules/win_wusa.py Normal file
View file

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
'''
Microsoft Update files management via wusa.exe
:maintainer: Thomas Lemarchand
:platform: Windows
:depends: PowerShell
'''
# Import python libs
from __future__ import absolute_import
import logging
# Import salt libs
import salt.utils.platform
log = logging.getLogger(__name__)
# Define the module's virtual name
__virtualname__ = 'win_wusa'
def __virtual__():
'''
Load only on Windows
'''
if not salt.utils.platform.is_windows():
return False, 'Only available on Windows systems'
powershell_info = __salt__['cmd.shell_info']('powershell', True)
if not powershell_info['installed']:
return False, 'PowerShell not available'
return __virtualname__
def is_installed(kb):
get_hotfix_result = __salt__['cmd.powershell_all']('Get-HotFix -Id {0}'.format(kb), ignore_retcode=True)
return get_hotfix_result['retcode'] == 0
def install(path):
return __salt__['cmd.run_all']('wusa.exe {0} /quiet /norestart'.format(path), ignore_retcode=True)
def uninstall(kb):
return __salt__['cmd.run_all']('wusa.exe /uninstall /kb:{0} /quiet /norestart'.format(kb[2:]), ignore_retcode=True)

115
salt/states/win_wusa.py Normal file
View file

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
'''
Microsoft Updates (KB) Management
This module provides the ability to enforce KB installations
from files (.msu), without WSUS.
'''
# Import python libs
from __future__ import absolute_import
import logging
# Import salt libs
import salt.utils.platform
import salt.exceptions
log = logging.getLogger(__name__)
# Define the module's virtual name
__virtualname__ = 'win_wusa'
def __virtual__():
'''
Load only on Windows
'''
if not salt.utils.platform.is_windows():
return False, 'Only available on Windows systems'
return __virtualname__
def installed(name, source):
'''
Enforce the installed state of a KB
name
Name of the Windows KB ("KB123456")
source
Source of .msu file corresponding to the KB
'''
ret = {
'name': name,
'changes': {},
'result': False,
'comment': '',
'pchanges': {},
}
# Start with basic error-checking. Do all the passed parameters make sense
# and agree with each-other?
if not name or not source:
raise salt.exceptions.SaltInvocationError(
'Arguments "name" and "source" are mandatory.')
# Check the current state of the system. Does anything need to change?
current_state = __salt__['win_wusa.is_installed'](name)
if current_state:
ret['result'] = True
ret['comment'] = 'KB already installed'
return ret
# The state of the system does need to be changed. Check if we're running
# in ``test=true`` mode.
if __opts__['test'] is True:
ret['comment'] = 'The KB "{0}" will be installed.'.format(name)
ret['pchanges'] = {
'old': current_state,
'new': True,
}
# Return ``None`` when running with ``test=true``.
ret['result'] = None
return ret
try:
result = __states__['file.cached'](source,
skip_verify=True,
saltenv=__env__)
except Exception as exc:
msg = 'Failed to cache {0}: {1}'.format(
salt.utils.url.redact_http_basic_auth(source),
exc.__str__())
log.exception(msg)
ret['comment'] = msg
return ret
if result['result']:
# Get the path of the file in the minion cache
cached = __salt__['cp.is_cached'](source, saltenv=__env__)
else:
log.debug(
'failed to download %s',
salt.utils.url.redact_http_basic_auth(source)
)
return result
# Finally, make the actual change and return the result.
new_state = __salt__['win_wusa.install'](cached)
ret['comment'] = 'The KB "{0}" was installed!'.format(name)
ret['changes'] = {
'old': current_state,
'new': new_state,
}
ret['result'] = True
return ret