diff options
Diffstat (limited to '')
-rw-r--r-- | src/pybind/mgr/ansible/output_wizards.py | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/pybind/mgr/ansible/output_wizards.py b/src/pybind/mgr/ansible/output_wizards.py new file mode 100644 index 00000000..d924bf04 --- /dev/null +++ b/src/pybind/mgr/ansible/output_wizards.py @@ -0,0 +1,158 @@ +""" +ceph-mgr Output Wizards module + +Output wizards are used to process results in different ways in +completion objects +""" + +# pylint: disable=bad-continuation + +import json + + +from orchestrator import InventoryDevice, InventoryNode + +from .ansible_runner_svc import EVENT_DATA_URL + +class OutputWizard(object): + """Base class for help to process output in completion objects + """ + def __init__(self, ar_client, logger): + """Make easy to work in output wizards using this attributes: + + :param ars_client: Ansible Runner Service client + :param logger: log object + """ + self.ar_client = ar_client + self.log = logger + + def process(self, operation_id, raw_result): + """Make the magic here + + :param operation_id: Allows to identify the Ansible Runner Service + operation whose result we wnat to process + :param raw_result: input for processing + """ + raise NotImplementedError + +class ProcessInventory(OutputWizard): + """ Adapt the output of the playbook used in 'get_inventory' + to the Orchestrator expected output (list of InventoryNode) + """ + + def process(self, operation_id, raw_result): + """ + :param operation_id: Playbook uuid + :param raw_result: events dict with the results + + Example: + inventory_events = + {'37-100564f1-9fed-48c2-bd62-4ae8636dfcdb': {'host': '192.168.121.254', + 'task': 'list storage inventory', + 'event': 'runner_on_ok'}, + '36-2016b900-e38f-7dcd-a2e7-00000000000e': {'host': '192.168.121.252' + 'task': 'list storage inventory', + 'event': 'runner_on_ok'}} + + :return : list of InventoryNode + """ + # Just making more readable the method + inventory_events = raw_result + + #Obtain the needed data for each result event + inventory_nodes = [] + + # Loop over the result events and request the event data + for event_key, dummy_data in inventory_events.items(): + + event_response = self.ar_client.http_get(EVENT_DATA_URL % + (operation_id, event_key)) + + # self.pb_execution.play_uuid + + # Process the data for each event + if event_response: + event_data = json.loads(event_response.text)["data"]["event_data"] + + host = event_data["host"] + + devices = json.loads(event_data["res"]["stdout"]) + devs = [] + for storage_device in devices: + dev = InventoryDevice.from_ceph_volume_inventory(storage_device) + devs.append(dev) + + inventory_nodes.append(InventoryNode(host, devs)) + + + return inventory_nodes + +class ProcessPlaybookResult(OutputWizard): + """ Provides the result of a playbook execution as plain text + """ + def process(self, operation_id, raw_result): + """ + :param operation_id: Playbook uuid + :param raw_result: events dict with the results + + :return : String with the playbook execution event list + """ + # Just making more readable the method + inventory_events = raw_result + + result = "" + + # Loop over the result events and request the data + for event_key, dummy_data in inventory_events.items(): + event_response = self.ar_client.http_get(EVENT_DATA_URL % + (operation_id, event_key)) + + result += event_response.text + + return result + + +class ProcessHostsList(OutputWizard): + """ Format the output of host ls call + """ + def process(self, operation_id, raw_result): + """ Format the output of host ls call + + :param operation_id: Not used in this output wizard + :param raw_result: In this case is like the following json: + { + "status": "OK", + "msg": "", + "data": { + "hosts": [ + "host_a", + "host_b", + ... + "host_x", + ] + } + } + + :return: list of InventoryNodes + """ + # Just making more readable the method + host_ls_json = raw_result + + inventory_nodes = [] + + try: + json_resp = json.loads(host_ls_json) + + for host in json_resp["data"]["hosts"]: + inventory_nodes.append(InventoryNode(host, [])) + + except ValueError: + self.log.exception("Malformed json response") + except KeyError: + self.log.exception("Unexpected content in Ansible Runner Service" + " response") + except TypeError: + self.log.exception("Hosts data must be iterable in Ansible Runner " + "Service response") + + return inventory_nodes |