2019-04-10 12:50:48 +00:00
|
|
|
"""Checks related to generic YAML syntax (yamllint)."""
|
|
|
|
|
2018-12-19 10:19:07 +00:00
|
|
|
import os
|
|
|
|
|
2019-04-10 14:09:37 +00:00
|
|
|
from ansiblelater.command.candidates import Error
|
|
|
|
from ansiblelater.command.candidates import Result
|
|
|
|
from ansiblelater.utils.rulehelper import get_action_tasks
|
|
|
|
from ansiblelater.utils.rulehelper import get_normalized_task
|
|
|
|
from ansiblelater.utils.rulehelper import get_normalized_yaml
|
2021-01-09 12:16:08 +00:00
|
|
|
from ansiblelater.utils.rulehelper import get_raw_yaml
|
2019-04-10 14:09:37 +00:00
|
|
|
from ansiblelater.utils.rulehelper import run_yamllint
|
2018-12-19 10:19:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
def check_yaml_has_content(candidate, settings):
|
|
|
|
lines, errors = get_normalized_yaml(candidate, settings)
|
|
|
|
description = "the file appears to have no useful content"
|
|
|
|
|
2021-01-09 12:16:08 +00:00
|
|
|
if (lines and len(lines) == 0) and not errors:
|
2018-12-19 10:19:07 +00:00
|
|
|
errors.append(Error(None, description))
|
|
|
|
|
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
|
|
|
def check_native_yaml(candidate, settings):
|
|
|
|
tasks, errors = get_action_tasks(candidate, settings)
|
|
|
|
description = "task arguments appear to be in key value rather than YAML format"
|
|
|
|
|
|
|
|
if not errors:
|
|
|
|
for task in tasks:
|
|
|
|
normal_form, error = get_normalized_task(task, candidate, settings)
|
|
|
|
if error:
|
|
|
|
errors.extend(error)
|
|
|
|
break
|
|
|
|
|
2019-04-04 14:06:18 +00:00
|
|
|
action = normal_form["action"]["__ansible_module__"]
|
2020-05-19 08:40:29 +00:00
|
|
|
arguments = [
|
|
|
|
bytes(x, "utf-8").decode("unicode_escape")
|
|
|
|
for x in normal_form["action"]["__ansible_arguments__"]
|
|
|
|
]
|
2019-04-04 14:06:18 +00:00
|
|
|
# Cope with `set_fact` where task["set_fact"] is None
|
2018-12-19 10:19:07 +00:00
|
|
|
if not task.get(action):
|
|
|
|
continue
|
|
|
|
if isinstance(task[action], dict):
|
|
|
|
continue
|
|
|
|
# strip additional newlines off task[action]
|
2020-03-04 11:29:35 +00:00
|
|
|
task_action = bytes(task[action].strip(), "utf-8").decode("unicode_escape")
|
|
|
|
if task_action.split() != arguments:
|
2019-04-04 14:06:18 +00:00
|
|
|
errors.append(Error(task["__line__"], description))
|
2018-12-19 10:19:07 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
|
|
|
def check_yaml_empty_lines(candidate, settings):
|
2020-04-05 12:33:43 +00:00
|
|
|
options = "rules: {{empty-lines: {conf}}}".format(conf=settings["yamllint"]["empty-lines"])
|
2021-01-09 12:16:08 +00:00
|
|
|
errors = run_yamllint(candidate, options)
|
2018-12-19 10:19:07 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
|
|
|
def check_yaml_indent(candidate, settings):
|
2020-04-05 12:33:43 +00:00
|
|
|
options = "rules: {{indentation: {conf}}}".format(conf=settings["yamllint"]["indentation"])
|
2021-01-09 12:16:08 +00:00
|
|
|
errors = run_yamllint(candidate, options)
|
2018-12-19 10:19:07 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
|
|
|
def check_yaml_hyphens(candidate, settings):
|
2020-04-05 12:33:43 +00:00
|
|
|
options = "rules: {{hyphens: {conf}}}".format(conf=settings["yamllint"]["hyphens"])
|
2021-01-09 12:16:08 +00:00
|
|
|
errors = run_yamllint(candidate, options)
|
2018-12-19 10:19:07 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
|
|
|
def check_yaml_document_start(candidate, settings):
|
2019-04-10 12:44:08 +00:00
|
|
|
options = "rules: {{document-start: {conf}}}".format(
|
2020-04-05 12:33:43 +00:00
|
|
|
conf=settings["yamllint"]["document-start"]
|
|
|
|
)
|
2021-01-09 12:16:08 +00:00
|
|
|
errors = run_yamllint(candidate, options)
|
2018-12-19 10:19:07 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
2019-10-15 22:31:25 +00:00
|
|
|
def check_yaml_document_end(candidate, settings):
|
2020-04-05 12:33:43 +00:00
|
|
|
options = "rules: {{document-end: {conf}}}".format(conf=settings["yamllint"]["document-end"])
|
2021-01-09 12:16:08 +00:00
|
|
|
errors = run_yamllint(candidate, options)
|
2019-10-15 22:31:25 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
2018-12-19 10:19:07 +00:00
|
|
|
def check_yaml_colons(candidate, settings):
|
2020-04-05 12:33:43 +00:00
|
|
|
options = "rules: {{colons: {conf}}}".format(conf=settings["yamllint"]["colons"])
|
2021-01-09 12:16:08 +00:00
|
|
|
errors = run_yamllint(candidate, options)
|
2018-12-19 10:19:07 +00:00
|
|
|
return Result(candidate.path, errors)
|
|
|
|
|
|
|
|
|
|
|
|
def check_yaml_file(candidate, settings):
|
|
|
|
errors = []
|
|
|
|
filename = candidate.path
|
|
|
|
|
|
|
|
if os.path.isfile(filename) and os.path.splitext(filename)[1][1:] != "yml":
|
2020-04-05 12:33:43 +00:00
|
|
|
errors.append(Error(None, "file does not have a .yml extension"))
|
2018-12-19 10:19:07 +00:00
|
|
|
elif os.path.isfile(filename) and os.path.splitext(filename)[1][1:] == "yml":
|
2021-01-09 12:16:08 +00:00
|
|
|
content, errors = get_raw_yaml(candidate, settings)
|
2018-12-19 10:19:07 +00:00
|
|
|
|
|
|
|
return Result(candidate.path, errors)
|