Improve error catching from malformed playbook data

Fixes #12478
pull/12490/head
James Cammarata 9 years ago
parent e8e1d9f6fb
commit c9a004227e

@ -159,6 +159,9 @@ class Base:
assert ds is not None assert ds is not None
# cache the datastructure internally
setattr(self, '_ds', ds)
# the variable manager class is used to manage and merge variables # the variable manager class is used to manage and merge variables
# down to a single dictionary for reference in templating, etc. # down to a single dictionary for reference in templating, etc.
self._variable_manager = variable_manager self._variable_manager = variable_manager
@ -192,9 +195,6 @@ class Base:
# run early, non-critical validation # run early, non-critical validation
self.validate() self.validate()
# cache the datastructure internally
setattr(self, '_ds', ds)
# return the constructed object # return the constructed object
return self return self

@ -19,6 +19,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
from ansible.errors import AnsibleParserError
from ansible.playbook.attribute import Attribute, FieldAttribute from ansible.playbook.attribute import Attribute, FieldAttribute
from ansible.playbook.base import Base from ansible.playbook.base import Base
from ansible.playbook.become import Become from ansible.playbook.become import Become
@ -96,6 +97,7 @@ class Block(Base, Become, Conditional, Taggable):
return super(Block, self).preprocess_data(ds) return super(Block, self).preprocess_data(ds)
def _load_block(self, attr, ds): def _load_block(self, attr, ds):
try:
return load_list_of_tasks( return load_list_of_tasks(
ds, ds,
play=self._play, play=self._play,
@ -106,8 +108,11 @@ class Block(Base, Become, Conditional, Taggable):
loader=self._loader, loader=self._loader,
use_handlers=self._use_handlers, use_handlers=self._use_handlers,
) )
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def _load_rescue(self, attr, ds): def _load_rescue(self, attr, ds):
try:
return load_list_of_tasks( return load_list_of_tasks(
ds, ds,
play=self._play, play=self._play,
@ -118,8 +123,11 @@ class Block(Base, Become, Conditional, Taggable):
loader=self._loader, loader=self._loader,
use_handlers=self._use_handlers, use_handlers=self._use_handlers,
) )
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def _load_always(self, attr, ds): def _load_always(self, attr, ds):
try:
return load_list_of_tasks( return load_list_of_tasks(
ds, ds,
play=self._play, play=self._play,
@ -130,19 +138,8 @@ class Block(Base, Become, Conditional, Taggable):
loader=self._loader, loader=self._loader,
use_handlers=self._use_handlers, use_handlers=self._use_handlers,
) )
except AssertionError:
# not currently used raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
#def _load_otherwise(self, attr, ds):
# return load_list_of_tasks(
# ds,
# play=self._play,
# block=self,
# role=self._role,
# task_include=self._task_include,
# variable_manager=self._variable_manager,
# loader=self._loader,
# use_handlers=self._use_handlers,
# )
def copy(self, exclude_parent=False, exclude_tasks=False): def copy(self, exclude_parent=False, exclude_tasks=False):
def _dupe_task_list(task_list, new_block): def _dupe_task_list(task_list, new_block):

@ -34,8 +34,7 @@ def load_list_of_blocks(ds, play, parent_block=None, role=None, task_include=Non
# we import here to prevent a circular dependency with imports # we import here to prevent a circular dependency with imports
from ansible.playbook.block import Block from ansible.playbook.block import Block
if not isinstance(ds, (list, type(None))): assert isinstance(ds, (list, type(None)))
raise AnsibleParserError('block has bad type: "%s". Expecting "list"' % type(ds).__name__, obj=ds)
block_list = [] block_list = []
if ds: if ds:
@ -74,13 +73,11 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
from ansible.playbook.handler import Handler from ansible.playbook.handler import Handler
from ansible.playbook.task import Task from ansible.playbook.task import Task
if not isinstance(ds, list): assert isinstance(ds, list)
raise AnsibleParserError('task has bad type: "%s". Expected "list"' % type(ds).__name__, obj=ds)
task_list = [] task_list = []
for task in ds: for task in ds:
if not isinstance(task, dict): assert isinstance(task, dict)
raise AnsibleParserError('task/handler has bad type: "%s". Expected "dict"' % type(task).__name__, obj=task)
if 'block' in task: if 'block' in task:
t = Block.load( t = Block.load(
@ -113,8 +110,7 @@ def load_list_of_roles(ds, play, current_role_path=None, variable_manager=None,
# we import here to prevent a circular dependency with imports # we import here to prevent a circular dependency with imports
from ansible.playbook.role.include import RoleInclude from ansible.playbook.role.include import RoleInclude
if not isinstance(ds, list): assert isinstance(ds, list)
raise AnsibleParserError('roles has bad type: "%s". Expectes "list"' % type(ds).__name__, obj=ds)
roles = [] roles = []
for role_def in ds: for role_def in ds:

@ -157,28 +157,40 @@ class Play(Base, Taggable, Become):
Loads a list of blocks from a list which may be mixed tasks/blocks. Loads a list of blocks from a list which may be mixed tasks/blocks.
Bare tasks outside of a block are given an implicit block. Bare tasks outside of a block are given an implicit block.
''' '''
try:
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader) return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def _load_pre_tasks(self, attr, ds): def _load_pre_tasks(self, attr, ds):
''' '''
Loads a list of blocks from a list which may be mixed tasks/blocks. Loads a list of blocks from a list which may be mixed tasks/blocks.
Bare tasks outside of a block are given an implicit block. Bare tasks outside of a block are given an implicit block.
''' '''
try:
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader) return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def _load_post_tasks(self, attr, ds): def _load_post_tasks(self, attr, ds):
''' '''
Loads a list of blocks from a list which may be mixed tasks/blocks. Loads a list of blocks from a list which may be mixed tasks/blocks.
Bare tasks outside of a block are given an implicit block. Bare tasks outside of a block are given an implicit block.
''' '''
try:
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader) return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def _load_handlers(self, attr, ds): def _load_handlers(self, attr, ds):
''' '''
Loads a list of blocks from a list which may be mixed handlers/blocks. Loads a list of blocks from a list which may be mixed handlers/blocks.
Bare handlers outside of a block are given an implicit block. Bare handlers outside of a block are given an implicit block.
''' '''
try:
return load_list_of_blocks(ds=ds, play=self, use_handlers=True, variable_manager=self._variable_manager, loader=self._loader) return load_list_of_blocks(ds=ds, play=self, use_handlers=True, variable_manager=self._variable_manager, loader=self._loader)
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def _load_roles(self, attr, ds): def _load_roles(self, attr, ds):
''' '''
@ -189,7 +201,10 @@ class Play(Base, Taggable, Become):
if ds is None: if ds is None:
ds = [] ds = []
try:
role_includes = load_list_of_roles(ds, play=self, variable_manager=self._variable_manager, loader=self._loader) role_includes = load_list_of_roles(ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
except AssertionError:
raise AnsibleParserError("A malformed role declaration was encountered.", obj=self._ds)
roles = [] roles = []
for ri in role_includes: for ri in role_includes:

@ -72,7 +72,10 @@ class RoleMetadata(Base):
if self._owner: if self._owner:
current_role_path = os.path.dirname(self._owner._role_path) current_role_path = os.path.dirname(self._owner._role_path)
try:
return load_list_of_roles(ds, play=self._owner._play, current_role_path=current_role_path, variable_manager=self._variable_manager, loader=self._loader) return load_list_of_roles(ds, play=self._owner._play, current_role_path=current_role_path, variable_manager=self._variable_manager, loader=self._loader)
except AssertionError:
raise AnsibleParserError("A malformed list of role dependencies was encountered.", obj=self._ds)
def _load_galaxy_info(self, attr, ds): def _load_galaxy_info(self, attr, ds):
''' '''

Loading…
Cancel
Save