From 3765dc85672a64a7e4a44e00980bc16e631d9bc4 Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Mon, 4 Dec 2023 18:08:30 +0100
Subject: [PATCH] add generic playbook execution method to the provisioning
proxy service
---
gso/services/provisioning_proxy.py | 66 ++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/gso/services/provisioning_proxy.py b/gso/services/provisioning_proxy.py
index f18de6c22..38d3037b3 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,
--
GitLab