Merge pull request #14311 from sivel/unsafe-yaml-constructor

Add new 'unsafe' YAML constructor
This commit is contained in:
Matt Martz 2016-02-23 11:29:53 -06:00
commit 38b663471d
4 changed files with 77 additions and 1 deletions

View file

@ -0,0 +1,59 @@
Advanced Syntax
===============
.. contents:: Topics
This page describes advanced YAML syntax that enables you to have more control over the data placed in YAML files used by Ansible.
.. _yaml_tags_and_python_types
YAML tags and Python types
``````````````````````````
The documentation covered here is an extension of the documentation that can be found in the `PyYAML Documentation <http://pyyaml.org/wiki/PyYAMLDocumentation#YAMLtagsandPythontypes>`_
.. _unsafe_strings
Unsafe or Raw Strings
~~~~~~~~~~~~~~~~~~~~~
As of Ansible 2.0, there is an internal data type for declaring variable values as "unsafe". This means that the data held within the variables value should be treated as unsafe preventing unsafe character subsitition and information disclosure.
Jinja2 contains functionality for escaping, or telling Jinja2 to not template data by means of functionality such as ``{% raw %} ... {% endraw %}``, however this uses a more comprehensive implementation to ensure that the value is never templated.
Using YAML tags, you can also mark a value as "unsafe" by using the ``!unsafe`` tag such as::
---
my_unsafe_variable: !unsafe 'this variable has {{ characters that shouldn't be treated as a jinja2 template'
In a playbook, this may look like::
---
hosts: all
vars:
my_unsafe_variable: !unsafe 'unsafe value'
tasks:
...
For complex variables such as hashes or arrays, ``!unsafe`` should be used on the individual elements such as::
---
my_unsafe_array:
- !unsafe 'unsafe element'
- 'safe element'
my_unsafe_hash:
unsafe_key: !unsafe 'unsafe value'
.. seealso::
:doc:`playbooks_variables`
All about variables
`User Mailing List <http://groups.google.com/group/ansible-project>`_
Have a question? Stop by the google group!
`irc.freenode.net <http://irc.freenode.net>`_
#ansible IRC chat channel

View file

@ -14,6 +14,7 @@ and adopt these only if they seem relevant or useful to your environment.
playbooks_delegation
playbooks_environment
playbooks_error_handling
playbooks_advanced_syntax
playbooks_lookups
playbooks_prompts
playbooks_tags

View file

@ -933,6 +933,11 @@ how all of these things can work together.
.. _ansible-examples: https://github.com/ansible/ansible-examples
.. _builtin filters: http://jinja.pocoo.org/docs/templates/#builtin-filters
Advanced Syntax
```````````````
For information about advanced YAML syntax used to declare variables and have more control over the data placed in YAML files used by Ansible, see `playbooks_advanced_syntax`_
.. seealso::
:doc:`playbooks`

View file

@ -22,6 +22,7 @@ __metaclass__ = type
from yaml.constructor import Constructor, ConstructorError
from yaml.nodes import MappingNode
from ansible.parsing.yaml.objects import AnsibleMapping, AnsibleSequence, AnsibleUnicode
from ansible.vars.unsafe_proxy import wrap_var
try:
from __main__ import display
@ -72,7 +73,7 @@ class AnsibleConstructor(Constructor):
return mapping
def construct_yaml_str(self, node):
def construct_yaml_str(self, node, unsafe=False):
# Override the default string handling function
# to always return unicode objects
value = self.construct_scalar(node)
@ -80,6 +81,9 @@ class AnsibleConstructor(Constructor):
ret.ansible_pos = self._node_position_info(node)
if unsafe:
ret = wrap_var(ret)
return ret
def construct_yaml_seq(self, node):
@ -88,6 +92,9 @@ class AnsibleConstructor(Constructor):
data.extend(self.construct_sequence(node))
data.ansible_pos = self._node_position_info(node)
def construct_yaml_unsafe(self, node):
return self.construct_yaml_str(node, unsafe=True)
def _node_position_info(self, node):
# the line number where the previous token has ended (plus empty lines)
# Add one so that the first line is line 1 rather than line 0
@ -121,3 +128,7 @@ AnsibleConstructor.add_constructor(
AnsibleConstructor.add_constructor(
u'tag:yaml.org,2002:seq',
AnsibleConstructor.construct_yaml_seq)
AnsibleConstructor.add_constructor(
u'!unsafe',
AnsibleConstructor.construct_yaml_unsafe)