21148a1833581f1dbae19fe0d170ccb61fd1b18c
[functest-xtesting.git] / xtesting / core / ansible.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2021 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 """Implement a Xtesting driver to run any Ansible playbook."""
11
12 import logging
13 import os
14 import shutil
15 import time
16
17 import ansible_runner
18
19 from xtesting.core import testcase
20
21
22 class Ansible(testcase.TestCase):
23     """Class designed to run any Ansible playbook via ansible-runner."""
24
25     __logger = logging.getLogger(__name__)
26
27     def check_requirements(self):
28         """Check if ansible-playbook is in $PATH"""
29         self.is_skipped = not shutil.which("ansible-playbook")
30         if self.is_skipped:
31             self.__logger.warning("ansible-playbook is missing")
32
33     def run(self, **kwargs):
34         """ Wrap ansible_runner.interface.run()
35
36         It calls ansible_runner.interface.run() by converting the testcase
37         description data to kwargs. It only overrides quiet and artifact_dir to
38         implement the Xtesting behavior.
39
40         Following the playbook logic, criteria is considered as boolean
41         whatever the value set in testcases.yaml.
42
43         Args:
44             kwargs: Arbitrary keyword arguments.
45
46         Returns:
47             EX_OK if the playbook ran well.
48             EX_RUN_ERROR otherwise.
49         """
50         status = self.EX_RUN_ERROR
51         self.start_time = time.time()
52         if ("private_data_dir" in kwargs and
53                 os.path.isdir(kwargs['private_data_dir'])):
54             try:
55                 if not os.path.exists(self.res_dir):
56                     os.makedirs(self.res_dir)
57                 kwargs["quiet"] = True
58                 kwargs["artifact_dir"] = self.res_dir
59                 runner = ansible_runner.run(**kwargs)
60                 self.details = runner.stats
61                 if runner.rc == 0:
62                     self.result = 100
63                 status = self.EX_OK
64             except Exception:  # pylint: # pylint: disable=broad-except
65                 self.__logger.exception("Cannot execute the playbook")
66         else:
67             self.__logger.error(
68                 "Please set a relevant private_data_dir in testcases.yaml")
69         self.stop_time = time.time()
70         return status