From 1d40d26c046dfeef86aa0e9aff2e157421906f8e Mon Sep 17 00:00:00 2001 From: abregman Date: Tue, 11 Dec 2018 08:39:44 +0200 Subject: [PATCH] Add method to Ansible manager to run playbooks This will allow us to support resources creation by using Ansible playbooks. Also, updated the floatinip playbook to include tasks for removing an istnace. As opposed to Heat, where we can just specify the stack name to remove it, to remove Ansible resources we need to specify their names (since there is no bundling of resources). Also, updated pipfile with Ansible requirement and removed walk assert since there is no need to test it, it doesn't tells us anything about Tobiko funcionaility. Change-Id: I7581818934fca635ddb9b037ecee7ceae7a02010 --- Pipfile | 1 + extra-requirements.txt | 1 + tobiko/cmd/create.py | 17 +++++- tobiko/common/managers/ansible.py | 60 ++++++++++++++++++- .../scenario/playbooks/test_floatingip.yaml | 14 ++++- tox.ini | 2 + 6 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 extra-requirements.txt diff --git a/Pipfile b/Pipfile index 116b02ecb..ab6757e36 100644 --- a/Pipfile +++ b/Pipfile @@ -5,6 +5,7 @@ name = "pypi" [packages] tobiko = {editable = true, path = "."} +ansible = "*" [dev-packages] diff --git a/extra-requirements.txt b/extra-requirements.txt new file mode 100644 index 000000000..f3a3f524c --- /dev/null +++ b/extra-requirements.txt @@ -0,0 +1 @@ +ansible>=2.4.0 diff --git a/tobiko/cmd/create.py b/tobiko/cmd/create.py index b5f61d58f..3821463cd 100644 --- a/tobiko/cmd/create.py +++ b/tobiko/cmd/create.py @@ -39,6 +39,10 @@ class CreateUtil(base.TobikoCMD): '--stack', '-s', help="The name of the stack to create.\n" "This is based on the template name in templates dir") + parser.add_argument( + '--playbook', '-p', + help="The name of the playbook to execute.\n" + "This is based on the playbook name in playbooks dir") parser.add_argument( '--all', '-a', action='store_true', dest='all', help="Create all the stacks defined in Tobiko.") @@ -62,6 +66,10 @@ class CreateUtil(base.TobikoCMD): parameters=constants.DEFAULT_PARAMS, wait=wait) + def run_playbook(self, playbook): + """Executes given playbook.""" + self.ansibleManager.run_playbook(playbook, mode='create') + class NoSuchTemplateError(exceptions.TobikoException): message = "No such template. Existing templates:\n%(templates)s" @@ -70,9 +78,12 @@ class NoSuchTemplateError(exceptions.TobikoException): def main(): """Create CLI main entry.""" create_cmd = CreateUtil() - create_cmd.create_stacks(stack_name=create_cmd.args.stack, - all_stacks=create_cmd.args.all, - wait=create_cmd.args.wait) + if create_cmd.args.playbook: + create_cmd.run_playbook(create_cmd.args.playbook) + else: + create_cmd.create_stacks(stack_name=create_cmd.args.stack, + all_stacks=create_cmd.args.all, + wait=create_cmd.args.wait) if __name__ == '__main__': diff --git a/tobiko/common/managers/ansible.py b/tobiko/common/managers/ansible.py index 1abb5515f..e4018b84e 100644 --- a/tobiko/common/managers/ansible.py +++ b/tobiko/common/managers/ansible.py @@ -15,6 +15,12 @@ from __future__ import absolute_import import os +from collections import namedtuple + +from ansible.executor import playbook_executor +from ansible.inventory.manager import InventoryManager +from ansible.parsing.dataloader import DataLoader +from ansible.vars.manager import VariableManager from oslo_log import log from tobiko.common import constants @@ -26,9 +32,16 @@ LOG = log.getLogger(__name__) class AnsibleManager(object): """Manages Ansible entities.""" - def __init__(self, client_manager, templates_dir): - self.client_manager = client_manager.heat_client - self.playbooks_dir = templates_dir + def __init__(self, client_manager, playbooks_dir): + self.client_manager = client_manager + self.playbooks_dir = playbooks_dir + self.loader = DataLoader() + self.inventory = InventoryManager(loader=self.loader, + sources='localhost,') + self.variable_manager = VariableManager(loader=self.loader, + inventory=self.inventory) + self.options = self.get_options() + self.passwords = dict(vault_pass='secret') def get_playbooks_names(self, strip_suffix=False): """Returns a list of all the files in playbooks dir.""" @@ -39,3 +52,44 @@ class AnsibleManager(object): playbooks = [ f[:-len(constants.TEMPLATE_SUFFIX)] for f in playbooks] return playbooks + + def get_options(self): + """Returns namedtuple of Ansible options.""" + Options = namedtuple('Options', ['connection', 'module_path', + 'forks', 'become', 'become_method', + 'become_user', 'check', 'diff', + 'listhosts', 'listtasks', + 'listtags', 'syntax']) + + options = Options(connection='local', module_path=['/to/mymodules'], + forks=10, become=None, become_method=None, + become_user=None, check=False, diff=False, + listhosts=False, + listtasks=False, listtags=False, syntax=False) + + return options + + def run_playbook(self, playbook, mode='create'): + """Executes given playbook.""" + playbook_path = self.playbooks_dir + '/' + playbook + + extra_vars = {'mode': mode, + 'auth_url': self.client_manager.credentials['auth_url'], + 'username': self.client_manager.credentials['username'], + 'project_name': self.client_manager.credentials[ + 'project_name'], + 'image': constants.DEFAULT_PARAMS['image'], + 'flavor': constants.DEFAULT_PARAMS['flavor'], + 'password': self.client_manager.credentials['password']} + + self.variable_manager.extra_vars = extra_vars + + pb_executor = playbook_executor.PlaybookExecutor( + playbooks=[playbook_path], + inventory=self.inventory, + variable_manager=self.variable_manager, + loader=self.loader, + options=self.options, + passwords=self.passwords) + + pb_executor.run() diff --git a/tobiko/tests/scenario/playbooks/test_floatingip.yaml b/tobiko/tests/scenario/playbooks/test_floatingip.yaml index 8ce7d99a1..bac374cd3 100644 --- a/tobiko/tests/scenario/playbooks/test_floatingip.yaml +++ b/tobiko/tests/scenario/playbooks/test_floatingip.yaml @@ -11,8 +11,18 @@ project_name: "{{ project_name }}" name: server1 image: "{{ image }}" - key_name: "{{ key }}" timeout: 200 flavor: "{{ flavor }}" security_groups: default - auto_ip: yes + when: mode == 'create' + + - name: Remove instance + os_server: + state: absent + auth: + auth_url: "{{ auth_url }}" + username: "{{ username }}" + password: "{{ password }}" + project_name: "{{ project_name }}" + name: server1 + when: mode == 'delete' diff --git a/tox.ini b/tox.ini index 7c2ac11f1..cfa2ecd65 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,7 @@ minversion = 2.0 deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -r{toxinidir}/requirements.txt + -r{toxinidir}/extra-requirements.txt setenv = VIRTUAL_ENV={envdir} @@ -33,6 +34,7 @@ commands = deps = {[tobiko]deps} -r{toxinidir}/test-requirements.txt + -r{toxinidir}/extra-requirements.txt setenv = {[tobiko]setenv}