win_script: add support for become and centralise exec wrapper builder (#45582)

* win_script: add support for become and centralise exec wrapper builder

* satisfying the pep8 gods

* do not scan for module dependencies when running as a script
This commit is contained in:
Jordan Borean 2018-09-13 08:50:13 +10:00 committed by GitHub
parent 03dbb1d9c4
commit d81249994e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 101 additions and 73 deletions

View file

@ -688,6 +688,69 @@ def _is_binary(b_module_data):
return bool(start.translate(None, textchars))
def _create_powershell_wrapper(b_module_data, module_args, environment,
async_timeout, become, become_method,
become_user, become_password, become_flags,
scan_dependencies=True):
# creates the manifest/wrapper used in PowerShell modules to enable things
# like become and async - this is also called in action/script.py
exec_manifest = dict(
module_entry=to_text(base64.b64encode(b_module_data)),
powershell_modules=dict(),
module_args=module_args,
actions=['exec'],
environment=environment
)
exec_manifest['exec'] = to_text(base64.b64encode(to_bytes(leaf_exec)))
if async_timeout > 0:
exec_manifest["actions"].insert(0, 'async_watchdog')
exec_manifest["async_watchdog"] = to_text(
base64.b64encode(to_bytes(async_watchdog)))
exec_manifest["actions"].insert(0, 'async_wrapper')
exec_manifest["async_wrapper"] = to_text(
base64.b64encode(to_bytes(async_wrapper)))
exec_manifest["async_jid"] = str(random.randint(0, 999999999999))
exec_manifest["async_timeout_sec"] = async_timeout
if become and become_method == 'runas':
exec_manifest["actions"].insert(0, 'become')
exec_manifest["become_user"] = become_user
exec_manifest["become_password"] = become_password
exec_manifest['become_flags'] = become_flags
exec_manifest["become"] = to_text(
base64.b64encode(to_bytes(become_wrapper)))
finder = PSModuleDepFinder()
# we don't want to scan for any module_utils or other module related flags
# if scan_dependencies=False - action/script sets to False
if scan_dependencies:
finder.scan_module(b_module_data)
for name, data in finder.modules.items():
b64_data = to_text(base64.b64encode(data))
exec_manifest['powershell_modules'][name] = b64_data
exec_manifest['min_ps_version'] = finder.ps_version
exec_manifest['min_os_version'] = finder.os_version
if finder.become and 'become' not in exec_manifest['actions']:
exec_manifest['actions'].insert(0, 'become')
exec_manifest['become_user'] = 'SYSTEM'
exec_manifest['become_password'] = None
exec_manifest['become_flags'] = None
exec_manifest['become'] = to_text(
base64.b64encode(to_bytes(become_wrapper)))
# FUTURE: smuggle this back as a dict instead of serializing here;
# the connection plugin may need to modify it
b_json = to_bytes(json.dumps(exec_manifest))
b_data = exec_wrapper.replace(b"$json_raw = ''",
b"$json_raw = @'\r\n%s\r\n'@" % b_json)
return b_data
def _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, templar, module_compression, async_timeout, become,
become_method, become_user, become_password, become_flags, environment):
"""
@ -867,53 +930,14 @@ def _find_module_utils(module_name, b_module_data, module_path, module_args, tas
# it can fail in the presence of the UTF8 BOM commonly added by
# Windows text editors
shebang = u'#!powershell'
exec_manifest = dict(
module_entry=to_text(base64.b64encode(b_module_data)),
powershell_modules=dict(),
module_args=module_args,
actions=['exec'],
environment=environment
# create the common exec wrapper payload and set that as the module_data
# bytes
b_module_data = _create_powershell_wrapper(
b_module_data, module_args, environment, async_timeout, become,
become_method, become_user, become_password, become_flags,
scan_dependencies=True
)
exec_manifest['exec'] = to_text(base64.b64encode(to_bytes(leaf_exec)))
if async_timeout > 0:
exec_manifest["actions"].insert(0, 'async_watchdog')
exec_manifest["async_watchdog"] = to_text(base64.b64encode(to_bytes(async_watchdog)))
exec_manifest["actions"].insert(0, 'async_wrapper')
exec_manifest["async_wrapper"] = to_text(base64.b64encode(to_bytes(async_wrapper)))
exec_manifest["async_jid"] = str(random.randint(0, 999999999999))
exec_manifest["async_timeout_sec"] = async_timeout
if become and become_method == 'runas':
exec_manifest["actions"].insert(0, 'become')
exec_manifest["become_user"] = become_user
exec_manifest["become_password"] = become_password
exec_manifest['become_flags'] = become_flags
exec_manifest["become"] = to_text(base64.b64encode(to_bytes(become_wrapper)))
finder = PSModuleDepFinder()
finder.scan_module(b_module_data)
for name, data in finder.modules.items():
b64_data = to_text(base64.b64encode(data))
exec_manifest['powershell_modules'][name] = b64_data
exec_manifest['min_ps_version'] = finder.ps_version
exec_manifest['min_os_version'] = finder.os_version
if finder.become and 'become' not in exec_manifest['actions']:
exec_manifest['actions'].insert(0, 'become')
exec_manifest['become_user'] = 'SYSTEM'
exec_manifest['become_password'] = None
exec_manifest['become_flags'] = None
exec_manifest['become'] = to_text(base64.b64encode(to_bytes(become_wrapper)))
# FUTURE: smuggle this back as a dict instead of serializing here; the connection plugin may need to modify it
module_json = json.dumps(exec_manifest)
b_module_data = exec_wrapper.replace(b"$json_raw = ''", b"$json_raw = @'\r\n%s\r\n'@" % to_bytes(module_json))
elif module_substyle == 'jsonargs':
module_args_json = to_bytes(json.dumps(module_args))