From 2fe34b6444502079dc0b84365ce82dbc92de308e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 14:06:49 +0200 Subject: Adding upstream version 6.17.2. Signed-off-by: Daniel Baumann --- src/ansiblelint/schemas/README.md | 102 ++ src/ansiblelint/schemas/__init__.py | 1 + src/ansiblelint/schemas/__main__.py | 120 ++ src/ansiblelint/schemas/__store__.json | 62 + src/ansiblelint/schemas/ansible-lint-config.json | 289 ++++ .../schemas/ansible-navigator-config.json | 530 +++++++ src/ansiblelint/schemas/ansible-navigator.json | 430 ++++++ src/ansiblelint/schemas/ansible.json | 1202 ++++++++++++++++ src/ansiblelint/schemas/changelog.json | 262 ++++ src/ansiblelint/schemas/execution-environment.json | 309 ++++ src/ansiblelint/schemas/galaxy.json | 643 +++++++++ src/ansiblelint/schemas/inventory.json | 66 + src/ansiblelint/schemas/main.py | 37 + src/ansiblelint/schemas/meta-runtime.json | 82 ++ src/ansiblelint/schemas/meta.json | 1473 ++++++++++++++++++++ src/ansiblelint/schemas/molecule.json | 561 ++++++++ src/ansiblelint/schemas/playbook.json | 1245 +++++++++++++++++ src/ansiblelint/schemas/requirements.json | 135 ++ src/ansiblelint/schemas/role-arg-spec.json | 250 ++++ src/ansiblelint/schemas/rulebook.json | 645 +++++++++ src/ansiblelint/schemas/tasks.json | 588 ++++++++ src/ansiblelint/schemas/vars.json | 29 + 22 files changed, 9061 insertions(+) create mode 100644 src/ansiblelint/schemas/README.md create mode 100644 src/ansiblelint/schemas/__init__.py create mode 100644 src/ansiblelint/schemas/__main__.py create mode 100644 src/ansiblelint/schemas/__store__.json create mode 100644 src/ansiblelint/schemas/ansible-lint-config.json create mode 100644 src/ansiblelint/schemas/ansible-navigator-config.json create mode 100644 src/ansiblelint/schemas/ansible-navigator.json create mode 100644 src/ansiblelint/schemas/ansible.json create mode 100644 src/ansiblelint/schemas/changelog.json create mode 100644 src/ansiblelint/schemas/execution-environment.json create mode 100644 src/ansiblelint/schemas/galaxy.json create mode 100644 src/ansiblelint/schemas/inventory.json create mode 100644 src/ansiblelint/schemas/main.py create mode 100644 src/ansiblelint/schemas/meta-runtime.json create mode 100644 src/ansiblelint/schemas/meta.json create mode 100644 src/ansiblelint/schemas/molecule.json create mode 100644 src/ansiblelint/schemas/playbook.json create mode 100644 src/ansiblelint/schemas/requirements.json create mode 100644 src/ansiblelint/schemas/role-arg-spec.json create mode 100644 src/ansiblelint/schemas/rulebook.json create mode 100644 src/ansiblelint/schemas/tasks.json create mode 100644 src/ansiblelint/schemas/vars.json (limited to 'src/ansiblelint/schemas') diff --git a/src/ansiblelint/schemas/README.md b/src/ansiblelint/schemas/README.md new file mode 100644 index 0000000..6d986b0 --- /dev/null +++ b/src/ansiblelint/schemas/README.md @@ -0,0 +1,102 @@ +# Schemas for Ansible and its related tools + +[![ci](https://github.com/ansible-community/schemas/actions/workflows/task.yml/badge.svg)](https://github.com/ansible-community/schemas/actions/workflows/task.yml) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![Repository License: MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) + +## About Schemas + +This project aims to generate JSON/YAML validation schemas for Ansible files +such as playbooks, tasks, requirements, meta or vars and also for Molecule +configuration. + +Keep in mind that these schemas will limit your freedom of choice regarding the +syntax you can use to write Ansible tasks as they do not allow some historical +forms which are still allowed by Ansible itself. + +Not any file accepted by Ansible will pass these schemas but we do expect that +any file that passed these schemas should be accepted by Ansible. + +- YAML 1.2 booleans are required as `true` or `false`, while Ansible itself + allows you to use more relaxed forms like `yes` or `no`. +- Inline actions are not allowed, as schema cannot validate them +- Non-built-in modules must be called using `action:` blocks +- Module arguments are not yet verified but we plan to implement it +- Out schemas are strict about usage of jinja2 templating and require `{{` on + arguments declared as **explicit**, which forbid the use of `{{` on those + marked as **implicit**. See the section below for details. + +As these schemas are still experimental, creating pull requests to improve the +schema is of much greater help. Though you are still welcome to report bugs but +expect them to take a long time until someone finds time to fix them. + +If you want to help improve the schemas, have a look at the +[development documentation](CONTRIBUTING.md). + +## Schema Bundle + +We are currently migrating towards a single [ansible.json](/f/ansible.json) +schema bundle, one that contains subschema definitions for all the supported +file types. + +To configure your validator or editor to use the bundle, use the new URLs below, +the part after the `#` in the URLs is essential for informing the loader about +which subschema to use. You can also look at our +[settings.json](.vscode/settings.json) to understand how to configure the +[vscode-yaml](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) +extension. + +- [playbook subschema url](https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json#/$defs/playbook) +- [tasks subschema uri](https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json#/$defs/tasks) + +## Jinja2 implicit vs explicit templating + +While Ansible might allow you to combine implicit and explicit templating, our +schema will not. Our schemas will only allow you to use the recommended form, +either by forbidding you to use the curly braces on implicit ones or forcing you +to add them on explicit ones. + +Examples: + +```yaml +- name: some task + command: echo 123 + register: result + vars: + become_method_var: sudo + become_method: become_method_var # <-- schema will not allow this + # become_method: "{{ become_method_var }}" # <-- that is allowed +``` + +### How to find if a field is implicit or explicit? + +Run assuming that your keyword is `no_log`, you can run +`ansible-doc -t keyword no_log`, which will give you the following output: + +```yaml +failed_when: + applies_to: + - Task + description: + Conditional expression that overrides the task's normal 'failed' status. + priority: 0 + template: implicit + type: list +``` + +As you can see the `template` field tells you if is implicit or explicit. + +Being more restrictive, schema protects you from common accidents, like writing +a simple string in an explicit field. That will always evaluate as true instead +of being evaluated as a jinja template. + +## Activating the schemas + +At this moment installing +[Ansible VS Code Extension by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.ansible) +will activate these schemas. The file patterns used to trigger their use can be +seen +[here](https://github.com/ansible-community/vscode-ansible/blob/master/package.json#L44-L94) + +Because these schemas are generic, you can easily use them with any validators +that support them. diff --git a/src/ansiblelint/schemas/__init__.py b/src/ansiblelint/schemas/__init__.py new file mode 100644 index 0000000..f1dad48 --- /dev/null +++ b/src/ansiblelint/schemas/__init__.py @@ -0,0 +1 @@ +"""Module containing cached JSON schemas.""" diff --git a/src/ansiblelint/schemas/__main__.py b/src/ansiblelint/schemas/__main__.py new file mode 100644 index 0000000..e3ec8ae --- /dev/null +++ b/src/ansiblelint/schemas/__main__.py @@ -0,0 +1,120 @@ +"""Module containing cached JSON schemas.""" +import json +import logging +import os +import sys +import time +import urllib.request +from collections import defaultdict +from functools import cache +from http.client import HTTPException +from pathlib import Path +from typing import Any +from urllib.request import Request + +_logger = logging.getLogger(__package__) + +# Maps kinds to JSON schemas +# See https://www.schemastore.org/json/ +store_file = Path(f"{__file__}/../__store__.json").resolve() +with store_file.open(encoding="utf-8") as json_file: + JSON_SCHEMAS = json.load(json_file) + + +class SchemaCacheDict(defaultdict): # type: ignore[type-arg] + """Caching schema store.""" + + def __missing__(self, key: str) -> Any: + """Load schema on its first use.""" + value = get_schema(key) + self[key] = value + return value + + +@cache +def get_schema(kind: str) -> Any: + """Return the schema for the given kind.""" + schema_file = Path(__file__).parent / f"{kind}.json" + with schema_file.open(encoding="utf-8") as f: + return json.load(f) + + +_schema_cache = SchemaCacheDict() + + +def refresh_schemas(min_age_seconds: int = 3600 * 24) -> int: + """Refresh JSON schemas by downloading latest versions. + + Returns number of changed schemas. + """ + age = int(time.time() - store_file.stat().st_mtime) + + # never check for updated schemas more than once a day + if min_age_seconds > age: + return 0 + if not os.access(store_file, os.W_OK): # pragma: no cover + _logger.debug( + "Skipping schema update due to lack of writing rights on %s", + store_file, + ) + return -1 + _logger.debug("Checking for updated schemas...") + + changed = 0 + for kind, data in JSON_SCHEMAS.items(): + url = data["url"] + if "#" in url: + msg = f"Schema URLs cannot contain # due to python-jsonschema limitation: {url}" + raise RuntimeError(msg) + path = Path(__file__).parent.resolve() / f"{kind}.json" + _logger.debug("Refreshing %s schema ...", kind) + request = Request(url) + etag = data.get("etag", "") + if etag: + request.add_header("If-None-Match", f'"{data.get("etag")}"') + try: + with urllib.request.urlopen(request, timeout=10) as response: # noqa: S310 + if response.status == 200: + content = response.read().decode("utf-8").rstrip() + etag = response.headers["etag"].strip('"') + if etag != data.get("etag", ""): + JSON_SCHEMAS[kind]["etag"] = etag + changed += 1 + with path.open("w", encoding="utf-8") as f_out: + _logger.info("Schema %s was updated", kind) + f_out.write(content) + f_out.write("\n") # prettier/editors + f_out.truncate() + os.fsync(f_out.fileno()) + # unload possibly loaded schema + if kind in _schema_cache: # pragma: no cover + del _schema_cache[kind] + except (ConnectionError, OSError, HTTPException) as exc: + if ( + isinstance(exc, urllib.error.HTTPError) + and getattr(exc, "code", None) == 304 + ): + _logger.debug("Schema %s is not modified", url) + continue + # In case of networking issues, we just stop and use last-known good + _logger.debug("Skipped schema refresh due to unexpected exception: %s", exc) + break + if changed: # pragma: no cover + with store_file.open("w", encoding="utf-8") as f_out: + # formatting should match our .prettierrc.yaml + json.dump(JSON_SCHEMAS, f_out, indent=2, sort_keys=True) + f_out.write("\n") # prettier and editors in general + # clear schema cache + get_schema.cache_clear() + else: + store_file.touch() + changed = 1 + return changed + + +if __name__ == "__main__": + if refresh_schemas(60 * 10): # pragma: no cover + print("Schemas were updated.") # noqa: T201 + sys.exit(1) + else: # pragma: no cover + print("Schemas not updated", 0) # noqa: T201 diff --git a/src/ansiblelint/schemas/__store__.json b/src/ansiblelint/schemas/__store__.json new file mode 100644 index 0000000..d4bcdca --- /dev/null +++ b/src/ansiblelint/schemas/__store__.json @@ -0,0 +1,62 @@ +{ + "ansible-lint-config": { + "etag": "0ec39ba1ca9c20aea463f7f536c6903c88288f47c1b2b2b3d53b527c293f8cc3", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible-lint-config.json" + }, + "ansible-navigator-config": { + "etag": "dd0f0dea68266ae61e5a8d6aed0a1279fdee16f2da4911bc27970241df80f798", + "url": "https://raw.githubusercontent.com/ansible/ansible-navigator/main/src/ansible_navigator/data/ansible-navigator.json" + }, + "changelog": { + "etag": "593ed5eef7c1e670f3667de70d43a41a5138513bd9640a85cbe8cb6faaa59793", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/changelog.json" + }, + "execution-environment": { + "etag": "f3abb1716134227ccd667607840dd7bdebfd02a8980603df031282126dc78264", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/execution-environment.json" + }, + "galaxy": { + "etag": "61f38feb51dc7eaff43ab22f3759b3a5202776ee75ee4204f07135282817f724", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/galaxy.json" + }, + "inventory": { + "etag": "3dcd4890bf31e634a7c4f6138286a42b4985393f210f7ffaa840c2127876aa55", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json" + }, + "meta": { + "etag": "0f376059285181985711b4271a6ff34a8dde662b9fc221d09bdcd64e4fbf86bf", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json" + }, + "meta-runtime": { + "etag": "448b614e9d4411b82d220950b7a415c248cc75d5431f9b8058c771a595d40163", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta-runtime.json" + }, + "molecule": { + "etag": "3456b2e5aaa02fde359ff147cff81d01a37c07f5e10542b6b8b61aaaf8c756a6", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/molecule.json" + }, + "playbook": { + "etag": "acbd5edfc66279f8c3f6f8a99d0874669a254983ace5e4a2cce6105489ab3e21", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/playbook.json" + }, + "requirements": { + "etag": "93c6ccd1f79f58134795b85f9b1193d6e18417dd01a9d1f37d9f247562a1e6fe", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/requirements.json" + }, + "role-arg-spec": { + "etag": "498a6f716c7e99bd474ae9e7d34b3f43fbf2aad750f769392fc8e29fa590be6c", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/role-arg-spec.json" + }, + "rulebook": { + "etag": "f0bbd0ecd656b2298febccc6da0ecf4a7bd239cc112b9de8292c1f50bad612e0", + "url": "https://raw.githubusercontent.com/ansible/ansible-rulebook/main/ansible_rulebook/schema/ruleset_schema.json" + }, + "tasks": { + "etag": "f9fbc0855680d1321fa3902181131d73838d922362d8dfb85a4f59402240cc07", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/tasks.json" + }, + "vars": { + "etag": "5d6c2c22a58f2b48c2a8d8d129f2516e4f17ffc78a2c9ba045eb5ede0ff749d7", + "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/vars.json" + } +} diff --git a/src/ansiblelint/schemas/ansible-lint-config.json b/src/ansiblelint/schemas/ansible-lint-config.json new file mode 100644 index 0000000..f7d50e4 --- /dev/null +++ b/src/ansiblelint/schemas/ansible-lint-config.json @@ -0,0 +1,289 @@ +{ + "$defs": { + "rule": { + "additionalProperties": false, + "properties": { + "exclude_paths": { + "items": { + "type": "string" + }, + "title": "Glob-like paths to be excluded.", + "type": "array" + } + }, + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible-lint-config.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": [ + ".ansible-lint", + ".config/ansible-lint.yml", + ".config/ansible-lint.yaml" + ], + "properties": { + "display_relative_path": { + "default": true, + "title": "Configure how to display file paths", + "type": "boolean" + }, + "enable_list": { + "items": { + "type": "string" + }, + "title": "Enable List", + "type": "array" + }, + "exclude_paths": { + "items": { + "type": "string" + }, + "title": "Exclude Paths", + "type": "array" + }, + "extra_vars": { + "title": "Extra Vars", + "type": "object" + }, + "kinds": { + "items": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "title": "Kinds", + "type": "array" + }, + "loop_var_prefix": { + "title": "Loop Var Prefix", + "type": "string" + }, + "mock_modules": { + "items": { + "type": "string" + }, + "title": "Mock Modules", + "type": "array" + }, + "mock_roles": { + "items": { + "type": "string" + }, + "title": "Mock Roles", + "type": "array" + }, + "offline": { + "default": false, + "title": "Offline", + "type": "boolean" + }, + "only_builtins_allow_collections": { + "items": { + "type": "string" + }, + "title": "Only Builtins Allow Collections", + "type": "array" + }, + "only_builtins_allow_modules": { + "items": { + "type": "string" + }, + "title": "Only Builtins Allow Modules", + "type": "array" + }, + "parseable": { + "default": true, + "title": "Parseable", + "type": "boolean" + }, + "profile": { + "enum": [ + "min", + "basic", + "moderate", + "safety", + "shared", + "production", + null + ], + "title": "Profile", + "type": ["null", "string"] + }, + "progressive": { + "default": false, + "title": "Progressive (removed feature)", + "type": "boolean" + }, + "project_dir": { + "default": null, + "title": "Project Directory", + "type": ["string", "null"] + }, + "quiet": { + "default": true, + "title": "Quiet", + "type": "boolean" + }, + "rules": { + "additionalProperties": { + "$ref": "#/$defs/rule" + }, + "propertyNames": { + "oneOf": [ + { + "enum": [ + "command-instead-of-module", + "command-instead-of-shell", + "deprecated-bare-vars", + "deprecated-local-action", + "deprecated-module", + "empty-string-compare", + "fqcn", + "fqcn[action-core]", + "fqcn[action]", + "fqcn[canonical]", + "fqcn[keyword]", + "galaxy", + "galaxy[no-changelog]", + "galaxy[no-runtime]", + "galaxy[tags]", + "galaxy[version-incorrect]", + "galaxy[version-missing]", + "ignore-errors", + "inline-env-var", + "internal-error", + "jinja", + "jinja[invalid]", + "jinja[spacing]", + "key-order", + "latest", + "literal-compare", + "load-failure", + "load-failure[not-found]", + "loop-var-prefix", + "loop-var-prefix[missing]", + "loop-var-prefix[wrong]", + "meta-incorrect", + "meta-no-tags", + "meta-runtime", + "meta-video-links", + "name", + "name[casing]", + "name[play]", + "name[prefix]", + "name[template]", + "no-changed-when", + "no-handler", + "no-jinja-when", + "no-log-password", + "no-prompting", + "no-relative-paths", + "no-same-owner", + "no-tabs", + "only-builtins", + "package-latest", + "parser-error", + "partial-become", + "playbook-extension", + "risky-file-permissions", + "risky-octal", + "risky-shell-pipe", + "role-name", + "run-once", + "run-once[play]", + "run-once[task]", + "sanity", + "sanity[bad-ignore]", + "sanity[cannot-ignore]", + "schema", + "syntax-check", + "var-naming", + "yaml" + ], + "type": "string" + }, + { + "pattern": "^[a-z0-9-\\[\\]]+$", + "type": "string" + } + ] + }, + "title": "Rules specific configuration.", + "type": "object" + }, + "rulesdir": { + "items": { + "type": "string" + }, + "title": "Rulesdir", + "type": "array" + }, + "sarif_file": { + "default": null, + "title": "SARIF Output filename", + "type": ["null", "string"] + }, + "skip_action_validation": { + "default": false, + "title": "Skip Action Validation", + "type": "boolean" + }, + "skip_list": { + "items": { + "type": "string" + }, + "title": "Skip List", + "type": "array" + }, + "strict": { + "default": false, + "title": "Strict", + "type": "boolean" + }, + "tags": { + "items": { + "type": "string" + }, + "title": "Tags", + "type": "array" + }, + "task_name_prefix": { + "default": "{stem} | ", + "title": "Allow custom prefix for task[prefix]", + "type": "string" + }, + "use_default_rules": { + "default": true, + "title": "Use Default Rules", + "type": "boolean" + }, + "var_naming_pattern": { + "default": "^[a-z_][a-z0-9_]*$", + "title": "Regex used to verify variable names", + "type": "string" + }, + "verbosity": { + "default": 0, + "title": "Verbosity", + "type": "integer" + }, + "warn_list": { + "items": { + "type": "string" + }, + "title": "Warn List", + "type": "array" + }, + "write_list": { + "items": { + "type": "string" + }, + "title": "Write List", + "type": "array" + } + }, + "title": "Ansible-lint Configuration Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/ansible-navigator-config.json b/src/ansiblelint/schemas/ansible-navigator-config.json new file mode 100644 index 0000000..e81a878 --- /dev/null +++ b/src/ansiblelint/schemas/ansible-navigator-config.json @@ -0,0 +1,530 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "properties": { + "ansible-navigator": { + "additionalProperties": false, + "properties": { + "ansible": { + "additionalProperties": false, + "properties": { + "cmdline": { + "description": "Extra parameters passed to the corresponding command", + "type": "string" + }, + "config": { + "additionalProperties": false, + "properties": { + "help": { + "default": false, + "description": "Help options for ansible-config command in stdout mode", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "path": { + "description": "Specify the path to the ansible configuration file", + "type": "string" + } + } + }, + "doc": { + "additionalProperties": false, + "properties": { + "help": { + "default": false, + "description": "Help options for ansible-doc command in stdout mode", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "plugin": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Specify the plugin name", + "type": "string" + }, + "type": { + "default": "module", + "description": "Specify the plugin type, 'become', 'cache', 'callback', 'cliconf', 'connection', 'filter', 'httpapi', 'inventory', 'keyword', 'lookup', 'module', 'netconf', 'role', 'shell', 'strategy', 'test' or 'vars'", + "enum": [ + "become", + "cache", + "callback", + "cliconf", + "connection", + "filter", + "httpapi", + "inventory", + "keyword", + "lookup", + "module", + "netconf", + "role", + "shell", + "strategy", + "test", + "vars" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "inventory": { + "additionalProperties": false, + "properties": { + "entries": { + "description": "Specify an inventory file path or comma separated host list", + "items": { + "type": "string" + }, + "type": "array" + }, + "help": { + "default": false, + "description": "Help options for ansible-inventory command in stdout mode", + "enum": [ + true, + false + ], + "type": "boolean" + } + } + }, + "playbook": { + "additionalProperties": false, + "properties": { + "help": { + "default": false, + "description": "Help options for ansible-playbook command in stdout mode", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "path": { + "description": "Specify the playbook name", + "type": "string" + } + } + } + }, + "type": "object" + }, + "ansible-builder": { + "additionalProperties": false, + "properties": { + "help": { + "default": false, + "description": "Help options for ansible-builder command in stdout mode", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "workdir": { + "default": ".", + "description": "Specify the path that contains ansible-builder manifest files", + "type": "string" + } + }, + "type": "object" + }, + "ansible-lint": { + "additionalProperties": false, + "properties": { + "config": { + "description": "Specify the path to the ansible-lint configuration file", + "type": "string" + }, + "lintables": { + "description": "Path to files on which to run ansible-lint", + "type": "string" + } + }, + "type": "object" + }, + "ansible-runner": { + "additionalProperties": false, + "properties": { + "artifact-dir": { + "description": "The directory path to store artifacts generated by ansible-runner", + "type": "string" + }, + "job-events": { + "default": false, + "description": "Write ansible-runner job_events in the artifact directory", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "rotate-artifacts-count": { + "description": "Keep ansible-runner artifact directories, for last n runs, if set to 0 artifact directories won't be deleted", + "type": "integer" + }, + "timeout": { + "description": "The timeout value after which ansible-runner will forcefully stop the execution", + "type": "integer" + } + }, + "type": "object" + }, + "app": { + "default": "welcome", + "description": "Subcommands", + "enum": [ + "builder", + "collections", + "config", + "doc", + "exec", + "images", + "inventory", + "lint", + "replay", + "run", + "settings", + "welcome" + ], + "type": "string" + }, + "collection-doc-cache-path": { + "default": "~/.cache/ansible-navigator/collection_doc_cache.db", + "description": "The path to collection doc cache", + "type": "string" + }, + "color": { + "additionalProperties": false, + "properties": { + "enable": { + "default": true, + "description": "Enable the use of color for mode interactive and stdout", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "osc4": { + "default": true, + "description": "Enable or disable terminal color changing support with OSC 4", + "enum": [ + true, + false + ], + "type": "boolean" + } + }, + "type": "object" + }, + "editor": { + "additionalProperties": false, + "properties": { + "command": { + "default": "vi +{line_number} {filename}", + "description": "Specify the editor command", + "type": "string" + }, + "console": { + "default": true, + "description": "Specify if the editor is console based", + "enum": [ + true, + false + ], + "type": "boolean" + } + }, + "type": "object" + }, + "enable-prompts": { + "default": false, + "description": "Enable prompts for password and in playbooks. This will set mode to stdout and disable playbook artifact creation", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "exec": { + "additionalProperties": false, + "properties": { + "command": { + "default": "/bin/bash", + "description": "Specify the command to run within the execution environment", + "type": "string" + }, + "shell": { + "default": true, + "description": "Specify the exec command should be run in a shell", + "enum": [ + true, + false + ], + "type": "boolean" + } + }, + "type": "object" + }, + "execution-environment": { + "additionalProperties": false, + "properties": { + "container-engine": { + "default": "auto", + "description": "Specify the container engine (auto=podman then docker)", + "enum": [ + "auto", + "podman", + "docker" + ], + "type": "string" + }, + "container-options": { + "description": "Extra parameters passed to the container engine command", + "items": { + "type": "string" + }, + "type": "array" + }, + "enabled": { + "default": true, + "description": "Enable or disable the use of an execution environment", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "environment-variables": { + "additionalProperties": false, + "properties": { + "pass": { + "description": "Specify an existing environment variable to be passed through to and set within the execution environment (--penv MY_VAR)", + "items": { + "type": "string" + }, + "type": "array" + }, + "set": { + "description": "Specify an environment variable and a value to be set within the execution environment (--senv MY_VAR=42)", + "type": "object" + } + }, + "type": "object" + }, + "image": { + "description": "Specify the name of the execution environment image", + "type": "string" + }, + "pull": { + "additionalProperties": false, + "properties": { + "arguments": { + "description": "Specify any additional parameters that should be added to the pull command when pulling an execution environment from a container registry. e.g. --pa='--tls-verify=false'", + "items": { + "type": "string" + }, + "type": "array" + }, + "policy": { + "default": "tag", + "description": "Specify the image pull policy always:Always pull the image, missing:Pull if not locally available, never:Never pull the image, tag:if the image tag is 'latest', always pull the image, otherwise pull if not locally available", + "enum": [ + "always", + "missing", + "never", + "tag" + ], + "type": "string" + } + } + }, + "volume-mounts": { + "additionalProperties": false, + "description": "Specify volume to be bind mounted within an execution environment (--eev /home/user/test:/home/user/test:Z)", + "items": { + "additionalProperties": false, + "properties": { + "dest": { + "type": "string" + }, + "options": { + "type": "string" + }, + "src": { + "type": "string" + } + }, + "required": [ + "src", + "dest" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "format": { + "default": "yaml", + "description": "Specify the format for stdout output.", + "enum": [ + "json", + "yaml" + ], + "type": "string" + }, + "images": { + "additionalProperties": false, + "properties": { + "details": { + "default": [ + "everything" + ], + "description": "Provide detailed information about the selected execution environment image", + "items": { + "enum": [ + "ansible_collections", + "ansible_version", + "everything", + "os_release", + "python_packages", + "python_version", + "redhat_release", + "system_packages" + ], + "type": "string" + }, + "type": "array" + } + } + }, + "inventory-columns": { + "description": "Specify a host attribute to show in the inventory view", + "items": { + "type": "string" + }, + "type": "array" + }, + "logging": { + "additionalProperties": false, + "properties": { + "append": { + "default": true, + "description": "Specify if log messages should be appended to an existing log file, otherwise a new log file will be created per session", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "file": { + "default": "./ansible-navigator.log", + "description": "Specify the full path for the ansible-navigator log file", + "type": "string" + }, + "level": { + "default": "warning", + "description": "Specify the ansible-navigator log level", + "enum": [ + "debug", + "info", + "warning", + "error", + "critical" + ], + "type": "string" + } + }, + "type": "object" + }, + "mode": { + "default": "interactive", + "description": "Specify the user-interface mode", + "enum": [ + "stdout", + "interactive" + ], + "type": "string" + }, + "playbook-artifact": { + "additionalProperties": false, + "properties": { + "enable": { + "default": true, + "description": "Enable or disable the creation of artifacts for completed playbooks. Note: not compatible with '--mode stdout' when playbooks require user input", + "enum": [ + true, + false + ], + "type": "boolean" + }, + "replay": { + "description": "Specify the path for the playbook artifact to replay", + "type": "string" + }, + "save-as": { + "default": "{playbook_dir}/{playbook_name}-artifact-{time_stamp}.json", + "description": "Specify the name for artifacts created from completed playbooks. The following placeholders are available: {playbook_dir}, {playbook_name}, {playbook_status}, and {time_stamp}", + "type": "string" + } + }, + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "effective": { + "default": false, + "description": "Show the effective settings. Defaults, CLI parameters, environment variables, and the settings file will be combined", + "type": "boolean" + }, + "sample": { + "default": false, + "description": "Generate a sample settings file", + "type": "boolean" + }, + "schema": { + "default": "json", + "description": "Generate a schema for the settings file ('json'= draft-07 JSON Schema)", + "enum": [ + "json" + ], + "type": "string" + }, + "sources": { + "default": false, + "description": "Show the source of each current settings entry", + "type": "boolean" + } + } + }, + "time-zone": { + "default": "UTC", + "description": "Specify the IANA time zone to use or 'local' to use the system time zone", + "type": "string" + } + } + } + }, + "required": [ + "ansible-navigator" + ], + "title": "ansible-navigator settings v3", + "type": "object", + "version": "3" +} diff --git a/src/ansiblelint/schemas/ansible-navigator.json b/src/ansiblelint/schemas/ansible-navigator.json new file mode 100644 index 0000000..be83649 --- /dev/null +++ b/src/ansiblelint/schemas/ansible-navigator.json @@ -0,0 +1,430 @@ +{ + "$defs": { + "AnsibleBuilderModel": { + "additionalProperties": false, + "properties": { + "workdir": { + "default": "/tmp/", + "description": "Specify the path that contains ansible-builder manifest files", + "title": "Workdir", + "type": "string" + } + }, + "type": "object" + }, + "AnsibleModel": { + "additionalProperties": false, + "properties": { + "cmdline": { + "description": "Extra parameters passed to the corresponding command", + "title": "Cmdline", + "type": "string" + }, + "config": { + "description": "Specify the path to the ansible configuration file", + "title": "Config", + "type": "string" + }, + "inventories": { + "description": "Specify an inventory file path or host list", + "items": { + "type": "string" + }, + "title": "Inventories", + "type": "array" + }, + "playbook": { + "description": "Specify the playbook name", + "title": "Playbook", + "type": "string" + } + }, + "title": "AnsibleModel", + "type": "object" + }, + "AnsibleNavigatorModel": { + "additionalProperties": false, + "properties": { + "ansible": { + "$ref": "#/$defs/AnsibleModel" + }, + "ansible-builder": { + "$ref": "#/$defs/AnsibleBuilderModel" + }, + "ansible-runner": { + "$ref": "#/$defs/AnsibleRunnerModel" + }, + "app": { + "default": "welcome", + "description": "Subcommands", + "enum": [ + "collections", + "config", + "doc", + "exec", + "images", + "inventory", + "replay", + "run", + "welcome" + ], + "title": "App", + "type": "string" + }, + "collection-doc-cache-path": { + "default": "$HOME/.cache/ansible-navigator/collection_doc_cache.db", + "description": "The path to collection doc cache", + "title": "Collection-Doc-Cache-Path", + "type": "string" + }, + "color": { + "$ref": "#/$defs/ColorModel" + }, + "documentation": { + "$ref": "#/$defs/DocumentationModel" + }, + "editor": { + "$ref": "#/$defs/EditorModel" + }, + "exec": { + "$ref": "#/$defs/ExecModel" + }, + "execution-environment": { + "$ref": "#/$defs/ExecutionEnvironmentModel" + }, + "help-builder": { + "default": false, + "description": "Help options for ansible-builder command in stdout mode", + "title": "Help-Builder", + "type": "boolean" + }, + "help-config": { + "default": false, + "description": "Help options for ansible-config command in stdout mode", + "title": "Help-Config", + "type": "boolean" + }, + "help-doc": { + "default": false, + "description": "Help options for ansible-doc command in stdout mode", + "title": "Help-Doc", + "type": "boolean" + }, + "help-inventory": { + "default": false, + "description": "Help options for ansible-inventory command in stdout mode", + "title": "Help-Inventory", + "type": "boolean" + }, + "help-playbook": { + "default": false, + "description": "Help options for ansible-playbook command in stdout mode", + "title": "Help-Playbook", + "type": "boolean" + }, + "inventory-columns": { + "description": "Specify a host attribute to show in the inventory view", + "items": { + "type": "string" + }, + "title": "Inventory-Columns", + "type": "array" + }, + "logging": { + "$ref": "#/$defs/LoggingModel" + }, + "mode": { + "default": "interactive", + "description": "Specify the user-interface mode", + "enum": ["stdout", "interactive"], + "title": "Mode", + "type": "string" + }, + "playbook-artifact": { + "$ref": "#/$defs/PlaybookArtifactModel" + } + }, + "title": "AnsibleNavigatorModel", + "type": "object" + }, + "AnsibleRunnerModel": { + "additionalProperties": false, + "properties": { + "artifact-dir": { + "description": "The directory path to store artifacts generated by ansible-runner", + "title": "Artifact-Dir", + "type": "string" + }, + "rotate-artifacts-count": { + "description": "Keep ansible-runner artifact directories, for last n runs, if set to 0 artifact directories won't be deleted", + "title": "Rotate-Artifacts-Count", + "type": "integer" + }, + "timeout": { + "description": "The timeout value after which ansible-runner will force stop the execution", + "title": "Timeout", + "type": "integer" + } + }, + "title": "AnsibleRunnerModel", + "type": "object" + }, + "ColorModel": { + "additionalProperties": false, + "properties": { + "enable": { + "default": false, + "description": "Enable the use of color in the display", + "title": "Enable", + "type": "boolean" + }, + "osc4": { + "default": true, + "description": "Enable or disable terminal color changing support with OSC 4", + "title": "Osc4", + "type": "boolean" + } + }, + "title": "ColorModel", + "type": "object" + }, + "DocumentationModel": { + "additionalProperties": false, + "properties": { + "plugin": { + "$ref": "#/$defs/PluginModel" + } + }, + "title": "DocumentationModel", + "type": "object" + }, + "EditorModel": { + "additionalProperties": false, + "properties": { + "command": { + "default": "vi +{line_number} {filename}", + "description": "Specify the editor command", + "title": "Command", + "type": "string" + }, + "console": { + "default": true, + "description": "Specify if the editor is console based", + "title": "Console", + "type": "boolean" + } + }, + "title": "EditorModel", + "type": "object" + }, + "EnvironmentVariablesModel": { + "additionalProperties": false, + "properties": { + "pass": { + "description": "Specify an exiting environment variable to be passed through to and set within the execution environment", + "items": { + "type": "string" + }, + "title": "Pass", + "type": "array" + }, + "set": { + "additionalProperties": { + "type": "string" + }, + "description": "Specify an environment variable and a value to be set within the execution environment", + "title": "Set", + "type": "object" + } + }, + "title": "EnvironmentVariablesModel", + "type": "object" + }, + "ExecModel": { + "additionalProperties": false, + "properties": { + "command": { + "default": "/bin/bash", + "description": "Specify the command to run within the execution environment", + "title": "Command", + "type": "string" + }, + "shell": { + "default": true, + "description": "Specify the exec command should be run in a shell", + "title": "Shell", + "type": "boolean" + } + }, + "title": "ExecModel", + "type": "object" + }, + "ExecutionEnvironmentModel": { + "additionalProperties": false, + "properties": { + "container-engine": { + "default": "auto", + "description": "Specify the container engine (auto=podman then docker)", + "enum": ["auto", "podman", "docker"], + "title": "Container-Engine", + "type": "string" + }, + "container-options": { + "description": "Extra parameters passed to the container engine command", + "items": { + "type": "string" + }, + "title": "Container-Options", + "type": "array" + }, + "enabled": { + "default": true, + "description": "Enable or disable the use of an execution environment", + "title": "Enabled", + "type": "boolean" + }, + "environment-variables": { + "$ref": "#/$defs/EnvironmentVariablesModel" + }, + "image": { + "default": "quay.io/ansible/creator-ee:v0.2.0", + "description": "Specify the name of the execution environment image", + "title": "Image", + "type": "string" + }, + "pull-policy": { + "default": "tag", + "description": "Specify the image pull policy.\nalways: Always pull the image\nmissing: Pull if not locally available\nnever: Never pull the image\ntag: if the image tag is 'latest', always pull the image, otherwise pull if not locally available", + "enum": ["always", "missing", "never", "tag"], + "title": "Pull-Policy", + "type": "string" + }, + "volume-mounts": { + "description": "Specify volume to be bind mounted within an execution environment", + "items": { + "$ref": "#/$defs/VolumeMountsModel" + }, + "title": "Volume-Mounts", + "type": "array" + } + }, + "title": "ExecutionEnvironmentModel", + "type": "object" + }, + "LoggingModel": { + "additionalProperties": false, + "properties": { + "append": { + "default": true, + "description": "Specify if log messages should be appended to an existing log file, otherwise a new log file will be created per session", + "title": "Append", + "type": "boolean" + }, + "file": { + "default": "$PWD/ansible-navigator.", + "description": "Specify the full path for the ansible-navigator log file", + "title": "File", + "type": "string" + }, + "level": { + "default": "warning", + "description": "Specify the ansible-navigator log level", + "enum": ["debug", "info", "warning", "error", "critical"], + "title": "Level", + "type": "string" + } + }, + "title": "LoggingModel", + "type": "object" + }, + "PlaybookArtifactModel": { + "additionalProperties": false, + "properties": { + "enable": { + "default": true, + "description": "Enable or disable the creation of artifacts for completed playbooks.\nNote: not compatible with 'mode: stdout' when playbooks require user input", + "title": "Enable", + "type": "boolean" + }, + "replay": { + "description": "Specify the path for the playbook artifact to replay", + "title": "Replay", + "type": "string" + }, + "save-as": { + "default": "{playbook_dir}/{playbook_name}-artifact-{ts_utc}.json", + "description": "Specify the name for artifacts created from completed playbooks", + "title": "Save-As", + "type": "string" + } + }, + "title": "PlaybookArtifactModel", + "type": "object" + }, + "PluginModel": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Specify the plugin name", + "title": "Name", + "type": "string" + }, + "type": { + "default": "module", + "description": "Specify the plugin type", + "enum": [ + "become", + "cache", + "callback", + "cliconf", + "connection", + "httpapi", + "inventory", + "lookup", + "module", + "netconf", + "shell", + "strategy", + "vars" + ], + "title": "Type", + "type": "string" + } + }, + "title": "PluginModel", + "type": "object" + }, + "VolumeMountsModel": { + "additionalProperties": false, + "properties": { + "dest": { + "title": "Dest", + "type": "string" + }, + "label": { + "title": "Label", + "type": "string" + }, + "src": { + "title": "Src", + "type": "string" + } + }, + "required": ["src", "dest"], + "title": "VolumeMountsModel", + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible-navigator.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": ["ansible-navigator.yml"], + "properties": { + "ansible-navigator": { + "$ref": "#/$defs/AnsibleNavigatorModel" + } + }, + "required": ["ansible-navigator"], + "title": "Ansible-Navigator Configuration Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/ansible.json b/src/ansiblelint/schemas/ansible.json new file mode 100644 index 0000000..94846d0 --- /dev/null +++ b/src/ansiblelint/schemas/ansible.json @@ -0,0 +1,1202 @@ +{ + "$defs": { + "ansible.builtin.import_playbook": { + "additionalProperties": false, + "oneOf": [ + { + "not": { + "required": ["import_playbook"] + }, + "required": ["ansible.builtin.import_playbook"] + }, + { + "not": { + "required": ["ansible.builtin.import_playbook"] + }, + "required": ["import_playbook"] + } + ], + "patternProperties": { + "^(ansible\\.builtin\\.)?import_playbook$": { + "markdownDescription": "* Includes a file with a list of plays to be executed.\n * Files with a list of plays can only be included at the top level.\n * You cannot use this action inside a play.\n\nSee [import_playbook](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/import_playbook_module.html)", + "title": "Import Playbook", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "tags": { + "$ref": "#/$defs/tags" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "type": "object" + }, + "become_method": { + "anyOf": [ + { + "enum": [ + "ansible.builtin.sudo", + "ansible.builtin.su", + "community.general.pbrun", + "community.general.pfexec", + "ansible.builtin.runas", + "community.general.dzdo", + "community.general.ksu", + "community.general.doas", + "community.general.machinectl", + "community.general.pmrun", + "community.general.sesu", + "community.general.sudosu" + ], + "type": "string" + }, + { + "$ref": "#/$defs/full-jinja" + }, + { + "pattern": "[A-Za-z0-9_\\.]+", + "type": "string" + } + ], + "markdownDescription": "See [become](https://docs.ansible.com/ansible/latest/user_guide/become.html)", + "title": "Become Method" + }, + "block": { + "properties": { + "always": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "title": "Always", + "type": "array" + }, + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "block": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "markdownDescription": "Blocks create logical groups of tasks. Blocks also offer ways to handle task errors, similar to exception handling in many programming languages. See [blocks](https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html)", + "title": "Block", + "type": "array" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delegate_facts": { + "title": "Delegate Facts", + "type": "boolean" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "port": { + "$ref": "#/$defs/templated-integer" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "rescue": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "title": "Rescue", + "type": "array" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": ["block"], + "type": "object" + }, + "complex_conditional": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "items": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + }, + "type": "array" + } + ] + }, + "environment": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "$ref": "#/$defs/full-jinja" + } + ], + "title": "Environment" + }, + "full-jinja": { + "pattern": "^\\{[\\{%](.|[\r\n])*[\\}%]\\}$", + "type": "string" + }, + "ignore_errors": { + "$ref": "#/$defs/templated-boolean", + "markdownDescription": "See [ignore_errors](https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#ignoring-failed-commands)", + "title": "Ignore Errors" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean", + "markdownDescription": "Use for protecting sensitive data. See [no_log](https://docs.ansible.com/ansible/latest/reference_appendices/logging.html)", + "title": "no_log" + }, + "play": { + "additionalProperties": false, + "allOf": [ + { + "not": { + "required": ["ansible.builtin.import_playbook"] + } + }, + { + "not": { + "required": ["import_playbook"] + } + } + ], + "properties": { + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "fact_path": { + "title": "Fact Path", + "type": "string" + }, + "force_handlers": { + "title": "Force Handlers", + "type": "boolean" + }, + "gather_facts": { + "title": "Gather Facts", + "type": "boolean" + }, + "gather_subset": { + "items": { + "anyOf": [ + { + "enum": [ + "all", + "min", + "all_ipv4_addresses", + "all_ipv6_addresses", + "apparmor", + "architecture", + "caps", + "chroot,cmdline", + "date_time", + "default_ipv4", + "default_ipv6", + "devices", + "distribution", + "distribution_major_version", + "distribution_release", + "distribution_version", + "dns", + "effective_group_ids", + "effective_user_id", + "env", + "facter", + "fips", + "hardware", + "interfaces", + "is_chroot", + "iscsi", + "kernel", + "local", + "lsb", + "machine", + "machine_id", + "mounts", + "network", + "ohai", + "os_family", + "pkg_mgr", + "platform", + "processor", + "processor_cores", + "processor_count", + "python", + "python_version", + "real_user_id", + "selinux", + "service_mgr", + "ssh_host_key_dsa_public", + "ssh_host_key_ecdsa_public", + "ssh_host_key_ed25519_public", + "ssh_host_key_rsa_public", + "ssh_host_pub_keys", + "ssh_pub_keys", + "system", + "system_capabilities", + "system_capabilities_enforced", + "user", + "user_dir", + "user_gecos", + "user_gid", + "user_id", + "user_shell", + "user_uid", + "virtual", + "virtualization_role", + "virtualization_type" + ], + "type": "string" + }, + { + "enum": [ + "!all", + "!min", + "!all_ipv4_addresses", + "!all_ipv6_addresses", + "!apparmor", + "!architecture", + "!caps", + "!chroot,cmdline", + "!date_time", + "!default_ipv4", + "!default_ipv6", + "!devices", + "!distribution", + "!distribution_major_version", + "!distribution_release", + "!distribution_version", + "!dns", + "!effective_group_ids", + "!effective_user_id", + "!env", + "!facter", + "!fips", + "!hardware", + "!interfaces", + "!is_chroot", + "!iscsi", + "!kernel", + "!local", + "!lsb", + "!machine", + "!machine_id", + "!mounts", + "!network", + "!ohai", + "!os_family", + "!pkg_mgr", + "!platform", + "!processor", + "!processor_cores", + "!processor_count", + "!python", + "!python_version", + "!real_user_id", + "!selinux", + "!service_mgr", + "!ssh_host_key_dsa_public", + "!ssh_host_key_ecdsa_public", + "!ssh_host_key_ed25519_public", + "!ssh_host_key_rsa_public", + "!ssh_host_pub_keys", + "!ssh_pub_keys", + "!system", + "!system_capabilities", + "!system_capabilities_enforced", + "!user", + "!user_dir", + "!user_gecos", + "!user_gid", + "!user_id", + "!user_shell", + "!user_uid", + "!virtual", + "!virtualization_role", + "!virtualization_type" + ], + "type": "string" + } + ] + }, + "title": "Gather Subset", + "type": "array" + }, + "gather_timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Gather Timeout" + }, + "handlers": { + "$ref": "#/$defs/tasks" + }, + "hosts": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Hosts" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "max_fail_percentage": { + "title": "Max Fail Percentage", + "type": "number" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "order": { + "enum": [ + "default", + "sorted", + "reverse_sorted", + "reverse_inventory", + "shuffle" + ], + "title": "Order", + "type": "string" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "post_tasks": { + "$ref": "#/$defs/tasks" + }, + "pre_tasks": { + "$ref": "#/$defs/tasks" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "roles": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/play-role" + }, + { + "type": "string" + } + ] + }, + "markdownDescription": "Roles let you automatically load related vars, files, tasks, handlers, and other Ansible artifacts based on a known file structure. After you group your content in roles, you can easily reuse them and share them with other users.\n See [roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#roles)", + "title": "Roles", + "type": "array" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "serial": { + "anyOf": [ + { + "$ref": "#/$defs/templated-integer-or-percent" + }, + { + "items": { + "$ref": "#/$defs/templated-integer-or-percent" + }, + "type": "array" + } + ], + "markdownDescription": "Integer, percentage or list of those. See [Setting the batch size with serial](https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html#setting-the-batch-size-with-serial)", + "title": "Batch size" + }, + "strategy": { + "title": "Strategy", + "type": "string" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "tasks": { + "$ref": "#/$defs/tasks" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "user": { + "title": "Remote User", + "type": "string" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "vars_files": { + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "title": "Vars Files", + "type": ["array", "string", "null"] + }, + "vars_prompt": { + "items": { + "$ref": "#/$defs/vars_prompt" + }, + "markdownDescription": "See [vars_prompt](https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html)", + "title": "vars_prompt", + "type": "array" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": ["hosts"], + "title": "play", + "type": "object" + }, + "play-role": { + "markdownDescription": "See [roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#roles)", + "properties": { + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "role": { + "title": "Role", + "type": "string" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": ["role"], + "title": "play-role", + "type": "object" + }, + "playbook": { + "examples": ["playbooks/*.yml", "playbooks/*.yaml"], + "items": { + "oneOf": [ + { + "$ref": "#/$defs/ansible.builtin.import_playbook" + }, + { + "$ref": "#/$defs/play" + } + ] + }, + "title": "Ansible Playbook", + "type": "array" + }, + "tags": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Tags" + }, + "task": { + "additionalProperties": true, + "allOf": [ + { + "not": { + "required": ["hosts"] + } + }, + { + "not": { + "required": ["tasks"] + } + }, + { + "not": { + "required": ["import_playbook"] + } + }, + { + "not": { + "required": ["block"] + } + } + ], + "properties": { + "action": { + "title": "Action", + "type": "string" + }, + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "args": { + "$ref": "#/$defs/templated-object", + "title": "Args" + }, + "async": { + "$ref": "#/$defs/templated-integer", + "title": "Async" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "changed_when": { + "$ref": "#/$defs/complex_conditional", + "markdownDescription": "See [changed_when](https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#defining-changed)", + "title": "Changed When" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delay": { + "$ref": "#/$defs/templated-integer", + "title": "Delay" + }, + "delegate_facts": { + "title": "Delegate Facts", + "type": "boolean" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "failed_when": { + "$ref": "#/$defs/complex_conditional", + "title": "Failed When" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "listen": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Applies only to handlers. See [listen](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html)", + "title": "Listen" + }, + "local_action": { + "title": "Local Action", + "type": ["string", "object"] + }, + "loop": { + "title": "Loop", + "type": ["string", "array"] + }, + "loop_control": { + "title": "Loop Control" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/no_log" + }, + "notify": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Notify" + }, + "poll": { + "$ref": "#/$defs/templated-integer", + "title": "Poll" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "register": { + "title": "Register", + "type": "string" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "retries": { + "$ref": "#/$defs/templated-integer", + "title": "Retries" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "until": { + "$ref": "#/$defs/complex_conditional", + "title": "Until" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + }, + "with_dict": { + "title": "With Dict" + }, + "with_fileglob": { + "title": "With Fileglob" + }, + "with_filetree": { + "title": "With Filetree" + }, + "with_first_found": { + "title": "With First Found" + }, + "with_indexed_items": { + "title": "With Indexed Items" + }, + "with_ini": { + "title": "With Ini" + }, + "with_inventory_hostnames": { + "title": "With Inventory Hostnames" + }, + "with_items": { + "anyOf": [ + { + "$ref": "#/$defs/full-jinja" + }, + { + "type": "array" + } + ], + "markdownDescription": "See [loops](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#loops)", + "title": "With Items" + }, + "with_lines": { + "title": "With Lines" + }, + "with_random_choice": { + "title": "With Random Choice" + }, + "with_sequence": { + "title": "With Sequence" + }, + "with_subelements": { + "title": "With Subelements" + }, + "with_together": { + "title": "With Together" + } + }, + "title": "task", + "type": "object" + }, + "tasks": { + "$schema": "http://json-schema.org/draft-07/schema", + "examples": ["tasks/*.yml", "handlers/*.yml"], + "items": { + "anyOf": [ + { + "$ref": "#/$defs/block" + }, + { + "$ref": "#/$defs/task" + } + ] + }, + "title": "Ansible Tasks Schema", + "type": ["array", "null"] + }, + "templated-boolean": { + "oneOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-integer": { + "oneOf": [ + { + "type": "integer" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-integer-or-percent": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^\\d+\\.?\\d*%?$", + "type": "string" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-object": { + "oneOf": [ + { + "type": "object" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "vars_prompt": { + "additionalProperties": false, + "properties": { + "confirm": { + "title": "Confirm", + "type": "boolean" + }, + "default": { + "title": "Default", + "type": "string" + }, + "encrypt": { + "enum": [ + "des_crypt", + "bsdi_crypt", + "bigcrypt", + "crypt16", + "md5_crypt", + "bcrypt", + "sha1_crypt", + "sun_md5_crypt", + "sha256_crypt", + "sha512_crypt", + "apr_md5_crypt", + "phpass", + "pbkdf2_digest", + "cta_pbkdf2_sha1", + "dlitz_pbkdf2_sha1", + "scram", + "bsd_nthash" + ], + "title": "Encrypt", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "private": { + "default": true, + "title": "Private", + "type": "boolean" + }, + "prompt": { + "title": "Prompt", + "type": "string" + }, + "salt_size": { + "default": 8, + "title": "Salt Size", + "type": "integer" + }, + "unsafe": { + "default": false, + "markdownDescription": "See [unsafe](https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html#allowing-special-characters-in-vars-prompt-values)", + "title": "Unsafe", + "type": "boolean" + } + }, + "required": ["name", "prompt"], + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": [], + "title": "Ansible Schemas Bundle 22.4", + "type": ["array", "object"] +} diff --git a/src/ansiblelint/schemas/changelog.json b/src/ansiblelint/schemas/changelog.json new file mode 100644 index 0000000..c243700 --- /dev/null +++ b/src/ansiblelint/schemas/changelog.json @@ -0,0 +1,262 @@ +{ + "$defs": { + "plugin-descriptions": { + "items": { + "properties": { + "description": { + "markdownDescription": "Value of `short_description` from plugin `DOCUMENTATION`.", + "title": "Description", + "type": "string" + }, + "name": { + "markdownDescription": "It must not be the FQCN, but the name inside the collection.", + "pattern": "[a-zA-Z0-9_]+", + "title": "Name", + "type": "string" + }, + "namespace": { + "type": "null" + } + }, + "type": "object" + }, + "type": "array" + }, + "release": { + "additionalProperties": false, + "properties": { + "changes": { + "additionalProperties": true, + "properties": { + "breaking_changes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "bugfixes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "deprecated_features": { + "items": { + "type": "string" + }, + "type": "array" + }, + "known_issues": { + "items": { + "type": "string" + }, + "type": "array" + }, + "major_changes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "minor_changes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "release_summary": { + "markdownDescription": "This must be valid [reStructuredText](https://en.wikipedia.org/wiki/ReStructuredText).", + "title": "Release Summary", + "type": "string" + }, + "removed_features": { + "items": { + "type": "string" + }, + "type": "array" + }, + "security_fixes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "trivial": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "codename": { + "type": "string" + }, + "fragments": { + "items": { + "type": "string" + }, + "markdownDescription": "List of strings representing filenames of changelog framents.", + "type": "array" + }, + "modules": { + "items": { + "properties": { + "description": { + "markdownDescription": "Value of `short_description` from plugin `DOCUMENTATION`.", + "title": "Description", + "type": "string" + }, + "name": { + "markdownDescription": "It must not be the FQCN, but the name inside the collection.", + "pattern": "[a-zA-Z0-9_]+", + "title": "Short module name", + "type": "string" + }, + "namespace": { + "markdownDescription": "Must be `''` for modules directly in `plugins/modules/`, or the dot-separated list of directories the module is in inside the `plugins/modules/` directory. The namespace is used to group new modules by their namespace inside the collection.", + "title": "Namespace", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "objects": { + "additionalProperties": false, + "properties": { + "playbook": { + "items": { + "properties": { + "description": { + "markdownDescription": "A short description of what the playbook does.", + "title": "Description", + "type": "string" + }, + "name": { + "markdownDescription": "It must not be the FQCN, but the name inside the collection.", + "pattern": "[a-zA-Z0-9_]+", + "title": "Short playbook name", + "type": "string" + }, + "namespace": { + "type": "null" + } + }, + "type": "object" + }, + "type": "array" + }, + "role": { + "items": { + "properties": { + "description": { + "markdownDescription": "Value of `short_description` from role's argument spec.", + "title": "Description", + "type": "string" + }, + "name": { + "markdownDescription": "It must not be the FQCN, but the name inside the collection.", + "pattern": "[a-zA-Z0-9_]+", + "title": "Short role name", + "type": "string" + }, + "namespace": { + "type": "null" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "plugins": { + "additionalProperties": false, + "properties": { + "become": { + "$ref": "#/$defs/plugin-descriptions" + }, + "cache": { + "$ref": "#/$defs/plugin-descriptions" + }, + "callback": { + "$ref": "#/$defs/plugin-descriptions" + }, + "cliconf": { + "$ref": "#/$defs/plugin-descriptions" + }, + "connection": { + "$ref": "#/$defs/plugin-descriptions" + }, + "filter": { + "$ref": "#/$defs/plugin-descriptions" + }, + "httpapi": { + "$ref": "#/$defs/plugin-descriptions" + }, + "inventory": { + "$ref": "#/$defs/plugin-descriptions" + }, + "lookup": { + "$ref": "#/$defs/plugin-descriptions" + }, + "netconf": { + "$ref": "#/$defs/plugin-descriptions" + }, + "shell": { + "$ref": "#/$defs/plugin-descriptions" + }, + "strategy": { + "$ref": "#/$defs/plugin-descriptions" + }, + "test": { + "$ref": "#/$defs/plugin-descriptions" + }, + "vars": { + "$ref": "#/$defs/plugin-descriptions" + } + }, + "type": "object" + }, + "release_date": { + "format": "date", + "markdownDescription": "Use ISO-8601 date format, like 2020-12-31", + "pattern": "\\d\\d\\d\\d-\\d\\d-\\d\\d", + "title": "Date of the release.", + "type": "string" + } + }, + "type": "object" + }, + "semver": { + "pattern": "\\d+.\\d+.\\d+.*", + "title": "Version string following SemVer specification.", + "type": ["string", "null"] + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/changelog.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": ["changelogs/changelog.yaml"], + "markdownDescription": "Antsibull Changelog Schema is based on [changelog.yaml-format.md](https://github.com/ansible-community/antsibull-changelog/blob/main/docs/changelog.yaml-format.md).", + "properties": { + "ancestor": { + "$ref": "#/$defs/semver" + }, + "releases": { + "patternProperties": { + "\\d+.\\d+.\\d+.*": { + "$ref": "#/$defs/release", + "type": "object" + } + }, + "type": "object" + } + }, + "title": "Antsibull Changelog Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/execution-environment.json b/src/ansiblelint/schemas/execution-environment.json new file mode 100644 index 0000000..4720a93 --- /dev/null +++ b/src/ansiblelint/schemas/execution-environment.json @@ -0,0 +1,309 @@ +{ + "$defs": { + "TYPE_DictOrStringOrListOfStrings": { + "anyOf": [ + { "type": "object" }, + { "type": "string" }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "TYPE_StringOrListOfStrings": { + "anyOf": [ + { "type": "string" }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "v1": { + "additionalProperties": false, + "properties": { + "additional_build_steps": { + "properties": { + "append": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "prepend": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + } + }, + "title": "Commands to append or prepend to container build process.", + "type": "object" + }, + "ansible_config": { + "examples": ["ansible.cfg"], + "title": "Ansible configuration file", + "type": "string" + }, + "build_arg_defaults": { + "additionalProperties": true, + "properties": { + "EE_BASE_IMAGE": { + "type": "string" + } + }, + "type": "object" + }, + "dependencies": { + "description": "Allows adding system, python or galaxy dependencies.", + "properties": { + "galaxy": { + "examples": ["requirements.yml"], + "markdownDescription": "Example `requirements.yml`", + "title": "Optional galaxy file", + "type": "string" + }, + "python": { + "examples": ["requirements.txt"], + "markdownDescription": "Example `requirements.txt`", + "title": "Optional python package dependencies", + "type": "string" + }, + "system": { + "examples": ["bindep.txt"], + "markdownDescription": "Example `bindep.txt`", + "title": "Optional system dependencies using bindep format", + "type": "string" + } + }, + "title": "Dependencies", + "type": "object" + }, + "version": { + "enum": [1], + "title": "Version", + "type": "integer" + } + }, + "required": ["version", "dependencies"], + "title": "Ansible Execution Environment Schema v1", + "type": "object" + }, + "v3": { + "additionalProperties": false, + "properties": { + "additional_build_files": { + "description": "Describes files to add to the build context", + "items": { + "additionalProperties": false, + "properties": { + "dest": { + "description": "Relative subdirectory under build context to place file", + "type": "string" + }, + "src": { + "description": "File to add to build context", + "type": "string" + } + }, + "required": ["src", "dest"], + "type": "object" + }, + "type": "array" + }, + "additional_build_steps": { + "properties": { + "append_base": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "append_builder": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "append_final": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "append_galaxy": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "prepend_base": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "prepend_builder": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "prepend_final": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + }, + "prepend_galaxy": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["RUN cat /etc/os-release"] + } + }, + "title": "Commands to append or prepend to container build process.", + "type": "object" + }, + "build_arg_defaults": { + "additionalProperties": false, + "properties": { + "ANSIBLE_GALAXY_CLI_COLLECTION_OPTS": { + "type": "string" + }, + "ANSIBLE_GALAXY_CLI_ROLE_OPTS": { + "type": "string" + }, + "PKGMGR_PRESERVE_CACHE": { + "type": "string" + } + }, + "type": "object" + }, + "dependencies": { + "description": "Allows adding system, python or galaxy dependencies.", + "properties": { + "ansible_core": { + "additionalProperties": false, + "description": "Ansible package installation", + "oneOf": [{ "required": ["package_pip"] }], + "properties": { + "package_pip": { + "description": "Ansible package to install via pip", + "type": "string" + } + }, + "type": "object" + }, + "ansible_runner": { + "additionalProperties": false, + "description": "Ansible Runner package installation", + "oneOf": [{ "required": ["package_pip"] }], + "properties": { + "package_pip": { + "description": "Ansible Runner package to install via pip", + "type": "string" + } + }, + "type": "object" + }, + "galaxy": { + "$ref": "#/$defs/TYPE_DictOrStringOrListOfStrings", + "examples": ["requirements.yml"], + "markdownDescription": "Example `requirements.yml`", + "title": "Optional galaxy file" + }, + "python": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["requirements.txt"], + "markdownDescription": "Example `requirements.txt`", + "title": "Optional python package dependencies" + }, + "python_interpreter": { + "additionalProperties": false, + "description": "Python package name and path", + "properties": { + "package_system": { + "description": "The python package to install via system package manager", + "type": "string" + }, + "python_path": { + "description": "Path to the python interpreter", + "type": "string" + } + }, + "type": "object" + }, + "system": { + "$ref": "#/$defs/TYPE_StringOrListOfStrings", + "examples": ["bindep.txt"], + "markdownDescription": "Example `bindep.txt`", + "title": "Optional system dependencies using bindep format" + } + }, + "title": "Dependencies", + "type": "object" + }, + "images": { + "additionalProperties": false, + "properties": { + "base_image": { + "name": { + "examples": [ + "registry.redhat.io/ansible-automation-platform-21/ee-minimal-rhel8:latest" + ], + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "options": { + "additionalProperties": false, + "description": "Options that effect runtime behavior", + "properties": { + "container_init": { + "additionalProperties": false, + "description": "Customize container startup behavior", + "properties": { + "cmd": { + "description": "literal value for CMD Containerfile directive", + "type": "string" + }, + "entrypoint": { + "description": "literal value for ENTRYPOINT Containerfile directive", + "type": "string" + }, + "package_pip": { + "description": "package to install via pip for entrypoint support", + "type": "string" + } + }, + "type": "object" + }, + "package_manager_path": { + "description": "Path to the system package manager to use", + "type": "string" + }, + "relax_passwd_permissions": { + "description": "allows GID0 write access to /etc/passwd; currently necessary for many uses", + "type": "boolean" + }, + "skip_ansible_check": { + "description": "Disables the check for Ansible/Runner in final image", + "type": "boolean" + }, + "user": { + "description": "Sets the username or UID", + "type": "string" + }, + "workdir": { + "description": "Default working directory, also often the homedir for ephemeral UIDs", + "type": ["string", "null"] + } + }, + "type": "object" + }, + "version": { + "enum": [3], + "title": "Version", + "type": "integer" + } + }, + "required": ["version", "dependencies"], + "title": "Ansible Execution Environment Schema v3", + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/execution-environment.json", + "$schema": "http://json-schema.org/draft-07/schema", + "description": "See \nV1: https://docs.ansible.com/automation-controller/latest/html/userguide/ee_reference.html\nV3: https://ansible-builder.readthedocs.io/en/latest/definition/", + "examples": ["execution-environment.yml"], + "oneOf": [{ "$ref": "#/$defs/v3" }, { "$ref": "#/$defs/v1" }], + "title": "Ansible Execution Environment Schema v1/v3" +} diff --git a/src/ansiblelint/schemas/galaxy.json b/src/ansiblelint/schemas/galaxy.json new file mode 100644 index 0000000..6381f28 --- /dev/null +++ b/src/ansiblelint/schemas/galaxy.json @@ -0,0 +1,643 @@ +{ + "$defs": { + "CollectionVersionConstraintModel": { + "additionalProperties": false, + "title": "CollectionVersionConstraintModel", + "type": "string" + }, + "SPDXLicense": { + "$ref": "#/$defs/SPDXLicenseEnum", + "title": "SPDXLicense" + }, + "SPDXLicenseEnum": { + "description": "An enumeration.", + "enum": [ + "0BSD", + "AAL", + "ADSL", + "AFL-1.1", + "AFL-1.2", + "AFL-2.0", + "AFL-2.1", + "AFL-3.0", + "AGPL-1.0-only", + "AGPL-1.0-or-later", + "AGPL-3.0-only", + "AGPL-3.0-or-later", + "AMDPLPA", + "AML", + "AMPAS", + "ANTLR-PD", + "ANTLR-PD-fallback", + "APAFML", + "APL-1.0", + "APSL-1.0", + "APSL-1.1", + "APSL-1.2", + "APSL-2.0", + "Abstyles", + "AdaCore-doc", + "Adobe-2006", + "Adobe-Glyph", + "Afmparse", + "Aladdin", + "Apache-1.0", + "Apache-1.1", + "Apache-2.0", + "App-s2p", + "Arphic-1999", + "Artistic-1.0", + "Artistic-1.0-Perl", + "Artistic-1.0-cl8", + "Artistic-2.0", + "BSD-1-Clause", + "BSD-2-Clause", + "BSD-2-Clause-Patent", + "BSD-2-Clause-Views", + "BSD-3-Clause", + "BSD-3-Clause-Attribution", + "BSD-3-Clause-Clear", + "BSD-3-Clause-LBNL", + "BSD-3-Clause-Modification", + "BSD-3-Clause-No-Military-License", + "BSD-3-Clause-No-Nuclear-License", + "BSD-3-Clause-No-Nuclear-License-2014", + "BSD-3-Clause-No-Nuclear-Warranty", + "BSD-3-Clause-Open-MPI", + "BSD-4-Clause", + "BSD-4-Clause-Shortened", + "BSD-4-Clause-UC", + "BSD-4.3RENO", + "BSD-4.3TAHOE", + "BSD-Advertising-Acknowledgement", + "BSD-Attribution-HPND-disclaimer", + "BSD-Protection", + "BSD-Source-Code", + "BSL-1.0", + "BUSL-1.1", + "Baekmuk", + "Bahyph", + "Barr", + "Beerware", + "BitTorrent-1.0", + "BitTorrent-1.1", + "Bitstream-Charter", + "Bitstream-Vera", + "BlueOak-1.0.0", + "Borceux", + "Brian-Gladman-3-Clause", + "C-UDA-1.0", + "CAL-1.0", + "CAL-1.0-Combined-Work-Exception", + "CATOSL-1.1", + "CC-BY-1.0", + "CC-BY-2.0", + "CC-BY-2.5", + "CC-BY-2.5-AU", + "CC-BY-3.0", + "CC-BY-3.0-AT", + "CC-BY-3.0-DE", + "CC-BY-3.0-IGO", + "CC-BY-3.0-NL", + "CC-BY-3.0-US", + "CC-BY-4.0", + "CC-BY-NC-1.0", + "CC-BY-NC-2.0", + "CC-BY-NC-2.5", + "CC-BY-NC-3.0", + "CC-BY-NC-3.0-DE", + "CC-BY-NC-4.0", + "CC-BY-NC-ND-1.0", + "CC-BY-NC-ND-2.0", + "CC-BY-NC-ND-2.5", + "CC-BY-NC-ND-3.0", + "CC-BY-NC-ND-3.0-DE", + "CC-BY-NC-ND-3.0-IGO", + "CC-BY-NC-ND-4.0", + "CC-BY-NC-SA-1.0", + "CC-BY-NC-SA-2.0", + "CC-BY-NC-SA-2.0-DE", + "CC-BY-NC-SA-2.0-FR", + "CC-BY-NC-SA-2.0-UK", + "CC-BY-NC-SA-2.5", + "CC-BY-NC-SA-3.0", + "CC-BY-NC-SA-3.0-DE", + "CC-BY-NC-SA-3.0-IGO", + "CC-BY-NC-SA-4.0", + "CC-BY-ND-1.0", + "CC-BY-ND-2.0", + "CC-BY-ND-2.5", + "CC-BY-ND-3.0", + "CC-BY-ND-3.0-DE", + "CC-BY-ND-4.0", + "CC-BY-SA-1.0", + "CC-BY-SA-2.0", + "CC-BY-SA-2.0-UK", + "CC-BY-SA-2.1-JP", + "CC-BY-SA-2.5", + "CC-BY-SA-3.0", + "CC-BY-SA-3.0-AT", + "CC-BY-SA-3.0-DE", + "CC-BY-SA-4.0", + "CC-PDDC", + "CC0-1.0", + "CDDL-1.0", + "CDDL-1.1", + "CDL-1.0", + "CDLA-Permissive-1.0", + "CDLA-Permissive-2.0", + "CDLA-Sharing-1.0", + "CECILL-1.0", + "CECILL-1.1", + "CECILL-2.0", + "CECILL-2.1", + "CECILL-B", + "CECILL-C", + "CERN-OHL-1.1", + "CERN-OHL-1.2", + "CERN-OHL-P-2.0", + "CERN-OHL-S-2.0", + "CERN-OHL-W-2.0", + "CFITSIO", + "CMU-Mach", + "CNRI-Jython", + "CNRI-Python", + "CNRI-Python-GPL-Compatible", + "COIL-1.0", + "CPAL-1.0", + "CPL-1.0", + "CPOL-1.02", + "CUA-OPL-1.0", + "Caldera", + "ClArtistic", + "Clips", + "Community-Spec-1.0", + "Condor-1.1", + "Cornell-Lossless-JPEG", + "Crossword", + "CrystalStacker", + "Cube", + "D-FSL-1.0", + "DL-DE-BY-2.0", + "DOC", + "DRL-1.0", + "DSDP", + "Dotseqn", + "ECL-1.0", + "ECL-2.0", + "EFL-1.0", + "EFL-2.0", + "EPICS", + "EPL-1.0", + "EPL-2.0", + "EUDatagrid", + "EUPL-1.0", + "EUPL-1.1", + "EUPL-1.2", + "Elastic-2.0", + "Entessa", + "ErlPL-1.1", + "Eurosym", + "FDK-AAC", + "FSFAP", + "FSFUL", + "FSFULLR", + "FSFULLRWD", + "FTL", + "Fair", + "Frameworx-1.0", + "FreeBSD-DOC", + "FreeImage", + "GD", + "GFDL-1.1-invariants-only", + "GFDL-1.1-invariants-or-later", + "GFDL-1.1-no-invariants-only", + "GFDL-1.1-no-invariants-or-later", + "GFDL-1.1-only", + "GFDL-1.1-or-later", + "GFDL-1.2-invariants-only", + "GFDL-1.2-invariants-or-later", + "GFDL-1.2-no-invariants-only", + "GFDL-1.2-no-invariants-or-later", + "GFDL-1.2-only", + "GFDL-1.2-or-later", + "GFDL-1.3-invariants-only", + "GFDL-1.3-invariants-or-later", + "GFDL-1.3-no-invariants-only", + "GFDL-1.3-no-invariants-or-later", + "GFDL-1.3-only", + "GFDL-1.3-or-later", + "GL2PS", + "GLWTPL", + "GPL-1.0-only", + "GPL-1.0-or-later", + "GPL-2.0-only", + "GPL-2.0-or-later", + "GPL-3.0-only", + "GPL-3.0-or-later", + "Giftware", + "Glide", + "Glulxe", + "Graphics-Gems", + "HP-1986", + "HPND", + "HPND-Markus-Kuhn", + "HPND-export-US", + "HPND-sell-variant", + "HPND-sell-variant-MIT-disclaimer", + "HTMLTIDY", + "HaskellReport", + "Hippocratic-2.1", + "IBM-pibs", + "ICU", + "IEC-Code-Components-EULA", + "IJG", + "IJG-short", + "IPA", + "IPL-1.0", + "ISC", + "ImageMagick", + "Imlib2", + "Info-ZIP", + "Intel", + "Intel-ACPI", + "Interbase-1.0", + "JPL-image", + "JPNIC", + "JSON", + "Jam", + "JasPer-2.0", + "Kazlib", + "Knuth-CTAN", + "LAL-1.2", + "LAL-1.3", + "LGPL-2.0-only", + "LGPL-2.0-or-later", + "LGPL-2.1-only", + "LGPL-2.1-or-later", + "LGPL-3.0-only", + "LGPL-3.0-or-later", + "LGPLLR", + "LOOP", + "LPL-1.0", + "LPL-1.02", + "LPPL-1.0", + "LPPL-1.1", + "LPPL-1.2", + "LPPL-1.3a", + "LPPL-1.3c", + "LZMA-SDK-9.11-to-9.20", + "LZMA-SDK-9.22", + "Latex2e", + "Leptonica", + "LiLiQ-P-1.1", + "LiLiQ-R-1.1", + "LiLiQ-Rplus-1.1", + "Libpng", + "Linux-OpenIB", + "Linux-man-pages-copyleft", + "MIT", + "MIT-0", + "MIT-CMU", + "MIT-Modern-Variant", + "MIT-Wu", + "MIT-advertising", + "MIT-enna", + "MIT-feh", + "MIT-open-group", + "MITNFA", + "MPL-1.0", + "MPL-1.1", + "MPL-2.0", + "MPL-2.0-no-copyleft-exception", + "MS-LPL", + "MS-PL", + "MS-RL", + "MTLL", + "MakeIndex", + "Martin-Birgmeier", + "Minpack", + "MirOS", + "Motosoto", + "MulanPSL-1.0", + "MulanPSL-2.0", + "Multics", + "Mup", + "NAIST-2003", + "NASA-1.3", + "NBPL-1.0", + "NCGL-UK-2.0", + "NCSA", + "NGPL", + "NICTA-1.0", + "NIST-PD", + "NIST-PD-fallback", + "NLOD-1.0", + "NLOD-2.0", + "NLPL", + "NOSL", + "NPL-1.0", + "NPL-1.1", + "NPOSL-3.0", + "NRL", + "NTP", + "NTP-0", + "Naumen", + "Net-SNMP", + "NetCDF", + "Newsletr", + "Nokia", + "Noweb", + "O-UDA-1.0", + "OCCT-PL", + "OCLC-2.0", + "ODC-By-1.0", + "ODbL-1.0", + "OFFIS", + "OFL-1.0", + "OFL-1.0-RFN", + "OFL-1.0-no-RFN", + "OFL-1.1", + "OFL-1.1-RFN", + "OFL-1.1-no-RFN", + "OGC-1.0", + "OGDL-Taiwan-1.0", + "OGL-Canada-2.0", + "OGL-UK-1.0", + "OGL-UK-2.0", + "OGL-UK-3.0", + "OGTSL", + "OLDAP-1.1", + "OLDAP-1.2", + "OLDAP-1.3", + "OLDAP-1.4", + "OLDAP-2.0", + "OLDAP-2.0.1", + "OLDAP-2.1", + "OLDAP-2.2", + "OLDAP-2.2.1", + "OLDAP-2.2.2", + "OLDAP-2.3", + "OLDAP-2.4", + "OLDAP-2.5", + "OLDAP-2.6", + "OLDAP-2.7", + "OLDAP-2.8", + "OML", + "OPL-1.0", + "OPUBL-1.0", + "OSET-PL-2.1", + "OSL-1.0", + "OSL-1.1", + "OSL-2.0", + "OSL-2.1", + "OSL-3.0", + "OpenPBS-2.3", + "OpenSSL", + "PDDL-1.0", + "PHP-3.0", + "PHP-3.01", + "PSF-2.0", + "Parity-6.0.0", + "Parity-7.0.0", + "Plexus", + "PolyForm-Noncommercial-1.0.0", + "PolyForm-Small-Business-1.0.0", + "PostgreSQL", + "Python-2.0", + "Python-2.0.1", + "QPL-1.0", + "QPL-1.0-INRIA-2004", + "Qhull", + "RHeCos-1.1", + "RPL-1.1", + "RPL-1.5", + "RPSL-1.0", + "RSA-MD", + "RSCPL", + "Rdisc", + "Ruby", + "SAX-PD", + "SCEA", + "SGI-B-1.0", + "SGI-B-1.1", + "SGI-B-2.0", + "SHL-0.5", + "SHL-0.51", + "SISSL", + "SISSL-1.2", + "SMLNJ", + "SMPPL", + "SNIA", + "SPL-1.0", + "SSH-OpenSSH", + "SSH-short", + "SSPL-1.0", + "SWL", + "Saxpath", + "SchemeReport", + "Sendmail", + "Sendmail-8.23", + "SimPL-2.0", + "Sleepycat", + "Spencer-86", + "Spencer-94", + "Spencer-99", + "SugarCRM-1.1.3", + "SunPro", + "Symlinks", + "TAPR-OHL-1.0", + "TCL", + "TCP-wrappers", + "TMate", + "TORQUE-1.1", + "TOSL", + "TPDL", + "TPL-1.0", + "TTWL", + "TU-Berlin-1.0", + "TU-Berlin-2.0", + "UCAR", + "UCL-1.0", + "UPL-1.0", + "Unicode-DFS-2015", + "Unicode-DFS-2016", + "Unicode-TOU", + "Unlicense", + "VOSTROM", + "VSL-1.0", + "Vim", + "W3C", + "W3C-19980720", + "W3C-20150513", + "WTFPL", + "Watcom-1.0", + "Wsuipa", + "X11", + "X11-distribute-modifications-variant", + "XFree86-1.1", + "XSkat", + "Xerox", + "Xnet", + "YPL-1.0", + "YPL-1.1", + "ZPL-1.1", + "ZPL-2.0", + "ZPL-2.1", + "Zed", + "Zend-2.0", + "Zimbra-1.3", + "Zimbra-1.4", + "Zlib", + "blessing", + "bzip2-1.0.6", + "checkmk", + "copyleft-next-0.3.0", + "copyleft-next-0.3.1", + "curl", + "diffmark", + "dvipdfm", + "eGenix", + "etalab-2.0", + "gSOAP-1.3b", + "gnuplot", + "iMatix", + "libpng-2.0", + "libselinux-1.0", + "libtiff", + "libutil-David-Nugent", + "mpi-permissive", + "mpich2", + "mplus", + "psfrag", + "psutils", + "snprintf", + "w3m", + "xinetd", + "xlock", + "xpp", + "zlib-acknowledgement" + ], + "title": "SPDXLicenseEnum" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/galaxy.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": ["galaxy.yml"], + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "build_ignore": { + "items": { + "type": "string" + }, + "title": "Build Ignore", + "type": "array" + }, + "dependencies": { + "additionalProperties": { + "$ref": "#/$defs/CollectionVersionConstraintModel" + }, + "title": "Dependencies", + "type": "object" + }, + "description": { + "title": "Description", + "type": "string" + }, + "documentation": { + "title": "Documentation", + "type": "string" + }, + "homepage": { + "title": "Homepage", + "type": "string" + }, + "issues": { + "title": "Issues", + "type": "string" + }, + "license": { + "items": { + "$ref": "#/$defs/SPDXLicense" + }, + "title": "License", + "type": "array" + }, + "license_file": { + "title": "License File", + "type": "string" + }, + "manifest": { + "additionalProperties": false, + "markdownDescription": "A dict controlling use of manifest directives used in building the collection artifact.\nThe key directives is a list of MANIFEST.in style directives\nThe key omit_default_directives is a boolean that controls whether the default directives are used.\nMutually exclusive with build_ignore.", + "properties": { + "directives": { + "items": { + "type": "string" + }, + "title": "Directives", + "type": "array" + }, + "omit_default_directives": { + "title": "Omit Default Directives", + "type": "boolean" + } + }, + "title": "Manifest", + "type": "object" + }, + "name": { + "minLength": 2, + "pattern": "^[a-z][a-z0-9_]+$", + "title": "Name", + "type": "string" + }, + "namespace": { + "minLength": 2, + "pattern": "^[a-z][a-z0-9_]+$", + "title": "Namespace", + "type": "string" + }, + "readme": { + "markdownDescription": "The path to the Markdown (.md) readme file. This path is relative to the root of the collection.\nSee [metadata structure](https://docs.ansible.com/ansible/latest/dev_guide/collections_galaxy_meta.html)", + "title": "Readme", + "type": "string" + }, + "repository": { + "title": "Repository", + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "title": "Tags", + "type": "array" + }, + "version": { + "markdownDescription": "Version must use [SemVer](https://semver.org/) format, which is more restrictive than [PEP-440](https://peps.python.org/pep-0440/). For example `1.0.0-rc1` is valid but `1.0.0rc` is not.", + "minLength": 5, + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "title": "Version", + "type": "string" + } + }, + "required": [ + "namespace", + "name", + "version", + "readme", + "authors", + "description", + "repository" + ], + "title": "Ansible galaxy.yml Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/inventory.json b/src/ansiblelint/schemas/inventory.json new file mode 100644 index 0000000..80333ce --- /dev/null +++ b/src/ansiblelint/schemas/inventory.json @@ -0,0 +1,66 @@ +{ + "$defs": { + "group": { + "properties": { + "children": { + "patternProperties": { + "[a-zA-Z-_0-9]": { + "$ref": "#/$defs/group" + } + } + }, + "hosts": { + "patternProperties": { + "[a-zA-Z.-_0-9]": { + "type": ["object", "null"] + } + }, + "type": ["object", "string"] + }, + "vars": { + "type": "object" + } + }, + "type": ["object", "null"] + }, + "special-group": { + "additionalProperties": false, + "properties": { + "children": { + "type": ["object", "null"] + }, + "groups": { + "type": ["object", "null"] + }, + "hosts": { + "type": ["object", "null"] + }, + "vars": { + "type": ["object", "null"] + } + }, + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": true, + "description": "Ansible Inventory Schema", + "examples": [ + "inventory.yaml", + "inventory.yml", + "inventory/*.yml", + "inventory/*.yaml" + ], + "markdownDescription": "All keys at top levels are groups with `all` and `ungrouped` having a special meaning.\n\nSee [How to build your inventory](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html)", + "properties": { + "all": { + "$ref": "#/$defs/special-group" + }, + "ungrouped": { + "$ref": "#/$defs/group" + } + }, + "title": "Ansible Inventory Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/main.py b/src/ansiblelint/schemas/main.py new file mode 100644 index 0000000..590aea3 --- /dev/null +++ b/src/ansiblelint/schemas/main.py @@ -0,0 +1,37 @@ +"""Module containing cached JSON schemas.""" +from __future__ import annotations + +import json +import logging +from typing import TYPE_CHECKING + +import jsonschema +import yaml +from jsonschema.exceptions import ValidationError + +from ansiblelint.loaders import yaml_load_safe +from ansiblelint.schemas.__main__ import JSON_SCHEMAS, _schema_cache + +_logger = logging.getLogger(__package__) + +if TYPE_CHECKING: + from ansiblelint.file_utils import Lintable + + +def validate_file_schema(file: Lintable) -> list[str]: + """Return list of JSON validation errors found.""" + if file.kind not in JSON_SCHEMAS: + return [f"Unable to find JSON Schema '{file.kind}' for '{file.path}' file."] + try: + # convert yaml to json (keys are converted to strings) + yaml_data = yaml_load_safe(file.content) + json_data = json.loads(json.dumps(yaml_data)) + jsonschema.validate( + instance=json_data, + schema=_schema_cache[file.kind], + ) + except yaml.constructor.ConstructorError as exc: + return [f"Failed to load YAML file '{file.path}': {exc.problem}"] + except ValidationError as exc: + return [exc.message] + return [] diff --git a/src/ansiblelint/schemas/meta-runtime.json b/src/ansiblelint/schemas/meta-runtime.json new file mode 100644 index 0000000..617647f --- /dev/null +++ b/src/ansiblelint/schemas/meta-runtime.json @@ -0,0 +1,82 @@ +{ + "$defs": { + "ActionGroup": { + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/$defs/Metadata" + } + ] + }, + "type": "array" + }, + "Metadata": { + "properties": { + "metadata": { + "properties": { + "extend_group": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "Redirect": { + "properties": { + "redirect": { + "type": "string" + } + }, + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta-runtime.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "description": "See https://docs.ansible.com/ansible/devel/dev_guide/developing_collections_structure.html#meta-directory", + "examples": ["**/meta/runtime.yml"], + "properties": { + "action_groups": { + "additionalProperties": { + "$ref": "#/$defs/ActionGroup" + }, + "description": "A mapping of groups and the list of action plugin and module names they contain. They may also have a special ‘metadata’ dictionary in the list, which can be used to include actions from other groups.", + "title": "Action Groups", + "type": "object" + }, + "import_redirection": { + "additionalProperties": { + "$ref": "#/$defs/Redirect" + }, + "description": "A mapping of names for Python import statements and their redirected locations.", + "title": "Import Redirection", + "type": "object" + }, + "plugin_routing": { + "markdownDescription": "Content in a collection that Ansible needs to load from another location or that has been deprecated/removed. The top level keys of plugin_routing are types of plugins, with individual plugin names as subkeys. To define a new location for a plugin, set the redirect field to another name. To deprecate a plugin, use the deprecation field to provide a custom warning message and the removal version or date. If the plugin has been renamed or moved to a new location, the redirect field should also be provided. If a plugin is being removed entirely, tombstone can be used for the fatal error message and removal version or date.", + "properties": { + "inventory": {}, + "module_utils": {}, + "modules": {} + }, + "title": "Plugin Routing", + "type": "object" + }, + "requires_ansible": { + "examples": [">=2.10,<2.11"], + "pattern": "^[^\\s]*$", + "title": "The version of Ansible Core (ansible-core) required to use the collection. Multiple versions can be separated with a comma.", + "type": "string" + } + }, + "title": "Ansible Meta Runtime Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/meta.json b/src/ansiblelint/schemas/meta.json new file mode 100644 index 0000000..384d113 --- /dev/null +++ b/src/ansiblelint/schemas/meta.json @@ -0,0 +1,1473 @@ +{ + "$defs": { + "AIXPlatformModel": { + "properties": { + "name": { + "const": "AIX", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["6.1", "7.1", "7.2", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "AIXPlatformModel", + "type": "object" + }, + "AlpinePlatformModel": { + "properties": { + "name": { + "const": "Alpine", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "AlpinePlatformModel", + "type": "object" + }, + "AmazonLinuxPlatformModel": { + "properties": { + "name": { + "const": "Amazon Linux", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all", "1", "2", "2023"], + "type": "string" + }, + "type": "array" + } + }, + "title": "Amazon Linux 2PlatformModel", + "type": "object" + }, + "AmazonPlatformModel": { + "properties": { + "name": { + "const": "Amazon", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "2013.03", + "2013.09", + "2014.03", + "2014.09", + "2015.03", + "2015.09", + "2016.03", + "2016.09", + "2017.03", + "2017.09", + "2017.12", + "2018.03", + "Candidate", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "AmazonPlatformModel", + "type": "object" + }, + "ArchLinuxPlatformModel": { + "properties": { + "name": { + "const": "ArchLinux", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "ArchLinuxPlatformModel", + "type": "object" + }, + "ClearLinuxPlatformModel": { + "properties": { + "name": { + "const": "ClearLinux", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "ClearLinuxPlatformModel", + "type": "object" + }, + "CumulusPlatformModel": { + "properties": { + "name": { + "const": "Cumulus", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["2.5", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "CumulusPlatformModel", + "type": "object" + }, + "DebianPlatformModel": { + "properties": { + "name": { + "const": "Debian", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "bookworm", + "bullseye", + "buster", + "etch", + "jessie", + "lenny", + "sid", + "squeeze", + "stretch", + "wheezy", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "DebianPlatformModel", + "type": "object" + }, + "DellOSPlatformModel": { + "properties": { + "name": { + "const": "DellOS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["10", "6", "9", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "DellOSPlatformModel", + "type": "object" + }, + "DependencyModel": { + "additionalProperties": true, + "anyOf": [ + { + "required": ["role"] + }, + { + "required": ["src"] + }, + { + "required": ["name"] + } + ], + "markdownDescription": "See https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html#role-dependencies and https://github.com/ansible/ansible/blob/devel/lib/ansible/playbook/role/metadata.py#L79\n\nOther keys are treated as role [parameters](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#passing-different-parameters).", + "properties": { + "become": { + "title": "Become", + "type": "boolean" + }, + "name": { + "title": "Name", + "type": "string" + }, + "role": { + "title": "Role", + "type": "string" + }, + "scm": { + "enum": ["hg", "git"], + "title": "Scm", + "type": "string" + }, + "src": { + "title": "Src", + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "title": "Tags", + "type": ["array", "string"] + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "version": { + "title": "Version", + "type": "string" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "title": "Dependency entry", + "type": "object" + }, + "DevuanPlatformModel": { + "properties": { + "name": { + "const": "Devuan", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["ascii", "beowulf", "ceres", "jessie", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "DevuanPlatformModel", + "type": "object" + }, + "DragonFlyBSDPlatformModel": { + "properties": { + "name": { + "const": "DragonFlyBSD", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["5.2", "5.4", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "DragonFlyBSDPlatformModel", + "type": "object" + }, + "ELPlatformModel": { + "properties": { + "name": { + "const": "EL", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["5", "6", "7", "8", "9", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "ELPlatformModel", + "type": "object" + }, + "FedoraPlatformModel": { + "properties": { + "name": { + "const": "Fedora", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "FedoraPlatformModel", + "type": "object" + }, + "FreeBSDPlatformModel": { + "properties": { + "name": { + "const": "FreeBSD", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "10.0", + "10.1", + "10.2", + "10.3", + "10.4", + "11.0", + "11.1", + "11.2", + "11.3", + "11.4", + "12.0", + "12.1", + "12.2", + "13.0", + "13.1", + "13.2", + "14.0", + "8.0", + "8.1", + "8.2", + "8.3", + "8.4", + "9.0", + "9.1", + "9.2", + "9.3", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "FreeBSDPlatformModel", + "type": "object" + }, + "GalaxyInfoModel": { + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "standalone": { + "const": true + } + } + }, + "then": { + "$comment": "Standalone role, so we require several fields.", + "required": [ + "author", + "description", + "license", + "min_ansible_version" + ] + } + }, + { + "if": { + "properties": { + "standalone": { + "const": false + } + } + }, + "then": { + "$comment": "Collection roles do not use most galaxy fields.", + "not": { + "required": [ + "cloud_platforms", + "galaxy_tags", + "min_ansible_version", + "namespace", + "platforms", + "role_name", + "video_links" + ] + }, + "required": ["description"] + } + } + ], + "else": { + "$comment": "If standalone is false, then we have a collection role and only description is required", + "required": ["description"] + }, + "properties": { + "author": { + "title": "Author", + "type": "string" + }, + "cloud_platforms": { + "markdownDescription": "Only valid for old standalone roles." + }, + "company": { + "title": "Company", + "type": "string" + }, + "description": { + "title": "Description", + "type": "string" + }, + "galaxy_tags": { + "items": { + "type": "string" + }, + "markdownDescription": "See https://galaxy.ansible.com/docs/contributing/creating_role.html", + "title": "Galaxy Tags", + "type": "array" + }, + "github_branch": { + "markdownDescription": "Optionally specify the branch Galaxy will use when accessing the GitHub repo for this role", + "title": "GitHub Branch", + "type": "string" + }, + "issue_tracker_url": { + "title": "Issue Tracker Url", + "type": "string" + }, + "license": { + "title": "License", + "type": "string" + }, + "min_ansible_container_version": { + "title": "Min Ansible Container Version", + "type": "string" + }, + "min_ansible_version": { + "title": "Min Ansible Version", + "type": "string" + }, + "namespace": { + "markdownDescription": "Used by molecule and ansible-lint to compute FQRN for roles outside collections", + "minLength": 2, + "pattern": "^[a-z][a-z0-9_]+$", + "title": "Namespace Name", + "type": "string" + }, + "platforms": { + "$ref": "#/$defs/platforms" + }, + "role_name": { + "minLength": 2, + "pattern": "^[a-z][a-z0-9_]+$", + "title": "Role Name", + "type": "string" + }, + "standalone": { + "description": "Set to true for old standalone roles, or false for new collection roles.", + "title": "Standalone", + "type": "boolean" + }, + "video_links": { + "markdownDescription": "Only valid for old standalone roles.", + "type": "array" + } + }, + "title": "GalaxyInfoModel", + "type": "object" + }, + "GenericBSDPlatformModel": { + "properties": { + "name": { + "const": "GenericBSD", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "GenericBSDPlatformModel", + "type": "object" + }, + "GenericLinuxPlatformModel": { + "properties": { + "name": { + "const": "GenericLinux", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "GenericLinuxPlatformModel", + "type": "object" + }, + "GenericUNIXPlatformModel": { + "properties": { + "name": { + "const": "GenericUNIX", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "GenericUNIXPlatformModel", + "type": "object" + }, + "GentooPlatformModel": { + "properties": { + "name": { + "const": "Gentoo", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "GentooPlatformModel", + "type": "object" + }, + "HardenedBSDPlatformModel": { + "properties": { + "name": { + "const": "HardenedBSD", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["10", "11", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "HardenedBSDPlatformModel", + "type": "object" + }, + "IOSPlatformModel": { + "properties": { + "name": { + "const": "IOS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "IOSPlatformModel", + "type": "object" + }, + "JunosPlatformModel": { + "properties": { + "name": { + "const": "Junos", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "JunosPlatformModel", + "type": "object" + }, + "KaliPlatformModel": { + "properties": { + "name": { + "const": "Kali", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "2.0", + "2016", + "2017", + "2018", + "2019", + "2020", + "2021", + "2022", + "2023", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "KaliPlatformModel", + "type": "object" + }, + "MacOSXPlatformModel": { + "properties": { + "name": { + "const": "MacOSX", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "10.10", + "10.11", + "10.12", + "10.13", + "10.14", + "10.15", + "10.7", + "10.8", + "10.9", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "MacOSXPlatformModel", + "type": "object" + }, + "MageiaPlatformModel": { + "properties": { + "name": { + "const": "Mageia", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["7", "8", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "MageiaPlatformModel", + "type": "object" + }, + "NXOSPlatformModel": { + "properties": { + "name": { + "const": "NXOS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "NXOSPlatformModel", + "type": "object" + }, + "NetBSDPlatformModel": { + "properties": { + "name": { + "const": "NetBSD", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "8.0", + "8.1", + "8.2", + "9.0", + "9.1", + "9.2", + "9.3", + "10.0", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "NetBSDPlatformModel", + "type": "object" + }, + "OpenBSDPlatformModel": { + "properties": { + "name": { + "const": "OpenBSD", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "5.6", + "5.7", + "5.8", + "5.9", + "6.0", + "6.1", + "6.2", + "6.3", + "6.4", + "6.5", + "6.6", + "6.7", + "6.8", + "6.9", + "7.0", + "7.1", + "7.2", + "7.3", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "OpenBSDPlatformModel", + "type": "object" + }, + "OpenWrtPlatformModel": { + "properties": { + "name": { + "const": "OpenWrt", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["17.01", "18.06", "19.07", "21.02", "22.03", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "OpenWrtPlatformModel", + "type": "object" + }, + "OracleLinuxPlatformModel": { + "properties": { + "name": { + "const": "OracleLinux", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "7.0", + "7.1", + "7.2", + "7.3", + "7.4", + "7.5", + "7.6", + "7.7", + "7.8", + "7.9", + "8.0", + "8.1", + "8.2", + "8.3", + "8.4", + "8.5", + "8.6", + "8.7", + "8.8", + "9.0", + "9.1", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "OracleLinuxPlatformModel", + "type": "object" + }, + "PAN-OSPlatformModel": { + "properties": { + "name": { + "const": "PAN-OS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["7.1", "8.0", "8.1", "9.0", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "PAN-OSPlatformModel", + "type": "object" + }, + "SLESPlatformModel": { + "properties": { + "name": { + "const": "SLES", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "10SP3", + "10SP4", + "11", + "11SP1", + "11SP2", + "11SP3", + "11SP4", + "12", + "12SP1", + "12SP2", + "12SP3", + "12SP4", + "12SP5", + "15", + "15SP1", + "15SP2", + "15SP3", + "15SP4", + "15SP5", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "SLESPlatformModel", + "type": "object" + }, + "SmartOSPlatformModel": { + "properties": { + "name": { + "const": "SmartOS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "SmartOSPlatformModel", + "type": "object" + }, + "SolarisPlatformModel": { + "properties": { + "name": { + "const": "Solaris", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["10", "11.0", "11.1", "11.2", "11.3", "11.4", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "SolarisPlatformModel", + "type": "object" + }, + "SynologyPlatformModel": { + "properties": { + "name": { + "const": "Synology", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["6.0", "6.1", "6.2", "7.0", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "SynologyPlatformModel", + "type": "object" + }, + "TMOSPlatformModel": { + "properties": { + "name": { + "const": "TMOS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["12.1", "13.0", "13.1", "14.0", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "TMOSPlatformModel", + "type": "object" + }, + "UbuntuPlatformModel": { + "properties": { + "name": { + "const": "Ubuntu", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "artful", + "bionic", + "cosmic", + "cuttlefish", + "disco", + "eoan", + "focal", + "groovy", + "hirsute", + "impish", + "jammy", + "lucid", + "maverick", + "natty", + "oneiric", + "precise", + "quantal", + "raring", + "saucy", + "trusty", + "utopic", + "vivid", + "wily", + "xenial", + "yakkety", + "zesty", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "UbuntuPlatformModel", + "type": "object" + }, + "Void_LinuxPlatformModel": { + "properties": { + "name": { + "const": "Void Linux", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "Void LinuxPlatformModel", + "type": "object" + }, + "WindowsPlatformModel": { + "properties": { + "name": { + "const": "Windows", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "2008R2", + "2008x64", + "2008x86", + "2012", + "2012R2", + "2016", + "2019", + "2022", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "WindowsPlatformModel", + "type": "object" + }, + "aosPlatformModel": { + "properties": { + "name": { + "const": "aos", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "aosPlatformModel", + "type": "object" + }, + "collections": { + "items": { + "markdownDescription": "See [Using collections in roles](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html#using-collections-in-roles) and [collection naming conventions](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_in_groups.html#naming-conventions)", + "pattern": "^[a-z_]+\\.[a-z_]+$", + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "complex_conditional": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "eosPlatformModel": { + "properties": { + "name": { + "const": "eos", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "eosPlatformModel", + "type": "object" + }, + "macOSPlatformModel": { + "properties": { + "name": { + "const": "macOS", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "Big-Sur", + "Catalina", + "High-Sierra", + "Mojave", + "Monterey", + "Sierra", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "macOSPlatformModel", + "type": "object" + }, + "opensusePlatformModel": { + "properties": { + "name": { + "const": "opensuse", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": [ + "12.1", + "12.2", + "12.3", + "13.1", + "13.2", + "15.0", + "15.1", + "15.2", + "15.3", + "15.4", + "15.5", + "42.1", + "42.2", + "42.3", + "all" + ], + "type": "string" + }, + "type": "array" + } + }, + "title": "opensusePlatformModel", + "type": "object" + }, + "os10PlatformModel": { + "properties": { + "name": { + "const": "os10", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "os10PlatformModel", + "type": "object" + }, + "platforms": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/AIXPlatformModel" + }, + { + "$ref": "#/$defs/AlpinePlatformModel" + }, + { + "$ref": "#/$defs/AmazonPlatformModel" + }, + { + "$ref": "#/$defs/AmazonLinuxPlatformModel" + }, + { + "$ref": "#/$defs/aosPlatformModel" + }, + { + "$ref": "#/$defs/ArchLinuxPlatformModel" + }, + { + "$ref": "#/$defs/ClearLinuxPlatformModel" + }, + { + "$ref": "#/$defs/CumulusPlatformModel" + }, + { + "$ref": "#/$defs/NetBSDPlatformModel" + }, + { + "$ref": "#/$defs/DebianPlatformModel" + }, + { + "$ref": "#/$defs/DellOSPlatformModel" + }, + { + "$ref": "#/$defs/DevuanPlatformModel" + }, + { + "$ref": "#/$defs/DragonFlyBSDPlatformModel" + }, + { + "$ref": "#/$defs/ELPlatformModel" + }, + { + "$ref": "#/$defs/eosPlatformModel" + }, + { + "$ref": "#/$defs/FedoraPlatformModel" + }, + { + "$ref": "#/$defs/FreeBSDPlatformModel" + }, + { + "$ref": "#/$defs/GenericBSDPlatformModel" + }, + { + "$ref": "#/$defs/GenericLinuxPlatformModel" + }, + { + "$ref": "#/$defs/GenericUNIXPlatformModel" + }, + { + "$ref": "#/$defs/GentooPlatformModel" + }, + { + "$ref": "#/$defs/HardenedBSDPlatformModel" + }, + { + "$ref": "#/$defs/IOSPlatformModel" + }, + { + "$ref": "#/$defs/JunosPlatformModel" + }, + { + "$ref": "#/$defs/KaliPlatformModel" + }, + { + "$ref": "#/$defs/macOSPlatformModel" + }, + { + "$ref": "#/$defs/MacOSXPlatformModel" + }, + { + "$ref": "#/$defs/MageiaPlatformModel" + }, + { + "$ref": "#/$defs/NXOSPlatformModel" + }, + { + "$ref": "#/$defs/OpenBSDPlatformModel" + }, + { + "$ref": "#/$defs/opensusePlatformModel" + }, + { + "$ref": "#/$defs/OpenWrtPlatformModel" + }, + { + "$ref": "#/$defs/OracleLinuxPlatformModel" + }, + { + "$ref": "#/$defs/os10PlatformModel" + }, + { + "$ref": "#/$defs/PAN-OSPlatformModel" + }, + { + "$ref": "#/$defs/SLESPlatformModel" + }, + { + "$ref": "#/$defs/SmartOSPlatformModel" + }, + { + "$ref": "#/$defs/SolarisPlatformModel" + }, + { + "$ref": "#/$defs/SynologyPlatformModel" + }, + { + "$ref": "#/$defs/TMOSPlatformModel" + }, + { + "$ref": "#/$defs/UbuntuPlatformModel" + }, + { + "$ref": "#/$defs/vCenterPlatformModel" + }, + { + "$ref": "#/$defs/Void_LinuxPlatformModel" + }, + { + "$ref": "#/$defs/vSpherePlatformModel" + }, + { + "$ref": "#/$defs/WindowsPlatformModel" + } + ] + }, + "title": "Platforms", + "type": "array" + }, + "vCenterPlatformModel": { + "properties": { + "name": { + "const": "vCenter", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "vCenterPlatformModel", + "type": "object" + }, + "vSpherePlatformModel": { + "properties": { + "name": { + "const": "vSphere", + "title": "Name", + "type": "string" + }, + "versions": { + "default": "all", + "items": { + "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "all"], + "type": "string" + }, + "type": "array" + } + }, + "title": "vSpherePlatformModel", + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json", + "$schema": "http://json-schema.org/draft-07/schema", + "examples": ["meta/main.yml"], + "properties": { + "additionalProperties": false, + "allow_duplicates": { + "title": "Allow Duplicates", + "type": "boolean" + }, + "collections": { + "$ref": "#/$defs/collections" + }, + "dependencies": { + "items": { + "$ref": "#/$defs/DependencyModel" + }, + "title": "Dependencies", + "type": "array" + }, + "galaxy_info": { + "$ref": "#/$defs/GalaxyInfoModel" + } + }, + "title": "Ansible Meta Schema v1/v2", + "type": ["object", "null"] +} diff --git a/src/ansiblelint/schemas/molecule.json b/src/ansiblelint/schemas/molecule.json new file mode 100644 index 0000000..d957f08 --- /dev/null +++ b/src/ansiblelint/schemas/molecule.json @@ -0,0 +1,561 @@ +{ + "$defs": { + "ContainerRegistryModel": { + "additionalProperties": false, + "properties": { + "url": { + "title": "Url", + "type": "string" + } + }, + "required": ["url"], + "title": "ContainerRegistryModel", + "type": "object" + }, + "MoleculeDependencyModel": { + "additionalProperties": false, + "properties": { + "command": { + "title": "Command", + "type": ["string", "null"] + }, + "enabled": { + "default": true, + "title": "Enabled", + "type": "boolean" + }, + "env": { + "title": "Env", + "type": "object" + }, + "name": { + "enum": ["galaxy", "shell"], + "title": "Name", + "type": "string" + }, + "options": { + "title": "Options", + "type": "object" + } + }, + "required": ["name"], + "title": "MoleculeDependencyModel", + "type": "object" + }, + "MoleculeDriverModel": { + "additionalProperties": false, + "properties": { + "cachier": { + "title": "Cachier", + "type": "string" + }, + "default_box": { + "title": "DefaultBox", + "type": "string" + }, + "name": { + "enum": [ + "azure", + "ec2", + "delegated", + "docker", + "containers", + "openstack", + "podman", + "vagrant", + "digitalocean", + "gce", + "libvirt", + "lxd" + ], + "title": "Name", + "type": "string" + }, + "options": { + "$ref": "#/$defs/MoleculeDriverOptionsModel" + }, + "parallel": { + "title": "Parallel", + "type": "boolean" + }, + "provider": { + "title": "Provider", + "type": "object" + }, + "provision": { + "title": "Provision", + "type": "boolean" + }, + "safe_files": { + "items": { + "type": "string" + }, + "title": "SafeFiles", + "type": "array" + }, + "ssh_connection_options": { + "items": { + "type": "string" + }, + "title": "SshConnectionOptions", + "type": "array" + } + }, + "title": "MoleculeDriverModel", + "type": "object" + }, + "MoleculeDriverOptionsModel": { + "additionalProperties": false, + "properties": { + "ansible_connection_options": { + "additionalProperties": { + "type": "string" + }, + "title": "Ansible Connection Options", + "type": "object" + }, + "login_cmd_template": { + "title": "Login Cmd Template", + "type": "string" + }, + "managed": { + "title": "Managed", + "type": "boolean" + } + }, + "title": "MoleculeDriverOptionsModel", + "type": "object" + }, + "MoleculePlatformModel": { + "additionalProperties": true, + "properties": { + "box": { + "title": "Box", + "type": "string" + }, + "cgroupns": { + "title": "Cgroupns", + "type": "string" + }, + "children": { + "items": { + "type": "string" + }, + "type": "array" + }, + "command": { + "title": "Command", + "type": "string" + }, + "cpus": { + "title": "Cpus", + "type": "integer" + }, + "dockerfile": { + "title": "Dockerfile", + "type": "string" + }, + "env": { + "items": { + "type": "object" + }, + "title": "Platform Environment Variables", + "type": "array" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "title": "Environment", + "type": "object" + }, + "groups": { + "items": { + "type": "string" + }, + "title": "Groups", + "type": "array" + }, + "hostname": { + "title": "Hostname", + "type": ["string", "boolean"] + }, + "image": { + "title": "Image", + "type": ["string", "null"] + }, + "interfaces": { + "title": "Interfaces", + "type": "array" + }, + "memory": { + "title": "Memory", + "type": "integer" + }, + "name": { + "title": "Name", + "type": "string" + }, + "network_mode": { + "anyOf": [ + { + "enum": ["bridge", "host", "none"], + "type": "string" + }, + { + "pattern": "^service:[a-zA-Z0-9:_.\\\\-]+$", + "type": "string" + }, + { + "pattern": "^container:[a-zA-Z0-9][a-zA-Z0-9_.-]+$", + "type": "string" + } + ], + "title": "Network Mode" + }, + "networks": { + "items": { + "$ref": "#/$defs/platform-network" + }, + "markdownDescription": "Used by docker and podman drivers.", + "title": "Networks", + "type": "array" + }, + "pkg_extras": { + "title": "Pkg Extras", + "type": "string" + }, + "pre_build_image": { + "title": "Pre Build Image", + "type": "boolean" + }, + "privileged": { + "title": "Privileged", + "type": "boolean" + }, + "provider_options": { + "title": "Provider options", + "type": "object" + }, + "provider_raw_config_args": { + "items": { + "type": "string" + }, + "title": "Provider Raw Config Args", + "type": "array" + }, + "registry": { + "$ref": "#/$defs/ContainerRegistryModel" + }, + "tmpfs": { + "items": { + "type": "string" + }, + "title": "Tmpfs", + "type": "array" + }, + "ulimits": { + "items": { + "type": "string" + }, + "title": "Ulimits", + "type": "array" + }, + "volumes": { + "items": { + "type": "string" + }, + "title": "Volumes", + "type": "array" + } + }, + "required": ["name"], + "title": "MoleculePlatformModel", + "type": "object" + }, + "MoleculeScenarioModel": { + "additionalProperties": false, + "properties": { + "check_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "cleanup_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "converge_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "create_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "dependency_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "destroy_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "idempotence_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "lint_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "name": { + "title": "Name", + "type": "string" + }, + "prepare_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "side_effect_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "syntax_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "test_sequence": { + "$ref": "#/$defs/ScenarioSequence" + }, + "verify_sequence": { + "$ref": "#/$defs/ScenarioSequence" + } + }, + "title": "MoleculeScenarioModel", + "type": "object" + }, + "ProvisionerConfigOptionsDefaultsModel": { + "additionalProperties": true, + "properties": { + "ansible_managed": { + "default": "Ansible managed: Do NOT edit this file manually!", + "title": "Ansible Managed", + "type": "string" + }, + "display_failed_stderr": { + "default": true, + "title": "Display Failed Stderr", + "type": "boolean" + }, + "fact_caching": { + "title": "Fact Caching", + "type": "string" + }, + "fact_caching_connection": { + "title": "Fact Caching Connection", + "type": "string" + }, + "forks": { + "default": 50, + "title": "Forks", + "type": "integer" + }, + "host_key_checking": { + "default": false, + "title": "Host Key Checking", + "type": "boolean" + }, + "interpreter_python": { + "default": "auto_silent", + "description": "See https://docs.ansible.com/ansible/devel/reference_appendices/interpreter_discovery.html", + "title": "Interpreter Python", + "type": "string" + }, + "nocows": { + "default": 1, + "title": "Nocows", + "type": "integer" + }, + "retry_files_enabled": { + "default": false, + "title": "Retry Files Enabled", + "type": "boolean" + } + }, + "title": "ProvisionerConfigOptionsDefaultsModel", + "type": "object" + }, + "ProvisionerConfigOptionsModel": { + "additionalProperties": true, + "properties": { + "defaults": { + "$ref": "#/$defs/ProvisionerConfigOptionsDefaultsModel" + }, + "ssh_connection": { + "$ref": "#/$defs/ProvisionerConfigOptionsSshConnectionModel" + } + }, + "title": "ProvisionerConfigOptionsModel", + "type": "object" + }, + "ProvisionerConfigOptionsSshConnectionModel": { + "additionalProperties": false, + "properties": { + "control_path": { + "default": "%(directory)s/%%h-%%p-%%r", + "title": "Control Path", + "type": "string" + }, + "scp_if_ssh": { + "default": true, + "title": "Scp If Ssh", + "type": "boolean" + } + }, + "title": "ProvisionerConfigOptionsSshConnectionModel", + "type": "object" + }, + "ProvisionerModel": { + "additionalProperties": true, + "properties": { + "config_options": { + "$ref": "#/$defs/ProvisionerConfigOptionsModel" + }, + "env": { + "title": "Env", + "type": "object" + }, + "inventory": { + "title": "Inventory", + "type": "object" + }, + "log": { + "title": "Log", + "type": "boolean" + }, + "name": { + "enum": ["ansible"], + "title": "Name", + "type": "string" + }, + "playbooks": { + "title": "Playbooks", + "type": "object" + } + }, + "title": "ProvisionerModel", + "type": "object" + }, + "ScenarioSequence": { + "additionalProperties": false, + "items": { + "enum": [ + "check", + "cleanup", + "converge", + "create", + "dependency", + "destroy", + "idempotence", + "lint", + "prepare", + "side_effect", + "syntax", + "test", + "verify" + ], + "type": "string" + }, + "title": "ScenarioSequence", + "type": "array" + }, + "VerifierModel": { + "additionalProperties": false, + "properties": { + "additional_files_or_dirs": { + "items": { + "type": "string" + }, + "title": "AdditionalFilesOrDirs", + "type": "array" + }, + "enabled": { + "title": "Enabled", + "type": "boolean" + }, + "env": { + "title": "Env", + "type": "object" + }, + "name": { + "default": "ansible", + "enum": ["ansible", "goss", "inspec", "testinfra"], + "title": "Name", + "type": "string" + }, + "options": { + "title": "Options", + "type": "object" + } + }, + "title": "VerifierModel", + "type": "object" + }, + "platform-network": { + "properties": { + "aliases": { + "items": { + "type": "string" + }, + "type": "array" + }, + "ipv4_address": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": ["name"], + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/molecule.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": ["molecule/*/molecule.yml"], + "properties": { + "dependency": { + "$ref": "#/$defs/MoleculeDependencyModel" + }, + "driver": { + "$ref": "#/$defs/MoleculeDriverModel" + }, + "lint": { + "title": "Lint", + "type": "string" + }, + "log": { + "default": true, + "title": "Log", + "type": "boolean" + }, + "platforms": { + "items": { + "$ref": "#/$defs/MoleculePlatformModel" + }, + "title": "Platforms", + "type": "array" + }, + "prerun": { + "title": "Prerun", + "type": "boolean" + }, + "provisioner": { + "$ref": "#/$defs/ProvisionerModel" + }, + "role_name_check": { + "enum": [0, 1, 2], + "title": "RoleNameCheck", + "type": "integer" + }, + "scenario": { + "$ref": "#/$defs/MoleculeScenarioModel" + }, + "verifier": { + "$ref": "#/$defs/VerifierModel" + } + }, + "required": ["driver", "platforms"], + "title": "Molecule Scenario Schema", + "type": "object" +} diff --git a/src/ansiblelint/schemas/playbook.json b/src/ansiblelint/schemas/playbook.json new file mode 100644 index 0000000..983033f --- /dev/null +++ b/src/ansiblelint/schemas/playbook.json @@ -0,0 +1,1245 @@ +{ + "$comment": "Generated from ansible.json, do not edit.", + "$defs": { + "ansible.builtin.import_playbook": { + "additionalProperties": false, + "oneOf": [ + { + "not": { + "required": [ + "import_playbook" + ] + }, + "required": [ + "ansible.builtin.import_playbook" + ] + }, + { + "not": { + "required": [ + "ansible.builtin.import_playbook" + ] + }, + "required": [ + "import_playbook" + ] + } + ], + "patternProperties": { + "^(ansible\\.builtin\\.)?import_playbook$": { + "markdownDescription": "* Includes a file with a list of plays to be executed.\n * Files with a list of plays can only be included at the top level.\n * You cannot use this action inside a play.\n\nSee [import_playbook](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/import_playbook_module.html)", + "title": "Import Playbook", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "tags": { + "$ref": "#/$defs/tags" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "type": "object" + }, + "become_method": { + "anyOf": [ + { + "enum": [ + "ansible.builtin.sudo", + "ansible.builtin.su", + "community.general.pbrun", + "community.general.pfexec", + "ansible.builtin.runas", + "community.general.dzdo", + "community.general.ksu", + "community.general.doas", + "community.general.machinectl", + "community.general.pmrun", + "community.general.sesu", + "community.general.sudosu" + ], + "type": "string" + }, + { + "$ref": "#/$defs/full-jinja" + }, + { + "pattern": "[A-Za-z0-9_\\.]+", + "type": "string" + } + ], + "markdownDescription": "See [become](https://docs.ansible.com/ansible/latest/user_guide/become.html)", + "title": "Become Method" + }, + "block": { + "properties": { + "always": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "title": "Always", + "type": "array" + }, + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "block": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "markdownDescription": "Blocks create logical groups of tasks. Blocks also offer ways to handle task errors, similar to exception handling in many programming languages. See [blocks](https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html)", + "title": "Block", + "type": "array" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delegate_facts": { + "title": "Delegate Facts", + "type": "boolean" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "port": { + "$ref": "#/$defs/templated-integer" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "rescue": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "title": "Rescue", + "type": "array" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": [ + "block" + ], + "type": "object" + }, + "complex_conditional": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "items": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + }, + "type": "array" + } + ] + }, + "environment": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "$ref": "#/$defs/full-jinja" + } + ], + "title": "Environment" + }, + "full-jinja": { + "pattern": "^\\{[\\{%](.|[\r\n])*[\\}%]\\}$", + "type": "string" + }, + "ignore_errors": { + "$ref": "#/$defs/templated-boolean", + "markdownDescription": "See [ignore_errors](https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#ignoring-failed-commands)", + "title": "Ignore Errors" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean", + "markdownDescription": "Use for protecting sensitive data. See [no_log](https://docs.ansible.com/ansible/latest/reference_appendices/logging.html)", + "title": "no_log" + }, + "play": { + "additionalProperties": false, + "allOf": [ + { + "not": { + "required": [ + "ansible.builtin.import_playbook" + ] + } + }, + { + "not": { + "required": [ + "import_playbook" + ] + } + } + ], + "properties": { + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "fact_path": { + "title": "Fact Path", + "type": "string" + }, + "force_handlers": { + "title": "Force Handlers", + "type": "boolean" + }, + "gather_facts": { + "title": "Gather Facts", + "type": "boolean" + }, + "gather_subset": { + "items": { + "anyOf": [ + { + "enum": [ + "all", + "min", + "all_ipv4_addresses", + "all_ipv6_addresses", + "apparmor", + "architecture", + "caps", + "chroot,cmdline", + "date_time", + "default_ipv4", + "default_ipv6", + "devices", + "distribution", + "distribution_major_version", + "distribution_release", + "distribution_version", + "dns", + "effective_group_ids", + "effective_user_id", + "env", + "facter", + "fips", + "hardware", + "interfaces", + "is_chroot", + "iscsi", + "kernel", + "local", + "lsb", + "machine", + "machine_id", + "mounts", + "network", + "ohai", + "os_family", + "pkg_mgr", + "platform", + "processor", + "processor_cores", + "processor_count", + "python", + "python_version", + "real_user_id", + "selinux", + "service_mgr", + "ssh_host_key_dsa_public", + "ssh_host_key_ecdsa_public", + "ssh_host_key_ed25519_public", + "ssh_host_key_rsa_public", + "ssh_host_pub_keys", + "ssh_pub_keys", + "system", + "system_capabilities", + "system_capabilities_enforced", + "user", + "user_dir", + "user_gecos", + "user_gid", + "user_id", + "user_shell", + "user_uid", + "virtual", + "virtualization_role", + "virtualization_type" + ], + "type": "string" + }, + { + "enum": [ + "!all", + "!min", + "!all_ipv4_addresses", + "!all_ipv6_addresses", + "!apparmor", + "!architecture", + "!caps", + "!chroot,cmdline", + "!date_time", + "!default_ipv4", + "!default_ipv6", + "!devices", + "!distribution", + "!distribution_major_version", + "!distribution_release", + "!distribution_version", + "!dns", + "!effective_group_ids", + "!effective_user_id", + "!env", + "!facter", + "!fips", + "!hardware", + "!interfaces", + "!is_chroot", + "!iscsi", + "!kernel", + "!local", + "!lsb", + "!machine", + "!machine_id", + "!mounts", + "!network", + "!ohai", + "!os_family", + "!pkg_mgr", + "!platform", + "!processor", + "!processor_cores", + "!processor_count", + "!python", + "!python_version", + "!real_user_id", + "!selinux", + "!service_mgr", + "!ssh_host_key_dsa_public", + "!ssh_host_key_ecdsa_public", + "!ssh_host_key_ed25519_public", + "!ssh_host_key_rsa_public", + "!ssh_host_pub_keys", + "!ssh_pub_keys", + "!system", + "!system_capabilities", + "!system_capabilities_enforced", + "!user", + "!user_dir", + "!user_gecos", + "!user_gid", + "!user_id", + "!user_shell", + "!user_uid", + "!virtual", + "!virtualization_role", + "!virtualization_type" + ], + "type": "string" + } + ] + }, + "title": "Gather Subset", + "type": "array" + }, + "gather_timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Gather Timeout" + }, + "handlers": { + "$ref": "#/$defs/tasks" + }, + "hosts": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Hosts" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "max_fail_percentage": { + "title": "Max Fail Percentage", + "type": "number" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "order": { + "enum": [ + "default", + "sorted", + "reverse_sorted", + "reverse_inventory", + "shuffle" + ], + "title": "Order", + "type": "string" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "post_tasks": { + "$ref": "#/$defs/tasks" + }, + "pre_tasks": { + "$ref": "#/$defs/tasks" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "roles": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/play-role" + }, + { + "type": "string" + } + ] + }, + "markdownDescription": "Roles let you automatically load related vars, files, tasks, handlers, and other Ansible artifacts based on a known file structure. After you group your content in roles, you can easily reuse them and share them with other users.\n See [roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#roles)", + "title": "Roles", + "type": "array" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "serial": { + "anyOf": [ + { + "$ref": "#/$defs/templated-integer-or-percent" + }, + { + "items": { + "$ref": "#/$defs/templated-integer-or-percent" + }, + "type": "array" + } + ], + "markdownDescription": "Integer, percentage or list of those. See [Setting the batch size with serial](https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html#setting-the-batch-size-with-serial)", + "title": "Batch size" + }, + "strategy": { + "title": "Strategy", + "type": "string" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "tasks": { + "$ref": "#/$defs/tasks" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "user": { + "title": "Remote User", + "type": "string" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "vars_files": { + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "title": "Vars Files", + "type": [ + "array", + "string", + "null" + ] + }, + "vars_prompt": { + "items": { + "$ref": "#/$defs/vars_prompt" + }, + "markdownDescription": "See [vars_prompt](https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html)", + "title": "vars_prompt", + "type": "array" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": [ + "hosts" + ], + "title": "play", + "type": "object" + }, + "play-role": { + "markdownDescription": "See [roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#roles)", + "properties": { + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "role": { + "title": "Role", + "type": "string" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": [ + "role" + ], + "title": "play-role", + "type": "object" + }, + "tags": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Tags" + }, + "task": { + "additionalProperties": true, + "allOf": [ + { + "not": { + "required": [ + "hosts" + ] + } + }, + { + "not": { + "required": [ + "tasks" + ] + } + }, + { + "not": { + "required": [ + "import_playbook" + ] + } + }, + { + "not": { + "required": [ + "block" + ] + } + } + ], + "properties": { + "action": { + "title": "Action", + "type": "string" + }, + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "args": { + "$ref": "#/$defs/templated-object", + "title": "Args" + }, + "async": { + "$ref": "#/$defs/templated-integer", + "title": "Async" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "changed_when": { + "$ref": "#/$defs/complex_conditional", + "markdownDescription": "See [changed_when](https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#defining-changed)", + "title": "Changed When" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delay": { + "$ref": "#/$defs/templated-integer", + "title": "Delay" + }, + "delegate_facts": { + "title": "Delegate Facts", + "type": "boolean" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "failed_when": { + "$ref": "#/$defs/complex_conditional", + "title": "Failed When" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "listen": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Applies only to handlers. See [listen](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html)", + "title": "Listen" + }, + "local_action": { + "title": "Local Action", + "type": [ + "string", + "object" + ] + }, + "loop": { + "title": "Loop", + "type": [ + "string", + "array" + ] + }, + "loop_control": { + "title": "Loop Control" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/no_log" + }, + "notify": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Notify" + }, + "poll": { + "$ref": "#/$defs/templated-integer", + "title": "Poll" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "register": { + "title": "Register", + "type": "string" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "retries": { + "$ref": "#/$defs/templated-integer", + "title": "Retries" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "until": { + "$ref": "#/$defs/complex_conditional", + "title": "Until" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + }, + "with_dict": { + "title": "With Dict" + }, + "with_fileglob": { + "title": "With Fileglob" + }, + "with_filetree": { + "title": "With Filetree" + }, + "with_first_found": { + "title": "With First Found" + }, + "with_indexed_items": { + "title": "With Indexed Items" + }, + "with_ini": { + "title": "With Ini" + }, + "with_inventory_hostnames": { + "title": "With Inventory Hostnames" + }, + "with_items": { + "anyOf": [ + { + "$ref": "#/$defs/full-jinja" + }, + { + "type": "array" + } + ], + "markdownDescription": "See [loops](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#loops)", + "title": "With Items" + }, + "with_lines": { + "title": "With Lines" + }, + "with_random_choice": { + "title": "With Random Choice" + }, + "with_sequence": { + "title": "With Sequence" + }, + "with_subelements": { + "title": "With Subelements" + }, + "with_together": { + "title": "With Together" + } + }, + "title": "task", + "type": "object" + }, + "tasks": { + "$schema": "http://json-schema.org/draft-07/schema", + "examples": [ + "tasks/*.yml", + "handlers/*.yml" + ], + "items": { + "anyOf": [ + { + "$ref": "#/$defs/block" + }, + { + "$ref": "#/$defs/task" + } + ] + }, + "title": "Ansible Tasks Schema", + "type": [ + "array", + "null" + ] + }, + "templated-boolean": { + "oneOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-integer": { + "oneOf": [ + { + "type": "integer" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-integer-or-percent": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^\\d+\\.?\\d*%?$", + "type": "string" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-object": { + "oneOf": [ + { + "type": "object" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "vars_prompt": { + "additionalProperties": false, + "properties": { + "confirm": { + "title": "Confirm", + "type": "boolean" + }, + "default": { + "title": "Default", + "type": "string" + }, + "encrypt": { + "enum": [ + "des_crypt", + "bsdi_crypt", + "bigcrypt", + "crypt16", + "md5_crypt", + "bcrypt", + "sha1_crypt", + "sun_md5_crypt", + "sha256_crypt", + "sha512_crypt", + "apr_md5_crypt", + "phpass", + "pbkdf2_digest", + "cta_pbkdf2_sha1", + "dlitz_pbkdf2_sha1", + "scram", + "bsd_nthash" + ], + "title": "Encrypt", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "private": { + "default": true, + "title": "Private", + "type": "boolean" + }, + "prompt": { + "title": "Prompt", + "type": "string" + }, + "salt_size": { + "default": 8, + "title": "Salt Size", + "type": "integer" + }, + "unsafe": { + "default": false, + "markdownDescription": "See [unsafe](https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html#allowing-special-characters-in-vars-prompt-values)", + "title": "Unsafe", + "type": "boolean" + } + }, + "required": [ + "name", + "prompt" + ], + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/playbook.json", + "$schema": "http://json-schema.org/draft-07/schema", + "examples": [ + "playbooks/*.yml", + "playbooks/*.yaml" + ], + "items": { + "oneOf": [ + { + "$ref": "#/$defs/ansible.builtin.import_playbook" + }, + { + "$ref": "#/$defs/play" + } + ] + }, + "title": "Ansible Playbook", + "type": "array" +} diff --git a/src/ansiblelint/schemas/requirements.json b/src/ansiblelint/schemas/requirements.json new file mode 100644 index 0000000..dc7ded6 --- /dev/null +++ b/src/ansiblelint/schemas/requirements.json @@ -0,0 +1,135 @@ +{ + "$defs": { + "CollectionModel": { + "additionalProperties": false, + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "source": { + "title": "Source", + "type": "string" + }, + "type": { + "enum": ["galaxy", "url", "file", "git", "dir", "subdirs"], + "title": "Type", + "type": "string" + }, + "version": { + "title": "Version", + "type": "string" + } + }, + "title": "CollectionModel", + "type": "object" + }, + "CollectionStringModel": { + "title": "CollectionStringModel", + "type": "string" + }, + "IncludeModel": { + "properties": { + "include": { + "title": "Include", + "type": "string" + } + }, + "required": ["include"], + "title": "IncludeModel", + "type": "object" + }, + "RequirementsV2Model": { + "additionalProperties": false, + "anyOf": [ + { + "required": ["collections"] + }, + { + "required": ["roles"] + } + ], + "properties": { + "collections": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/CollectionModel" + }, + { + "$ref": "#/$defs/CollectionStringModel" + } + ] + }, + "title": "Collections", + "type": "array" + }, + "roles": { + "items": { + "$ref": "#/$defs/RoleModel" + }, + "title": "Roles", + "type": "array" + } + }, + "title": "Requirements v2", + "type": "object" + }, + "RoleModel": { + "additionalProperties": false, + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "scm": { + "anyOf": [ + { + "enum": ["git"], + "type": "string" + }, + { + "enum": ["hg"], + "type": "string" + } + ], + "default": "git", + "title": "Scm" + }, + "src": { + "title": "Src", + "type": "string" + }, + "version": { + "default": "master", + "title": "Version", + "type": "string" + } + }, + "title": "Role", + "type": "object" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/requirements.json", + "$schema": "http://json-schema.org/draft-07/schema", + "anyOf": [ + { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/RoleModel" + }, + { + "$ref": "#/$defs/IncludeModel" + } + ] + }, + "type": "array" + }, + { + "$ref": "#/$defs/RequirementsV2Model" + } + ], + "examples": ["requirements.yml"], + "title": "Ansible Requirements Schema" +} diff --git a/src/ansiblelint/schemas/role-arg-spec.json b/src/ansiblelint/schemas/role-arg-spec.json new file mode 100644 index 0000000..433993e --- /dev/null +++ b/src/ansiblelint/schemas/role-arg-spec.json @@ -0,0 +1,250 @@ +{ + "$defs": { + "datatype": { + "enum": [ + "str", + "list", + "dict", + "bool", + "int", + "float", + "path", + "raw", + "jsonarg", + "json", + "bytes", + "bits" + ], + "type": "string" + }, + "deprecated_alias": { + "properties": { + "collection_name": { + "type": "string" + }, + "date": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": ["name"], + "type": "object" + }, + "entry_point": { + "additionalProperties": false, + "properties": { + "author": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "description": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "options": { + "additionalProperties": { + "$ref": "#/$defs/option" + }, + "type": "object" + }, + "seealso": { + "items": { + "oneOf": [ + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "module": { + "type": "string" + } + }, + "required": ["module"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "plugin": { + "type": "string" + }, + "plugin_type": { + "type": "string" + } + }, + "required": ["plugin", "plugin_type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "ref": { + "type": "string" + } + }, + "required": ["description", "ref"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "link": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": ["description", "link", "name"], + "type": "object" + } + ] + }, + "type": "array" + }, + "short_description": { + "type": "string" + }, + "version_added": { + "type": "string" + } + }, + "required": ["options"], + "title": "Entry Point", + "type": "object" + }, + "option": { + "additionalProperties": false, + "aliases": { + "items": { + "type": "string" + }, + "type": "array" + }, + "apply_defaults": { + "type": "string" + }, + "deprecated_aliases": { + "items": { + "$ref": "#/$defs/deprecated_alias" + }, + "type": "array" + }, + "markdownDescription": "xxx", + "options": { + "$ref": "#/$defs/option" + }, + "properties": { + "choices": { + "type": "array" + }, + "default": { + "default": "None" + }, + "description": { + "description": "Detailed explanation of what this option does. It should be written in full sentences.", + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "elements": { + "$ref": "#/$defs/datatype" + }, + "fallback": { + "default": "None", + "type": "string" + }, + "no_log": { + "default": false, + "type": "boolean" + }, + "option-name": { + "description": "The name of the option/argument.", + "type": "string" + }, + "options": { + "additionalProperties": { + "$ref": "#/$defs/option" + }, + "type": "object" + }, + "required": { + "default": false, + "type": "boolean" + }, + "type": { + "$ref": "#/$defs/datatype", + "markdownDescription": "See [argument-spec](https://docs.ansible.com/ansible/latest/dev_guide/developing_program_flow_modules.html#argument-spec" + }, + "version_added": { + "type": "string" + } + }, + "removed_at_date": { + "type": "string" + }, + "removed_from_collection": { + "type": "string" + }, + "removed_in_version": { + "type": "string" + }, + "title": "Option" + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/role-arg-spec.json", + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "examples": ["meta/argument_specs.yml"], + "markdownDescription": "Add entry point, usually `main`.\nSee [role-argument-validation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#role-argument-validation)", + "properties": { + "argument_specs": { + "additionalProperties": { + "$ref": "#/$defs/entry_point" + }, + "markdownDescription": "Add entry point, usually `main`.\nSee [role-argument-validation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#role-argument-validation)" + } + }, + "title": "Ansible Role Argument Specs Schema" +} diff --git a/src/ansiblelint/schemas/rulebook.json b/src/ansiblelint/schemas/rulebook.json new file mode 100644 index 0000000..6c441cd --- /dev/null +++ b/src/ansiblelint/schemas/rulebook.json @@ -0,0 +1,645 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/ansible/ansible-rulebook/main/ansible_rulebook/schema/ruleset_schema.json", + "type": "array", + "items": { + "$ref": "#/$defs/ruleset" + }, + "minItems": 1, + "examples": [ + "rulebooks/*.yml", + "rulebooks/*.yaml" + ], + "$defs": { + "ruleset": { + "type": "object", + "properties": { + "default_events_ttl": { + "type": "string", + "pattern": "^\\d+\\s(seconds?|minutes?|hours?|days?)$" + }, + "hosts": { + "type": "string" + }, + "gather_facts": { + "type": "boolean", + "default": false + }, + "name": { + "type": "string" + }, + "execution_strategy": { + "type": "string", + "enum": ["sequential", "parallel"], + "default": "sequential" + }, + "sources": { + "type": "array", + "items": { + "$ref": "#/$defs/source" + } + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/$defs/rule" + } + } + }, + "required": [ + "hosts", + "sources", + "rules" + ], + "additionalProperties": false + }, + "source": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "filters": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "additionalProperties": { + "oneOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "throttle": { + "type": "object", + "oneOf": [ + { + "required": [ + "once_within", + "group_by_attributes" + ] + }, + { + "required": [ + "once_after", + "group_by_attributes" + ] + } + ], + "properties": { + "once_within": { + "type": "string", + "pattern": "^\\d+\\s(milliseconds?|seconds?|minutes?|hours?|days?)$" + }, + "once_after": { + "type": "string", + "pattern": "^\\d+\\s(milliseconds?|seconds?|minutes?|hours?|days?)$" + }, + "group_by_attributes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "rule": { + "type": "object", + "oneOf": [ + { + "required": [ + "name", + "condition", + "actions" + ] + }, + { + "required": [ + "name", + "condition", + "action" + ] + } + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "pattern": "\\S" + }, + "enabled": { + "type": "boolean" + }, + "throttle": { + "$ref": "#/$defs/throttle" + }, + "condition": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/$defs/all-condition" + }, + { + "$ref": "#/$defs/any-condition" + }, + { + "$ref": "#/$defs/not-all-condition" + } + ] + }, + "actions": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/run-playbook-action" + }, + { + "$ref": "#/$defs/run-module-action" + }, + { + "$ref": "#/$defs/run-job-template-action" + }, + { + "$ref": "#/$defs/post-event-action" + }, + { + "$ref": "#/$defs/set-fact-action" + }, + { + "$ref": "#/$defs/retract-fact-action" + }, + { + "$ref": "#/$defs/print-event-action" + }, + { + "$ref": "#/$defs/debug-action" + }, + { + "$ref": "#/$defs/none-action" + }, + { + "$ref": "#/$defs/shutdown-action" + } + ] + } + }, + "action": { + "oneOf": [ + { + "$ref": "#/$defs/run-playbook-action" + }, + { + "$ref": "#/$defs/run-module-action" + }, + { + "$ref": "#/$defs/run-job-template-action" + }, + { + "$ref": "#/$defs/post-event-action" + }, + { + "$ref": "#/$defs/set-fact-action" + }, + { + "$ref": "#/$defs/retract-fact-action" + }, + { + "$ref": "#/$defs/print-event-action" + }, + { + "$ref": "#/$defs/debug-action" + }, + { + "$ref": "#/$defs/none-action" + }, + { + "$ref": "#/$defs/shutdown-action" + } + ] + } + }, + "additionalProperties": false + }, + "all-condition": { + "type": "object", + "properties": { + "all": { + "type": "array", + "items": { + "type": "string" + } + }, + "timeout": { + "type": "string", + "pattern": "^\\d+\\s(milliseconds?|seconds?|minutes?|hours?|days?)$" + } + }, + "additionalProperties": false + }, + "not-all-condition": { + "type": "object", + "properties": { + "not_all": { + "type": "array", + "items": { + "type": "string" + } + }, + "timeout": { + "type": "string", + "pattern": "^\\d+\\s(milliseconds?|seconds?|minutes?|hours?|days?)$" + } + }, + "required": [ + "timeout", + "not_all" + ], + "additionalProperties": false + }, + "any-condition": { + "type": "object", + "properties": { + "any": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "run-playbook-action": { + "type": "object", + "properties": { + "run_playbook": { + "type": "object", + "properties": { + "copy_files": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "post_events": { + "type": "boolean" + }, + "set_facts": { + "type": "boolean" + }, + "ruleset": { + "type": "string" + }, + "verbosity": { + "type": "integer" + }, + "var_root": { + "type": [ + "string", + "object" + ] + }, + "json_mode": { + "type": "boolean" + }, + "retry": { + "type": "boolean" + }, + "retries": { + "type": "integer" + }, + "delay": { + "type": "number" + }, + "extra_vars": { + "type": "object" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "required": [ + "run_playbook" + ], + "additionalProperties": false + }, + "run-module-action": { + "type": "object", + "properties": { + "run_module": { + "type": "object", + "properties": { + "copy_files": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "post_events": { + "type": "boolean" + }, + "set_facts": { + "type": "boolean" + }, + "verbosity": { + "type": "integer" + }, + "var_root": { + "type": [ + "string", + "object" + ] + }, + "json_mode": { + "type": "boolean" + }, + "retry": { + "type": "boolean" + }, + "retries": { + "type": "integer" + }, + "delay": { + "type": "number" + }, + "module_args": { + "type": "object" + }, + "extra_vars": { + "type": "object" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "required": [ + "run_module" + ], + "additionalProperties": false + }, + "run-job-template-action": { + "type": "object", + "properties": { + "run_job_template": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "organization": { + "type": "string" + }, + "job_args": { + "type": "object" + }, + "post_events": { + "type": "boolean" + }, + "set_facts": { + "type": "boolean" + }, + "ruleset": { + "type": "string" + }, + "var_root": { + "type": "string" + }, + "retry": { + "type": "boolean" + }, + "retries": { + "type": "integer" + }, + "delay": { + "type": "integer" + } + }, + "required": [ + "name", + "organization" + ], + "additionalProperties": false + } + }, + "required": [ + "run_job_template" + ], + "additionalProperties": false + }, + "post-event-action": { + "type": "object", + "properties": { + "post_event": { + "type": "object", + "properties": { + "ruleset": { + "type": "string" + }, + "event": { + "type": "object" + } + }, + "required": [ + "event" + ], + "additionalProperties": false + } + }, + "required": [ + "post_event" + ], + "additionalProperties": false + }, + "set-fact-action": { + "type": "object", + "properties": { + "set_fact": { + "type": "object", + "properties": { + "ruleset": { + "type": "string" + }, + "fact": { + "type": "object" + } + }, + "required": [ + "fact" + ], + "additionalProperties": false + } + }, + "required": [ + "set_fact" + ], + "additionalProperties": false + }, + "retract-fact-action": { + "type": "object", + "properties": { + "retract_fact": { + "type": "object", + "properties": { + "ruleset": { + "type": "string" + }, + "fact": { + "type": "object" + }, + "partial": { + "type": "boolean", + "default": true + } + }, + "required": [ + "fact" + ], + "additionalProperties": false + } + }, + "required": [ + "retract_fact" + ], + "additionalProperties": false + }, + "print-event-action": { + "type": "object", + "properties": { + "print_event": { + "type": [ + "object", + "null" + ], + "properties": { + "var_root": { + "type": [ + "string", + "object" + ] + }, + "pretty": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "required": [ + "print_event" + ], + "additionalProperties": false + }, + "debug-msg": { + "type": "object", + "properties": { + "msg": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + } + }, + "additionalProperties": false + }, + "debug-var": { + "type": "object", + "properties": { + "var": { + "type": "string" + } + }, + "additionalProperties": false + }, + "debug-action": { + "type": "object", + "properties": { + "debug": { + "anyOf": [ + { + "$ref": "#/$defs/debug-msg" + }, + { + "$ref": "#/$defs/debug-var" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "debug" + ] + }, + "none-action": { + "type": "object", + "properties": { + "none": { + "type": [ + "object", + "null" + ] + } + }, + "required": [ + "none" + ], + "additionalProperties": false + }, + "shutdown-action": { + "type": "object", + "properties": { + "shutdown": { + "type": [ + "object", + "null" + ], + "properties": { + "delay": { + "type": "number" + }, + "message": { + "type": "string" + }, + "kind": { + "type": "string", + "enum": [ + "graceful", + "now" + ] + } + }, + "additionalProperties": false + } + }, + "required": [ + "shutdown" + ], + "additionalProperties": false + } + } +} diff --git a/src/ansiblelint/schemas/tasks.json b/src/ansiblelint/schemas/tasks.json new file mode 100644 index 0000000..ec7f85d --- /dev/null +++ b/src/ansiblelint/schemas/tasks.json @@ -0,0 +1,588 @@ +{ + "$comment": "Generated from ansible.json, do not edit.", + "$defs": { + "become_method": { + "anyOf": [ + { + "enum": [ + "ansible.builtin.sudo", + "ansible.builtin.su", + "community.general.pbrun", + "community.general.pfexec", + "ansible.builtin.runas", + "community.general.dzdo", + "community.general.ksu", + "community.general.doas", + "community.general.machinectl", + "community.general.pmrun", + "community.general.sesu", + "community.general.sudosu" + ], + "type": "string" + }, + { + "$ref": "#/$defs/full-jinja" + }, + { + "pattern": "[A-Za-z0-9_\\.]+", + "type": "string" + } + ], + "markdownDescription": "See [become](https://docs.ansible.com/ansible/latest/user_guide/become.html)", + "title": "Become Method" + }, + "block": { + "properties": { + "always": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "title": "Always", + "type": "array" + }, + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "block": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "markdownDescription": "Blocks create logical groups of tasks. Blocks also offer ways to handle task errors, similar to exception handling in many programming languages. See [blocks](https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html)", + "title": "Block", + "type": "array" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delegate_facts": { + "title": "Delegate Facts", + "type": "boolean" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean" + }, + "port": { + "$ref": "#/$defs/templated-integer" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "rescue": { + "items": { + "anyOf": [ + { + "$ref": "#/$defs/task" + }, + { + "$ref": "#/$defs/block" + } + ] + }, + "title": "Rescue", + "type": "array" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + } + }, + "required": [ + "block" + ], + "type": "object" + }, + "complex_conditional": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "items": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + }, + "type": "array" + } + ] + }, + "environment": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "$ref": "#/$defs/full-jinja" + } + ], + "title": "Environment" + }, + "full-jinja": { + "pattern": "^\\{[\\{%](.|[\r\n])*[\\}%]\\}$", + "type": "string" + }, + "ignore_errors": { + "$ref": "#/$defs/templated-boolean", + "markdownDescription": "See [ignore_errors](https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#ignoring-failed-commands)", + "title": "Ignore Errors" + }, + "no_log": { + "$ref": "#/$defs/templated-boolean", + "markdownDescription": "Use for protecting sensitive data. See [no_log](https://docs.ansible.com/ansible/latest/reference_appendices/logging.html)", + "title": "no_log" + }, + "tags": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Tags" + }, + "task": { + "additionalProperties": true, + "allOf": [ + { + "not": { + "required": [ + "hosts" + ] + } + }, + { + "not": { + "required": [ + "tasks" + ] + } + }, + { + "not": { + "required": [ + "import_playbook" + ] + } + }, + { + "not": { + "required": [ + "block" + ] + } + } + ], + "properties": { + "action": { + "title": "Action", + "type": "string" + }, + "any_errors_fatal": { + "$ref": "#/$defs/templated-boolean", + "title": "Any Errors Fatal" + }, + "args": { + "$ref": "#/$defs/templated-object", + "title": "Args" + }, + "async": { + "$ref": "#/$defs/templated-integer", + "title": "Async" + }, + "become": { + "$ref": "#/$defs/templated-boolean", + "title": "Become" + }, + "become_exe": { + "title": "Become Exe", + "type": "string" + }, + "become_flags": { + "title": "Become Flags", + "type": "string" + }, + "become_method": { + "$ref": "#/$defs/become_method" + }, + "become_user": { + "title": "Become User", + "type": "string" + }, + "changed_when": { + "$ref": "#/$defs/complex_conditional", + "markdownDescription": "See [changed_when](https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#defining-changed)", + "title": "Changed When" + }, + "check_mode": { + "$ref": "#/$defs/complex_conditional", + "title": "Check Mode" + }, + "collections": { + "items": { + "type": "string" + }, + "title": "Collections", + "type": "array" + }, + "connection": { + "title": "Connection", + "type": "string" + }, + "debugger": { + "title": "Debugger", + "type": "string" + }, + "delay": { + "$ref": "#/$defs/templated-integer", + "title": "Delay" + }, + "delegate_facts": { + "title": "Delegate Facts", + "type": "boolean" + }, + "delegate_to": { + "title": "Delegate To", + "type": "string" + }, + "diff": { + "$ref": "#/$defs/templated-boolean", + "title": "Diff" + }, + "environment": { + "$ref": "#/$defs/environment" + }, + "failed_when": { + "$ref": "#/$defs/complex_conditional", + "title": "Failed When" + }, + "ignore_errors": { + "$ref": "#/$defs/ignore_errors" + }, + "ignore_unreachable": { + "title": "Ignore Unreachable", + "type": "boolean" + }, + "listen": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "markdownDescription": "Applies only to handlers. See [listen](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html)", + "title": "Listen" + }, + "local_action": { + "title": "Local Action", + "type": [ + "string", + "object" + ] + }, + "loop": { + "title": "Loop", + "type": [ + "string", + "array" + ] + }, + "loop_control": { + "title": "Loop Control" + }, + "module_defaults": { + "title": "Module Defaults" + }, + "name": { + "title": "Name", + "type": "string" + }, + "no_log": { + "$ref": "#/$defs/no_log" + }, + "notify": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "title": "Notify" + }, + "poll": { + "$ref": "#/$defs/templated-integer", + "title": "Poll" + }, + "port": { + "$ref": "#/$defs/templated-integer", + "title": "Port" + }, + "register": { + "title": "Register", + "type": "string" + }, + "remote_user": { + "title": "Remote User", + "type": "string" + }, + "retries": { + "$ref": "#/$defs/templated-integer", + "title": "Retries" + }, + "run_once": { + "$ref": "#/$defs/templated-boolean", + "title": "Run Once" + }, + "tags": { + "$ref": "#/$defs/tags", + "title": "Tags" + }, + "throttle": { + "$ref": "#/$defs/templated-integer", + "title": "Throttle" + }, + "timeout": { + "$ref": "#/$defs/templated-integer", + "title": "Timeout" + }, + "until": { + "$ref": "#/$defs/complex_conditional", + "title": "Until" + }, + "vars": { + "title": "Vars", + "type": "object" + }, + "when": { + "$ref": "#/$defs/complex_conditional", + "title": "When" + }, + "with_dict": { + "title": "With Dict" + }, + "with_fileglob": { + "title": "With Fileglob" + }, + "with_filetree": { + "title": "With Filetree" + }, + "with_first_found": { + "title": "With First Found" + }, + "with_indexed_items": { + "title": "With Indexed Items" + }, + "with_ini": { + "title": "With Ini" + }, + "with_inventory_hostnames": { + "title": "With Inventory Hostnames" + }, + "with_items": { + "anyOf": [ + { + "$ref": "#/$defs/full-jinja" + }, + { + "type": "array" + } + ], + "markdownDescription": "See [loops](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#loops)", + "title": "With Items" + }, + "with_lines": { + "title": "With Lines" + }, + "with_random_choice": { + "title": "With Random Choice" + }, + "with_sequence": { + "title": "With Sequence" + }, + "with_subelements": { + "title": "With Subelements" + }, + "with_together": { + "title": "With Together" + } + }, + "title": "task", + "type": "object" + }, + "templated-boolean": { + "oneOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-integer": { + "oneOf": [ + { + "type": "integer" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + }, + "templated-object": { + "oneOf": [ + { + "type": "object" + }, + { + "$ref": "#/$defs/full-jinja", + "type": "string" + } + ] + } + }, + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/tasks.json", + "$schema": "http://json-schema.org/draft-07/schema", + "examples": [ + "tasks/*.yml", + "handlers/*.yml" + ], + "items": { + "anyOf": [ + { + "$ref": "#/$defs/block" + }, + { + "$ref": "#/$defs/task" + } + ] + }, + "title": "Ansible Tasks Schema", + "type": [ + "array", + "null" + ] +} diff --git a/src/ansiblelint/schemas/vars.json b/src/ansiblelint/schemas/vars.json new file mode 100644 index 0000000..c0b66e8 --- /dev/null +++ b/src/ansiblelint/schemas/vars.json @@ -0,0 +1,29 @@ +{ + "$id": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/vars.json", + "$schema": "http://json-schema.org/draft-07/schema", + "anyOf": [ + { + "additionalProperties": false, + "patternProperties": { + "^(?!(False|None|True|and|any_errors_fatal|as|assert|async|await|become|become_exe|become_flags|become_method|become_user|break|check_mode|class|collections|connection|continue|debugger|def|del|diff|elif|else|environment|except|fact_path|finally|for|force_handlers|from|gather_facts|gather_subset|gather_timeout|global|handlers|hosts|if|ignore_errors|ignore_unreachable|import|in|is|lambda|max_fail_percentage|module_defaults|name|no_log|nonlocal|not|or|order|pass|port|post_tasks|pre_tasks|raise|remote_user|return|roles|run_once|serial|strategy|tags|tasks|throttle|timeout|try|vars|vars_files|vars_prompt|while|with|yield)$)[a-zA-Z_][\\w]*$": {} + }, + "type": "object" + }, + { + "pattern": "^\\$ANSIBLE_VAULT;", + "type": "string" + }, + { + "type": "null" + } + ], + "examples": [ + "playbooks/vars/*.yml", + "vars/*.yml", + "defaults/*.yml", + "host_vars/*.yml", + "group_vars/*.yml" + ], + "markdownDescription": "See [Using Variables](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html)", + "title": "Ansible Vars Schema" +} -- cgit v1.2.3