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
This commit is contained in:
abregman 2018-12-11 08:39:44 +02:00
parent d736ed8ae8
commit 1d40d26c04
6 changed files with 87 additions and 8 deletions

View File

@ -5,6 +5,7 @@ name = "pypi"
[packages] [packages]
tobiko = {editable = true, path = "."} tobiko = {editable = true, path = "."}
ansible = "*"
[dev-packages] [dev-packages]

1
extra-requirements.txt Normal file
View File

@ -0,0 +1 @@
ansible>=2.4.0

View File

@ -39,6 +39,10 @@ class CreateUtil(base.TobikoCMD):
'--stack', '-s', '--stack', '-s',
help="The name of the stack to create.\n" help="The name of the stack to create.\n"
"This is based on the template name in templates dir") "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( parser.add_argument(
'--all', '-a', action='store_true', dest='all', '--all', '-a', action='store_true', dest='all',
help="Create all the stacks defined in Tobiko.") help="Create all the stacks defined in Tobiko.")
@ -62,6 +66,10 @@ class CreateUtil(base.TobikoCMD):
parameters=constants.DEFAULT_PARAMS, parameters=constants.DEFAULT_PARAMS,
wait=wait) wait=wait)
def run_playbook(self, playbook):
"""Executes given playbook."""
self.ansibleManager.run_playbook(playbook, mode='create')
class NoSuchTemplateError(exceptions.TobikoException): class NoSuchTemplateError(exceptions.TobikoException):
message = "No such template. Existing templates:\n%(templates)s" message = "No such template. Existing templates:\n%(templates)s"
@ -70,9 +78,12 @@ class NoSuchTemplateError(exceptions.TobikoException):
def main(): def main():
"""Create CLI main entry.""" """Create CLI main entry."""
create_cmd = CreateUtil() create_cmd = CreateUtil()
create_cmd.create_stacks(stack_name=create_cmd.args.stack, if create_cmd.args.playbook:
all_stacks=create_cmd.args.all, create_cmd.run_playbook(create_cmd.args.playbook)
wait=create_cmd.args.wait) 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__': if __name__ == '__main__':

View File

@ -15,6 +15,12 @@ from __future__ import absolute_import
import os 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 oslo_log import log
from tobiko.common import constants from tobiko.common import constants
@ -26,9 +32,16 @@ LOG = log.getLogger(__name__)
class AnsibleManager(object): class AnsibleManager(object):
"""Manages Ansible entities.""" """Manages Ansible entities."""
def __init__(self, client_manager, templates_dir): def __init__(self, client_manager, playbooks_dir):
self.client_manager = client_manager.heat_client self.client_manager = client_manager
self.playbooks_dir = templates_dir 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): def get_playbooks_names(self, strip_suffix=False):
"""Returns a list of all the files in playbooks dir.""" """Returns a list of all the files in playbooks dir."""
@ -39,3 +52,44 @@ class AnsibleManager(object):
playbooks = [ playbooks = [
f[:-len(constants.TEMPLATE_SUFFIX)] for f in playbooks] f[:-len(constants.TEMPLATE_SUFFIX)] for f in playbooks]
return 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()

View File

@ -11,8 +11,18 @@
project_name: "{{ project_name }}" project_name: "{{ project_name }}"
name: server1 name: server1
image: "{{ image }}" image: "{{ image }}"
key_name: "{{ key }}"
timeout: 200 timeout: 200
flavor: "{{ flavor }}" flavor: "{{ flavor }}"
security_groups: default 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'

View File

@ -8,6 +8,7 @@ minversion = 2.0
deps = deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
-r{toxinidir}/requirements.txt -r{toxinidir}/requirements.txt
-r{toxinidir}/extra-requirements.txt
setenv = setenv =
VIRTUAL_ENV={envdir} VIRTUAL_ENV={envdir}
@ -33,6 +34,7 @@ commands =
deps = deps =
{[tobiko]deps} {[tobiko]deps}
-r{toxinidir}/test-requirements.txt -r{toxinidir}/test-requirements.txt
-r{toxinidir}/extra-requirements.txt
setenv = setenv =
{[tobiko]setenv} {[tobiko]setenv}