Add option to use a remote source
The config template action plugin assumes that the local node is supplying a configuration file that will be used to copy content to a target node. This change gives the module the ability to change configuration files on target nodes using all remote sources. The new boolean option, `remote_src` has been added to enable or disable this functionality. When enabled, the module will retrieve content from the target node and load it as "user_content". By pre-loading it in the user content the module will function normally without any major structural changes or performance impact. Change-Id: Id9c7e16fb935c2da0b32b7cf53449f68bd1e9c89 Signed-off-by: Kevin Carter <kecarter@redhat.com>
This commit is contained in:
parent
28a6032612
commit
73aa099f0a
@ -38,6 +38,7 @@ import tempfile as tmpfilelib
|
||||
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
from ansible import constants as C
|
||||
from ansible import errors
|
||||
from ansible.parsing.yaml.dumper import AnsibleDumper
|
||||
@ -611,17 +612,30 @@ class ActionModule(ActionBase):
|
||||
file_path = self._loader.get_basedir()
|
||||
|
||||
user_source = self._task.args.get('src')
|
||||
# (alextricity25) It's possible that the user could pass in a datatype
|
||||
# and not always a string. In this case we don't want the datatype
|
||||
# python representation to be printed out to the file, but rather we
|
||||
# want the serialized version.
|
||||
_user_content = self._task.args.get('content')
|
||||
remote_src = boolean(
|
||||
self._task.args.get('remote_src', False),
|
||||
strict=False
|
||||
)
|
||||
if remote_src:
|
||||
slurpee = self._execute_module(
|
||||
module_name='slurp',
|
||||
module_args=dict(src=user_source),
|
||||
task_vars=task_vars
|
||||
)
|
||||
_content = base64.b64decode(slurpee['content'])
|
||||
_user_content = _content.decode('utf-8')
|
||||
else:
|
||||
# (alextricity25) It's possible that the user could pass in a
|
||||
# datatype and not always a string. In this case we don't want
|
||||
# the datatype python representation to be printed out to the
|
||||
# file, but rather we want the serialized version.
|
||||
_user_content = self._task.args.get('content')
|
||||
|
||||
# If the data type of the content input is a dictionary, it's
|
||||
# converted dumped as json if config_type is 'json'.
|
||||
if isinstance(_user_content, dict):
|
||||
if self._task.args.get('config_type') == 'json':
|
||||
_user_content = json.dumps(_user_content)
|
||||
# If the data type of the content input is a dictionary, it's
|
||||
# converted dumped as json if config_type is 'json'.
|
||||
if isinstance(_user_content, dict):
|
||||
if self._task.args.get('config_type') == 'json':
|
||||
_user_content = json.dumps(_user_content)
|
||||
|
||||
user_content = str(_user_content)
|
||||
if not user_source:
|
||||
@ -671,6 +685,7 @@ class ActionModule(ActionBase):
|
||||
ignore_none_type = self._task.args.get('ignore_none_type', True)
|
||||
|
||||
default_section = self._task.args.get('default_section', 'DEFAULT')
|
||||
remote_src = self._task.args.get('remote_src', False)
|
||||
|
||||
yml_multilines = self._task.args.get('yml_multilines', False)
|
||||
|
||||
@ -683,7 +698,8 @@ class ActionModule(ActionBase):
|
||||
list_extend=list_extend,
|
||||
ignore_none_type=ignore_none_type,
|
||||
default_section=default_section,
|
||||
yml_multilines=yml_multilines
|
||||
yml_multilines=yml_multilines,
|
||||
remote_src=remote_src
|
||||
)
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
@ -838,6 +854,10 @@ class ActionModule(ActionBase):
|
||||
new_module_args.pop('ignore_none_type', None)
|
||||
new_module_args.pop('default_section', None)
|
||||
new_module_args.pop('yml_multilines', None)
|
||||
|
||||
# While this is in the copy module we dont want to use it.
|
||||
new_module_args.pop('remote_src', None)
|
||||
|
||||
# Content from config_template is converted to src
|
||||
new_module_args.pop('content', None)
|
||||
|
||||
|
@ -64,6 +64,17 @@ options:
|
||||
section that will appear at the top of the configuration file. For
|
||||
example 'global'.
|
||||
default: 'DEFAULT'
|
||||
remote_src:
|
||||
description:
|
||||
- Influence whether the template needs to be transferred or already is
|
||||
present remotely.
|
||||
- If false, it will search the originating machine.
|
||||
- If true, it will go to the remote/target machine to inject the
|
||||
template. If the remote source does not exist the module will fail.
|
||||
choices:
|
||||
- True
|
||||
- False
|
||||
default: false
|
||||
|
||||
author: Kevin Carter
|
||||
"""
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- The ability to set `remote_src` has been added to the `config_template`
|
||||
action plugin. This option will instruct the `config_template` action
|
||||
plugin to use an already remote file as its source content.
|
10
tests/files/test_remote_src_multistropts.ini.expected
Normal file
10
tests/files/test_remote_src_multistropts.ini.expected
Normal file
@ -0,0 +1,10 @@
|
||||
[multistropts]
|
||||
test = test1
|
||||
test = test2
|
||||
test = test3
|
||||
|
||||
[remote_src_section]
|
||||
test = output
|
||||
|
||||
[testsection]
|
||||
test = output
|
@ -188,6 +188,44 @@
|
||||
that:
|
||||
- _multistropts_file == _multistropts_expected_file
|
||||
|
||||
# Test remote_src
|
||||
- name: Template remote source using overrides
|
||||
config_template:
|
||||
src: /tmp/test_multistropts.ini
|
||||
dest: /tmp/test_remote_src_multistropts.ini
|
||||
remote_src: true
|
||||
config_overrides:
|
||||
remote_src_section:
|
||||
test: output
|
||||
config_type: ini
|
||||
- name: Create expected MultiStrOpts file
|
||||
copy:
|
||||
src: files/test_remote_src_multistropts.ini.expected
|
||||
dest: /tmp/test_remote_src_multistropts.ini.expected
|
||||
|
||||
- name: Read test_remote_src_multistropts.ini
|
||||
slurp:
|
||||
src: /tmp/test_remote_src_multistropts.ini
|
||||
register: multistropts_file
|
||||
- name: Read test_remote_src_multistropts.ini.expected
|
||||
slurp:
|
||||
src: /tmp/test_remote_src_multistropts.ini.expected
|
||||
register: multistropts_expected_file
|
||||
- name: Set content facts
|
||||
set_fact:
|
||||
_remote_src_file: "{{ (multistropts_file.content | b64decode).strip() }}"
|
||||
_remote_src_expected_file: "{{ (multistropts_expected_file.content | b64decode).strip() }}"
|
||||
- name: Show rendered file
|
||||
debug:
|
||||
msg: "multistropts rendered - {{ _remote_src_file }}"
|
||||
- name: Show expected file
|
||||
debug:
|
||||
msg: "multistropts expected - {{ _remote_src_expected_file }}"
|
||||
- name: Compare files
|
||||
assert:
|
||||
that:
|
||||
- _remote_src_file == _remote_src_expected_file
|
||||
|
||||
# Test content attribute with a dictionary input and config_type equal to 'json'
|
||||
- name: Template test JSON template with content attribute
|
||||
config_template:
|
||||
|
Loading…
Reference in New Issue
Block a user