mirror of
https://github.com/thegeeklab/ansible-later.git
synced 2024-11-23 21:30:40 +00:00
fix: fix handling of blocks (#767)
This commit is contained in:
parent
37e701217e
commit
a89d6d5336
@ -149,11 +149,12 @@ class RuleBase(metaclass=RuleExtendedMeta):
|
|||||||
# No need to normalize_task if we are skipping it.
|
# No need to normalize_task if we are skipping it.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
normalized.append(
|
normalized_task = normalize_task(
|
||||||
normalize_task(
|
|
||||||
task, candidate.path, settings["ansible"]["custom_modules"]
|
task, candidate.path, settings["ansible"]["custom_modules"]
|
||||||
)
|
)
|
||||||
)
|
normalized_task["__raw_task__"] = task
|
||||||
|
|
||||||
|
normalized.append(normalized_task)
|
||||||
|
|
||||||
except LaterError as ex:
|
except LaterError as ex:
|
||||||
e = ex.original
|
e = ex.original
|
||||||
|
@ -9,11 +9,7 @@ class CheckFQCNBuiltin(RuleBase):
|
|||||||
helptext = "use FQCN `{module_alias}` for module action `{module}`"
|
helptext = "use FQCN `{module_alias}` for module action `{module}`"
|
||||||
description = "Module actions should use full qualified collection names"
|
description = "Module actions should use full qualified collection names"
|
||||||
types = ["playbook", "task", "handler", "rolevars", "hostvars", "groupvars"]
|
types = ["playbook", "task", "handler", "rolevars", "hostvars", "groupvars"]
|
||||||
module_aliases = {
|
module_aliases = {"block/always/rescue": "block/always/rescue"}
|
||||||
"block": "block",
|
|
||||||
"always": "always",
|
|
||||||
"rescue": "rescue",
|
|
||||||
}
|
|
||||||
|
|
||||||
def check(self, candidate, settings):
|
def check(self, candidate, settings):
|
||||||
tasks, errors = self.get_normalized_tasks(candidate, settings)
|
tasks, errors = self.get_normalized_tasks(candidate, settings)
|
||||||
|
@ -21,7 +21,7 @@ SORTER_TASKS = (
|
|||||||
|
|
||||||
class CheckKeyOrder(RuleBase):
|
class CheckKeyOrder(RuleBase):
|
||||||
rid = "ANS129"
|
rid = "ANS129"
|
||||||
description = "Check optimized key order"
|
description = "Check for recommended key order"
|
||||||
helptext = "{type} key order can be improved to `{sorted_keys}`"
|
helptext = "{type} key order can be improved to `{sorted_keys}`"
|
||||||
types = ["playbook", "task", "handler"]
|
types = ["playbook", "task", "handler"]
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ class Settings:
|
|||||||
"exclude": [
|
"exclude": [
|
||||||
"meta",
|
"meta",
|
||||||
"debug",
|
"debug",
|
||||||
"block",
|
"block/always/rescue",
|
||||||
"include_role",
|
"include_role",
|
||||||
"import_role",
|
"import_role",
|
||||||
"include_tasks",
|
"include_tasks",
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import copy
|
|
||||||
import os
|
import os
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
|
|
||||||
@ -370,24 +369,22 @@ def _kv_to_dict(v):
|
|||||||
def normalize_task(task, filename, custom_modules=None):
|
def normalize_task(task, filename, custom_modules=None):
|
||||||
"""Ensure tasks have an action key and strings are converted to python objects."""
|
"""Ensure tasks have an action key and strings are converted to python objects."""
|
||||||
|
|
||||||
|
def _normalize(task, custom_modules):
|
||||||
if custom_modules is None:
|
if custom_modules is None:
|
||||||
custom_modules = []
|
custom_modules = []
|
||||||
|
|
||||||
ansible_action_type = task.get("__ansible_action_type__", "task")
|
|
||||||
if "__ansible_action_type__" in task:
|
|
||||||
del task["__ansible_action_type__"]
|
|
||||||
|
|
||||||
# temp. extract metadata
|
|
||||||
ansible_meta = {}
|
|
||||||
for key in ["__line__", "__file__", "__ansible_action_meta__"]:
|
|
||||||
default = None
|
|
||||||
|
|
||||||
if key == "__ansible_action_meta__":
|
|
||||||
default = {}
|
|
||||||
|
|
||||||
ansible_meta[key] = task.pop(key, default)
|
|
||||||
|
|
||||||
normalized = {}
|
normalized = {}
|
||||||
|
ansible_parsed_keys = ("action", "local_action", "args", "delegate_to")
|
||||||
|
|
||||||
|
if is_nested_task(task):
|
||||||
|
_extract_ansible_parsed_keys_from_task(normalized, task, ansible_parsed_keys)
|
||||||
|
# Add dummy action for block/always/rescue statements
|
||||||
|
normalized["action"] = {
|
||||||
|
"__ansible_module__": "block/always/rescue",
|
||||||
|
"__ansible_module_original__": "block/always/rescue",
|
||||||
|
"__ansible_arguments__": "block/always/rescue",
|
||||||
|
}
|
||||||
|
return normalized
|
||||||
|
|
||||||
builtin = list(ansible.parsing.mod_args.BUILTIN_TASKS)
|
builtin = list(ansible.parsing.mod_args.BUILTIN_TASKS)
|
||||||
builtin = list(set(builtin + custom_modules))
|
builtin = list(set(builtin + custom_modules))
|
||||||
@ -405,7 +402,7 @@ def normalize_task(task, filename, custom_modules=None):
|
|||||||
del arguments["_uses_shell"]
|
del arguments["_uses_shell"]
|
||||||
|
|
||||||
for k, v in list(task.items()):
|
for k, v in list(task.items()):
|
||||||
if k in ("action", "local_action", "args", "delegate_to") or k == action:
|
if k in ansible_parsed_keys or k == action:
|
||||||
# we don"t want to re-assign these values, which were
|
# we don"t want to re-assign these values, which were
|
||||||
# determined by the ModuleArgsParser() above
|
# determined by the ModuleArgsParser() above
|
||||||
continue
|
continue
|
||||||
@ -420,12 +417,32 @@ def normalize_task(task, filename, custom_modules=None):
|
|||||||
}
|
}
|
||||||
|
|
||||||
if "_raw_params" in arguments:
|
if "_raw_params" in arguments:
|
||||||
normalized["action"]["__ansible_arguments__"] = arguments["_raw_params"].strip().split()
|
normalized["action"]["__ansible_arguments__"] = (
|
||||||
|
arguments["_raw_params"].strip().split()
|
||||||
|
)
|
||||||
del arguments["_raw_params"]
|
del arguments["_raw_params"]
|
||||||
else:
|
else:
|
||||||
normalized["action"]["__ansible_arguments__"] = []
|
normalized["action"]["__ansible_arguments__"] = []
|
||||||
normalized["action"].update(arguments)
|
normalized["action"].update(arguments)
|
||||||
|
|
||||||
|
return normalized
|
||||||
|
|
||||||
|
# temp. extract metadata
|
||||||
|
ansible_meta = {}
|
||||||
|
for key in ["__line__", "__file__", "__ansible_action_meta__"]:
|
||||||
|
default = None
|
||||||
|
|
||||||
|
if key == "__ansible_action_meta__":
|
||||||
|
default = {}
|
||||||
|
|
||||||
|
ansible_meta[key] = task.pop(key, default)
|
||||||
|
|
||||||
|
ansible_action_type = task.get("__ansible_action_type__", "task")
|
||||||
|
if "__ansible_action_type__" in task:
|
||||||
|
del task["__ansible_action_type__"]
|
||||||
|
|
||||||
|
normalized = _normalize(task, custom_modules)
|
||||||
|
|
||||||
normalized[FILENAME_KEY] = filename
|
normalized[FILENAME_KEY] = filename
|
||||||
normalized["__ansible_action_type__"] = ansible_action_type
|
normalized["__ansible_action_type__"] = ansible_action_type
|
||||||
|
|
||||||
@ -446,13 +463,8 @@ def action_tasks(yaml, candidate):
|
|||||||
|
|
||||||
# Add sub-elements of block/rescue/always to tasks list
|
# Add sub-elements of block/rescue/always to tasks list
|
||||||
tasks.extend(extract_from_list(tasks, ["block", "rescue", "always"]))
|
tasks.extend(extract_from_list(tasks, ["block", "rescue", "always"]))
|
||||||
# Remove block/rescue/always elements from tasks list
|
|
||||||
block_rescue_always = ("block", "rescue", "always")
|
|
||||||
tasks[:] = [task for task in tasks if all(k not in task for k in block_rescue_always)]
|
|
||||||
|
|
||||||
allowed = ["include", "include_tasks", "import_playbook", "import_tasks"]
|
return tasks
|
||||||
|
|
||||||
return [task for task in tasks if set(allowed).isdisjoint(task.keys())]
|
|
||||||
|
|
||||||
|
|
||||||
def task_to_str(task):
|
def task_to_str(task):
|
||||||
@ -483,8 +495,6 @@ def extract_from_list(blocks, candidates):
|
|||||||
meta_data.pop(key, None)
|
meta_data.pop(key, None)
|
||||||
|
|
||||||
actions = add_action_type(block[candidate], candidate, meta_data)
|
actions = add_action_type(block[candidate], candidate, meta_data)
|
||||||
for action in actions:
|
|
||||||
action["__raw_task__"] = copy.copy(block)
|
|
||||||
|
|
||||||
results.extend(actions)
|
results.extend(actions)
|
||||||
elif block[candidate] is not None:
|
elif block[candidate] is not None:
|
||||||
@ -575,6 +585,26 @@ def normalized_yaml(file, options):
|
|||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def is_nested_task(task):
|
||||||
|
"""Check if task includes block/always/rescue."""
|
||||||
|
# Cannot really trust the input
|
||||||
|
if isinstance(task, str):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return any(task.get(key) for key in ["block", "rescue", "always"])
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_ansible_parsed_keys_from_task(result, task, keys):
|
||||||
|
"""Return a dict with existing key in task."""
|
||||||
|
for k, v in list(task.items()):
|
||||||
|
if k in keys:
|
||||||
|
# we don't want to re-assign these values, which were
|
||||||
|
# determined by the ModuleArgsParser() above
|
||||||
|
continue
|
||||||
|
result[k] = v
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class UnsafeTag:
|
class UnsafeTag:
|
||||||
"""Handle custom yaml unsafe tag."""
|
"""Handle custom yaml unsafe tag."""
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ ansible:
|
|||||||
exclude:
|
exclude:
|
||||||
- "meta"
|
- "meta"
|
||||||
- "debug"
|
- "debug"
|
||||||
- "block"
|
- "block/always/rescue"
|
||||||
- "include_role"
|
- "include_role"
|
||||||
- "include_tasks"
|
- "include_tasks"
|
||||||
- "include_vars"
|
- "include_vars"
|
||||||
|
Loading…
Reference in New Issue
Block a user