Compare commits
12 Commits
v2.12.5rc1
...
v2.12.6
| Author | SHA1 | Date | |
|---|---|---|---|
| a1683d3dab | |||
| 04ab182ef9 | |||
| 01cbef9476 | |||
| 48689b63e4 | |||
| 092d298b5c | |||
| a9f17d0532 | |||
| 4bde2d8a97 | |||
| 625a99aa32 | |||
| 013be12888 | |||
| b667639c2c | |||
| b104478f17 | |||
| 3ea4cdaddf |
@ -5,13 +5,31 @@ ansible-core 2.12 "Dazed and Confused" Release Notes
|
||||
.. contents:: Topics
|
||||
|
||||
|
||||
v2.12.5rc1
|
||||
==========
|
||||
v2.12.6
|
||||
=======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
| Release Date: 2022-04-18
|
||||
| Release Date: 2022-05-23
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Prevent losing unsafe on results returned from lookups (https://github.com/ansible/ansible/issues/77535)
|
||||
- arg_spec - Fix incorrect ``no_log`` warning when a parameter alias is used (https://github.com/ansible/ansible/pull/77576)
|
||||
- plugin loader will now load config data for plugin by name instead of by file to avoid issues with the same file being loaded under different names (fqcn + short name).
|
||||
- variablemanager, more efficient read of vars files
|
||||
|
||||
v2.12.5
|
||||
=======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
| Release Date: 2022-04-25
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
|
||||
|
||||
@ -1392,6 +1392,17 @@ releases:
|
||||
- nativejinjaunsafetext-yaml-representer.yml
|
||||
- v2.12.4rc1_summary.yaml
|
||||
release_date: '2022-03-21'
|
||||
2.12.5:
|
||||
changes:
|
||||
release_summary: '| Release Date: 2022-04-25
|
||||
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
'
|
||||
codename: Dazed and Confused
|
||||
fragments:
|
||||
- v2.12.5_summary.yaml
|
||||
release_date: '2022-04-25'
|
||||
2.12.5rc1:
|
||||
changes:
|
||||
bugfixes:
|
||||
@ -1431,3 +1442,37 @@ releases:
|
||||
- v2.12.5rc1_summary.yaml
|
||||
- winrm-kinit-path.yml
|
||||
release_date: '2022-04-18'
|
||||
2.12.6:
|
||||
changes:
|
||||
release_summary: '| Release Date: 2022-05-23
|
||||
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
'
|
||||
codename: Dazed and Confused
|
||||
fragments:
|
||||
- v2.12.6_summary.yaml
|
||||
release_date: '2022-05-23'
|
||||
2.12.6rc1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Prevent losing unsafe on results returned from lookups (https://github.com/ansible/ansible/issues/77535)
|
||||
- arg_spec - Fix incorrect ``no_log`` warning when a parameter alias is used
|
||||
(https://github.com/ansible/ansible/pull/77576)
|
||||
- plugin loader will now load config data for plugin by name instead of by file
|
||||
to avoid issues with the same file being loaded under different names (fqcn
|
||||
+ short name).
|
||||
- variablemanager, more efficient read of vars files
|
||||
release_summary: '| Release Date: 2022-05-16
|
||||
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
'
|
||||
codename: Dazed and Confused
|
||||
fragments:
|
||||
- 77535-prevent-losing-unsafe-lookups.yml
|
||||
- 77576-arg_spec-no_log-aliases.yml
|
||||
- config_load_by_name.yml
|
||||
- v2.12.6rc1_summary.yaml
|
||||
- vm_more_efficient.yml
|
||||
release_date: '2022-05-16'
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Prevent losing unsafe on results returned from lookups (https://github.com/ansible/ansible/issues/77535)
|
||||
2
changelogs/fragments/77576-arg_spec-no_log-aliases.yml
Normal file
2
changelogs/fragments/77576-arg_spec-no_log-aliases.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- arg_spec - Fix incorrect ``no_log`` warning when a parameter alias is used (https://github.com/ansible/ansible/pull/77576)
|
||||
2
changelogs/fragments/config_load_by_name.yml
Normal file
2
changelogs/fragments/config_load_by_name.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- plugin loader will now load config data for plugin by name instead of by file to avoid issues with the same file being loaded under different names (fqcn + short name).
|
||||
3
changelogs/fragments/v2.12.5_summary.yaml
Normal file
3
changelogs/fragments/v2.12.5_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2022-04-25
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
3
changelogs/fragments/v2.12.6_summary.yaml
Normal file
3
changelogs/fragments/v2.12.6_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2022-05-23
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
3
changelogs/fragments/v2.12.6rc1_summary.yaml
Normal file
3
changelogs/fragments/v2.12.6rc1_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2022-05-16
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
2
changelogs/fragments/vm_more_efficient.yml
Normal file
2
changelogs/fragments/vm_more_efficient.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- variablemanager, more efficient read of vars files
|
||||
@ -173,9 +173,9 @@ html_context = {
|
||||
'github_root_dir': 'devel/lib/ansible',
|
||||
'github_cli_version': 'devel/lib/ansible/cli/',
|
||||
'current_version': version,
|
||||
'latest_version': '2.12',
|
||||
'latest_version': '2.13',
|
||||
# list specifically out of order to make latest work
|
||||
'available_versions': ('2.12', '2.11', '2.10', 'devel',),
|
||||
'available_versions': ('2.13', '2.12', '2.11', 'devel',),
|
||||
}
|
||||
|
||||
# Add extra CSS styles to the resulting HTML pages
|
||||
|
||||
@ -508,6 +508,7 @@ class AnsibleModule(object):
|
||||
self.validation_result = self.validator.validate(self.params)
|
||||
self.params.update(self.validation_result.validated_parameters)
|
||||
self.no_log_values.update(self.validation_result._no_log_values)
|
||||
self.aliases.update(self.validation_result._aliases)
|
||||
|
||||
try:
|
||||
error = self.validation_result.errors[0]
|
||||
|
||||
@ -61,6 +61,7 @@ class ValidationResult:
|
||||
self._validated_parameters = deepcopy(parameters)
|
||||
self._deprecations = []
|
||||
self._warnings = []
|
||||
self._aliases = {}
|
||||
self.errors = AnsibleValidationErrorMultiple()
|
||||
"""
|
||||
:class:`~ansible.module_utils.errors.AnsibleValidationErrorMultiple` containing all
|
||||
@ -180,12 +181,11 @@ class ArgumentSpecValidator:
|
||||
alias_warnings = []
|
||||
alias_deprecations = []
|
||||
try:
|
||||
aliases = _handle_aliases(self.argument_spec, result._validated_parameters, alias_warnings, alias_deprecations)
|
||||
result._aliases.update(_handle_aliases(self.argument_spec, result._validated_parameters, alias_warnings, alias_deprecations))
|
||||
except (TypeError, ValueError) as e:
|
||||
aliases = {}
|
||||
result.errors.append(AliasError(to_native(e)))
|
||||
|
||||
legal_inputs = _get_legal_inputs(self.argument_spec, result._validated_parameters, aliases)
|
||||
legal_inputs = _get_legal_inputs(self.argument_spec, result._validated_parameters, result._aliases)
|
||||
|
||||
for option, alias in alias_warnings:
|
||||
result._warnings.append({'option': option, 'alias': alias})
|
||||
|
||||
@ -395,7 +395,7 @@ class PluginLoader:
|
||||
type_name = get_plugin_class(self.class_name)
|
||||
|
||||
# if type name != 'module_doc_fragment':
|
||||
if type_name in C.CONFIGURABLE_PLUGINS:
|
||||
if type_name in C.CONFIGURABLE_PLUGINS and not C.config.get_configuration_definition(type_name, name):
|
||||
dstring = AnsibleLoader(getattr(module, 'DOCUMENTATION', ''), file_name=path).get_single_data()
|
||||
if dstring:
|
||||
add_fragments(dstring, path, fragment_loader=fragment_loader, is_module=(type_name == 'module'))
|
||||
@ -825,10 +825,12 @@ class PluginLoader:
|
||||
|
||||
if path not in self._module_cache:
|
||||
self._module_cache[path] = self._load_module_source(name, path)
|
||||
self._load_config_defs(name, self._module_cache[path], path)
|
||||
found_in_cache = False
|
||||
|
||||
self._load_config_defs(name, self._module_cache[path], path)
|
||||
|
||||
obj = getattr(self._module_cache[path], self.class_name)
|
||||
|
||||
if self.base_class:
|
||||
# The import path is hardcoded and should be the right place,
|
||||
# so we are not expecting an ImportError.
|
||||
@ -955,15 +957,18 @@ class PluginLoader:
|
||||
else:
|
||||
full_name = basename
|
||||
module = self._load_module_source(full_name, path)
|
||||
self._load_config_defs(basename, module, path)
|
||||
except Exception as e:
|
||||
display.warning("Skipping plugin (%s) as it seems to be invalid: %s" % (path, to_text(e)))
|
||||
continue
|
||||
self._module_cache[path] = module
|
||||
found_in_cache = False
|
||||
else:
|
||||
module = self._module_cache[path]
|
||||
|
||||
self._load_config_defs(basename, module, path)
|
||||
|
||||
try:
|
||||
obj = getattr(self._module_cache[path], self.class_name)
|
||||
obj = getattr(module, self.class_name)
|
||||
except AttributeError as e:
|
||||
display.warning("Skipping plugin (%s) as it seems to be invalid: %s" % (path, to_text(e)))
|
||||
continue
|
||||
|
||||
@ -19,6 +19,6 @@
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
__version__ = '2.12.5rc1'
|
||||
__version__ = '2.12.6'
|
||||
__author__ = 'Ansible, Inc.'
|
||||
__codename__ = 'Dazed and Confused'
|
||||
|
||||
@ -1146,15 +1146,19 @@ class Templar:
|
||||
|
||||
jvars = AnsibleJ2Vars(self, t.globals)
|
||||
|
||||
self.cur_context = new_context = t.new_context(jvars, shared=True)
|
||||
rf = t.root_render_func(new_context)
|
||||
# In case this is a recursive call to do_template we need to
|
||||
# save/restore cur_context to prevent overriding __UNSAFE__.
|
||||
cached_context = self.cur_context
|
||||
|
||||
self.cur_context = t.new_context(jvars, shared=True)
|
||||
rf = t.root_render_func(self.cur_context)
|
||||
|
||||
try:
|
||||
if self.jinja2_native:
|
||||
res = ansible_native_concat(rf)
|
||||
else:
|
||||
res = j2_concat(rf)
|
||||
unsafe = getattr(new_context, 'unsafe', False)
|
||||
unsafe = getattr(self.cur_context, 'unsafe', False)
|
||||
if unsafe:
|
||||
res = wrap_var(res)
|
||||
except TypeError as te:
|
||||
@ -1165,6 +1169,8 @@ class Templar:
|
||||
else:
|
||||
display.debug("failing because of a type error, template data is: %s" % to_text(data))
|
||||
raise AnsibleError("Unexpected templating type error occurred on (%s): %s" % (to_native(data), to_native(te)))
|
||||
finally:
|
||||
self.cur_context = cached_context
|
||||
|
||||
if self.jinja2_native and not isinstance(res, string_types):
|
||||
return res
|
||||
|
||||
@ -357,8 +357,7 @@ class VariableManager:
|
||||
try:
|
||||
play_search_stack = play.get_search_path()
|
||||
found_file = real_file = self._loader.path_dwim_relative_stack(play_search_stack, 'vars', vars_file)
|
||||
decrypted_file = self._loader.get_real_file(found_file)
|
||||
data = preprocess_vars(self._loader.load_from_file(decrypted_file, unsafe=True))
|
||||
data = preprocess_vars(self._loader.load_from_file(found_file, unsafe=True, cache=False))
|
||||
if data is not None:
|
||||
for item in data:
|
||||
all_vars = _combine_and_track(all_vars, item, "play vars_files from '%s'" % vars_file)
|
||||
|
||||
@ -1,5 +1 @@
|
||||
shippable/posix/group1
|
||||
skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
skip/docker
|
||||
|
||||
@ -18,11 +18,12 @@
|
||||
|
||||
- name: check selinux policy type
|
||||
shell: grep '^SELINUXTYPE=' /etc/selinux/config | cut -d'=' -f2
|
||||
ignore_errors: yes
|
||||
register: r
|
||||
|
||||
- set_fact:
|
||||
selinux_policytype: "{{ r.stdout_lines[0] }}"
|
||||
when: r.changed
|
||||
when: r is success and r.stdout_lines
|
||||
|
||||
- assert:
|
||||
that:
|
||||
|
||||
@ -22,3 +22,6 @@ do
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# test config loading
|
||||
ansible-playbook use_coll_name.yml -i ../../inventory -e 'ansible_connection=ansible.builtin.ssh' "$@"
|
||||
|
||||
7
test/integration/targets/plugin_loader/use_coll_name.yml
Normal file
7
test/integration/targets/plugin_loader/use_coll_name.yml
Normal file
@ -0,0 +1,7 @@
|
||||
- name: ensure configuration is loaded when we use FQCN and have already loaded using 'short namne' (which is case will all builtin connection plugins)
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: relies on extra var being passed in with connection and fqcn
|
||||
ping:
|
||||
ignore_unreachable: True
|
||||
@ -17,3 +17,48 @@
|
||||
that:
|
||||
- this_always_safe == imunsafe
|
||||
- imunsafe == this_was_unsafe.strip()
|
||||
|
||||
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}"
|
||||
tasks:
|
||||
- set_fact:
|
||||
unsafe_foo: "{{ lookup('list', var0) }}"
|
||||
vars:
|
||||
var0: "{{ var1 }}"
|
||||
var1:
|
||||
- unsafe
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "{{ unsafe_foo[0] | type_debug == 'AnsibleUnsafeText' }}"
|
||||
|
||||
- block:
|
||||
- copy:
|
||||
dest: "{{ file_name }}"
|
||||
content: !unsafe "{{ i_should_not_be_templated }}"
|
||||
|
||||
- set_fact:
|
||||
file_content: "{{ lookup('file', file_name) }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- not file_content is contains('unsafe')
|
||||
|
||||
- set_fact:
|
||||
file_content: "{{ lookup('file', file_name_tmpl) }}"
|
||||
vars:
|
||||
file_name_tmpl: "{{ file_name }}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- not file_content is contains('unsafe')
|
||||
vars:
|
||||
file_name: "{{ output_dir }}/unsafe_file"
|
||||
i_should_not_be_templated: unsafe
|
||||
always:
|
||||
- file:
|
||||
dest: "{{ file_name }}"
|
||||
state: absent
|
||||
|
||||
@ -709,3 +709,16 @@ def test_no_log_none(stdin, capfd):
|
||||
# makes it into am.no_log_values. Instead we can check for the warning
|
||||
# emitted by am._log_invocation.
|
||||
assert len(get_warning_messages()) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("stdin", [{"pass": "testing"}], indirect=["stdin"])
|
||||
def test_no_log_alias(stdin, capfd):
|
||||
"""Given module parameters that use an alias for a parameter that matches
|
||||
PASSWORD_MATCH and has no_log=True set, a warning should not be issued.
|
||||
"""
|
||||
arg_spec = {
|
||||
"other_pass": {"no_log": True, "aliases": ["pass"]},
|
||||
}
|
||||
am = basic.AnsibleModule(arg_spec)
|
||||
|
||||
assert len(get_warning_messages()) == 0
|
||||
|
||||
@ -95,6 +95,11 @@ def test_aliases(arg_spec, parameters, expected, deprecation, warning):
|
||||
assert isinstance(result, ValidationResult)
|
||||
assert result.validated_parameters == expected
|
||||
assert result.error_messages == []
|
||||
assert result._aliases == dict(
|
||||
(alias, param)
|
||||
for param, value in arg_spec.items()
|
||||
for alias in value.get("aliases", [])
|
||||
)
|
||||
|
||||
if deprecation:
|
||||
assert deprecation == result._deprecations[0]
|
||||
|
||||
@ -444,3 +444,28 @@ class TestAnsibleContext(BaseTemplar, unittest.TestCase):
|
||||
def test_is_unsafe(self):
|
||||
context = self._context()
|
||||
self.assertFalse(context._is_unsafe(AnsibleUndefined()))
|
||||
|
||||
|
||||
def test_unsafe_lookup():
|
||||
res = Templar(
|
||||
None,
|
||||
variables={
|
||||
'var0': '{{ var1 }}',
|
||||
'var1': ['unsafe'],
|
||||
}
|
||||
).template('{{ lookup("list", var0) }}')
|
||||
assert getattr(res[0], '__UNSAFE__', False)
|
||||
|
||||
|
||||
def test_unsafe_lookup_no_conversion():
|
||||
res = Templar(
|
||||
None,
|
||||
variables={
|
||||
'var0': '{{ var1 }}',
|
||||
'var1': ['unsafe'],
|
||||
}
|
||||
).template(
|
||||
'{{ lookup("list", var0) }}',
|
||||
convert_data=False,
|
||||
)
|
||||
assert getattr(res, '__UNSAFE__', False)
|
||||
|
||||
Reference in New Issue
Block a user