diff --git a/setup.cfg b/setup.cfg index 27bdccdcd..73a347e43 100644 --- a/setup.cfg +++ b/setup.cfg @@ -150,7 +150,6 @@ mistral.actions = tripleo.undercloud.upload_backup_to_swift = tripleo_common.actions.undercloud:UploadUndercloudBackupToSwift tripleo.undercloud.remove_temp_dir = tripleo_common.actions.undercloud:RemoveTempDir # deprecated for pike release, will be removed in queens - tripleo.ansible = tripleo_common.actions.ansible:AnsibleAction tripleo.ansible-playbook = tripleo_common.actions.ansible:AnsiblePlaybookAction tripleo.templates.upload_default = tripleo_common.actions.templates:UploadTemplatesAction # deprecated for rocky release, will be removed in the "S" cycle diff --git a/tripleo_common/actions/ansible.py b/tripleo_common/actions/ansible.py index d93c64815..946598bee 100644 --- a/tripleo_common/actions/ansible.py +++ b/tripleo_common/actions/ansible.py @@ -151,191 +151,6 @@ def write_default_ansible_cfg(work_dir, return ansible_config_path -class AnsibleAction(actions.Action): - """Executes ansible module""" - - def __init__(self, **kwargs): - self._kwargs_for_run = kwargs - self.hosts = self._kwargs_for_run.pop('hosts', None) - self.module = self._kwargs_for_run.pop('module', None) - self.module_args = self._kwargs_for_run.pop('module_args', None) - if self.module_args and isinstance(self.module_args, dict): - self.module_args = json.dumps(self.module_args) - self.limit_hosts = self._kwargs_for_run.pop('limit_hosts', None) - self.remote_user = self._kwargs_for_run.pop('remote_user', None) - self.become = self._kwargs_for_run.pop('become', None) - self.become_user = self._kwargs_for_run.pop('become_user', None) - self.extra_vars = self._kwargs_for_run.pop('extra_vars', None) - if self.extra_vars: - self.extra_vars = json.dumps(self.extra_vars) - self._inventory = self._kwargs_for_run.pop('inventory', None) - self.verbosity = self._kwargs_for_run.pop('verbosity', 5) - self._ssh_private_key = self._kwargs_for_run.pop( - 'ssh_private_key', None) - self.forks = self._kwargs_for_run.pop('forks', None) - self.timeout = self._kwargs_for_run.pop('timeout', None) - self.ssh_extra_args = self._kwargs_for_run.pop('ssh_extra_args', None) - if self.ssh_extra_args: - self.ssh_extra_args = json.dumps(self.ssh_extra_args) - self.ssh_common_args = self._kwargs_for_run.pop( - 'ssh_common_args', None) - if self.ssh_common_args: - self.ssh_common_args = json.dumps(self.ssh_common_args) - self.use_openstack_credentials = self._kwargs_for_run.pop( - 'use_openstack_credentials', False) - self.extra_env_variables = self._kwargs_for_run.pop( - 'extra_env_variables', None) - self.gather_facts = self._kwargs_for_run.pop('gather_facts', False) - - self._work_dir = None - self._remove_work_dir = False - - @property - def work_dir(self): - if self._work_dir: - return self._work_dir - self._work_dir = tempfile.mkdtemp(prefix='ansible-mistral-action') - self._remove_work_dir = True - return self._work_dir - - @property - def inventory(self): - if not self._inventory: - return None - - # NOTE(flaper87): if it's a path, use it - if (isinstance(self._inventory, six.string_types) and - os.path.exists(self._inventory)): - return self._inventory - elif not isinstance(self._inventory, six.string_types): - self._inventory = yaml.safe_dump(self._inventory) - - path = os.path.join(self.work_dir, 'inventory.yaml') - - # NOTE(flaper87): - # We could probably catch parse errors here - # but if we do, they won't be propagated and - # we should not move forward with the action - # if the inventory generation failed - with open(path, 'w') as inventory: - inventory.write(self._inventory) - - self._inventory = path - return path - - @property - def ssh_private_key(self): - if not self._ssh_private_key: - return None - - # NOTE(flaper87): if it's a path, use it - if (isinstance(self._ssh_private_key, six.string_types) and - os.path.exists(self._ssh_private_key)): - return self._ssh_private_key - - path = os.path.join(self.work_dir, 'ssh_private_key') - - # NOTE(flaper87): - # We could probably catch parse errors here - # but if we do, they won't be propagated and - # we should not move forward with the action - # if the inventory generation failed - with open(path, 'w') as ssh_key: - ssh_key.write(self._ssh_private_key) - os.chmod(path, 0o600) - - self._ssh_private_key = path - return path - - def run(self, context): - - if 0 < self.verbosity < 6: - verbosity_option = '-' + ('v' * self.verbosity) - command = ['ansible', self.hosts, verbosity_option, ] - else: - command = ['ansible', self.hosts, ] - - if self.module: - command.extend(['--module-name', self.module]) - - if self.module_args: - command.extend(['--args', self.module_args]) - - if self.limit_hosts: - command.extend(['--limit', self.limit_hosts]) - - if self.become: - command.extend(['--become']) - - if self.become_user: - command.extend(['--become-user', self.become_user]) - - if self.extra_vars: - command.extend(['--extra-vars', self.extra_vars]) - - if self.forks: - command.extend(['--forks', self.forks]) - - if self.ssh_common_args: - command.extend(['--ssh-common-args', self.ssh_common_args]) - - if self.ssh_extra_args: - command.extend(['--ssh-extra-args', self.ssh_extra_args]) - - if self.timeout: - command.extend(['--timeout', self.timeout]) - - if self.inventory: - command.extend(['--inventory-file', self.inventory]) - - if self.extra_env_variables: - if not isinstance(self.extra_env_variables, dict): - msg = "extra_env_variables must be a dict" - return actions.Result(error=msg) - - if self.gather_facts: - command.extend(['--gather-facts', self.gather_facts]) - - try: - ansible_config_path = write_default_ansible_cfg( - self.work_dir, - self.remote_user, - ssh_private_key=self.ssh_private_key) - env_variables = { - 'HOME': self.work_dir, - 'ANSIBLE_LOCAL_TEMP': self.work_dir, - 'ANSIBLE_CONFIG': ansible_config_path - } - - if self.extra_env_variables: - env_variables.update(self.extra_env_variables) - - if self.use_openstack_credentials: - env_variables.update({ - 'OS_AUTH_URL': context.security.auth_uri, - 'OS_USERNAME': context.security.user_name, - 'OS_AUTH_TOKEN': context.security.auth_token, - 'OS_PROJECT_NAME': context.security.project_name}) - - LOG.info('Running ansible command: %s', command) - - stderr, stdout = processutils.execute( - *command, cwd=self.work_dir, - env_variables=env_variables, - log_errors=processutils.LogErrors.ALL) - return {"stderr": stderr, "stdout": stdout, - "log_path": os.path.join(self.work_dir, 'ansible.log')} - finally: - # NOTE(flaper87): clean the mess if debug is disabled. - try: - if not self.verbosity and self._remove_work_dir: - shutil.rmtree(self.work_dir) - except Exception as e: - msg = "An error happened while cleaning work directory: " + e - LOG.error(msg) - return actions.Result(error=msg) - - class AnsiblePlaybookAction(base.TripleOAction): """Executes ansible playbook""" diff --git a/tripleo_common/tests/actions/test_ansible.py b/tripleo_common/tests/actions/test_ansible.py index ea618e68e..1aada2428 100644 --- a/tripleo_common/tests/actions/test_ansible.py +++ b/tripleo_common/tests/actions/test_ansible.py @@ -29,49 +29,6 @@ from tripleo_common.actions import ansible from tripleo_common.tests import base -class AnsibleActionTest(base.TestCase): - - def setUp(self): - super(AnsibleActionTest, self).setUp() - - self.hosts = "127.0.0.2" - self.module = "foo" - self.remote_user = 'fido' - self.become = True - self.become_user = 'root' - self.ctx = mock.MagicMock() - - @mock.patch("tripleo_common.actions.ansible.write_default_ansible_cfg") - @mock.patch("oslo_concurrency.processutils.execute") - def test_run(self, mock_execute, mock_write_cfg): - - mock_execute.return_value = ('', '') - - action = ansible.AnsibleAction( - hosts=self.hosts, module=self.module, remote_user=self.remote_user, - become=self.become, become_user=self.become_user) - ansible_config_path = os.path.join(action.work_dir, 'ansible.cfg') - mock_write_cfg.return_value = ansible_config_path - - action.run(self.ctx) - - env = { - 'HOME': action.work_dir, - 'ANSIBLE_LOCAL_TEMP': action.work_dir, - 'ANSIBLE_CONFIG': ansible_config_path - } - - mock_write_cfg.assert_called_once_with(action.work_dir, - self.remote_user, - ssh_private_key=None) - - mock_execute.assert_called_once_with( - 'ansible', self.hosts, '-vvvvv', '--module-name', self.module, - '--become', '--become-user', self.become_user, env_variables=env, - cwd=action.work_dir, log_errors=processutils.LogErrors.ALL - ) - - class AnsiblePlaybookActionTest(base.TestCase): def setUp(self):