diff --git a/gso/services/provisioning_proxy.py b/gso/services/provisioning_proxy.py index f18de6c222d309cfe9cf03c5fc91c49890ab52e8..38d3037b33d59cc102d5e9ed02ffc4eb8d964074 100644 --- a/gso/services/provisioning_proxy.py +++ b/gso/services/provisioning_proxy.py @@ -7,6 +7,7 @@ import json import logging from functools import partial from http import HTTPStatus +from typing import Any import requests from orchestrator import step @@ -84,6 +85,71 @@ _send_put = partial(_send_request, CUDOperation.PUT) _send_delete = partial(_send_request, CUDOperation.DELETE) +def execute_playbook( + playbook_name: str, + callback_route: str, + inventory: dict[str, Any], + extra_vars: dict[str, Any] +) -> None: + """Execute a playbook remotely through the provisioning proxy. + + When providing this method with an inventory, the format should be compatible with the Ansible YAML-based format. + For example, an inventory consisting of two hosts, which each a unique host variable assigned to them looks as + follows: + + .. code-block:: json + + "inventory": { + "_meta": { + "vars": { + "host1.local": { + "foo": "bar" + }, + "host2.local": { + "key": "value" + } + } + }, + "all": { + "hosts": { + "host1.local": null, + "host2.local": null + } + } + } + + .. warning:: + Note the fact that the collection of all hosts is a dictionary, and not a list of strings. Ansible expects each + host to be a key-value pair. The key is the :term:`FQDN` of a host, and the value always ``null``. + + The extra vars can be a simple dict consisting of key-value pairs, for example: + + .. code-block:: json + + "extra_vars": { + "dry_run": true, + "commit_comment": "I am a robot!", + "verb": "deploy" + } + + :param str playbook_name: Filename of the playbook that is to be executed. It must be present on the remote system + running the provisioning proxy, otherwise it will return an error. + :param str callback_route: The endpoint at which :term:`GSO` expects a callback to continue the workflow executing + this step. + :param dict[str, Any] inventory: An inventory of machines at which the playbook is targeted. Must be in + YAML-compatible format. + :param dict[str, Any] extra_vars: Any extra variables that the playbook relies on. This can include a subscription + object, a boolean value indicating a dry run, a commit comment, etc. + """ + parameters = { + "playbook_name": playbook_name, + "inventory": inventory, + "extra_vars": extra_vars + } + + _send_post("playbook", parameters, callback_route) + + def provision_router( subscription: RouterProvisioning, process_id: UUIDstr,