Source code for tower_cli.resources.ad_hoc

# Copyright 2015, Ansible, Inc.
# Alan Rominger <arominger@ansible.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import, unicode_literals

import click

from tower_cli import models, resources, exceptions as exc
from tower_cli.api import client
from tower_cli.cli import types
from tower_cli.utils import debug
from tower_cli.utils.data_structures import OrderedDict


[docs]class Resource(models.ExeResource): """A resource for ad hoc commands.""" cli_help = 'Launch commands based on playbook given at runtime.' endpoint = '/ad_hoc_commands/' # Parameters similar to job job_explanation = models.Field(required=False, display=False) created = models.Field(required=False, display=True) status = models.Field(required=False, display=True) elapsed = models.Field(required=False, display=True, type=float) # Parameters similar to job_template job_type = models.Field( default='run', display=False, show_default=True, type=click.Choice(['run', 'check']), ) inventory = models.Field(type=types.Related('inventory')) limit = models.Field(required=False, display=False) credential = models.Field(display=False, type=types.Related('credential')) module_name = models.Field(required=False, display=True, default="command", show_default=True) module_args = models.Field(required=False, display=False) forks = models.Field(type=int, required=False, display=False) verbosity = models.Field( display=False, type=types.MappedChoice([ (0, 'default'), (1, 'verbose'), (2, 'more_verbose'), (3, 'debug'), (4, 'connection'), (5, 'winrm'), ]), required=False, ) become_enabled = models.Field(type=bool, required=False, display=False) diff_mode = models.Field(type=bool, required=False, display=False)
[docs] @resources.command( use_fields_as_options=( 'job_explanation', 'job_type', 'inventory', 'credential', 'module_name', 'module_args', 'forks', 'limit', 'verbosity', 'become_enabled', 'diff_mode', ) ) @click.option('--monitor', is_flag=True, default=False, help='If sent, immediately calls `monitor` on the newly ' 'launched command rather than exiting with a success.') @click.option('--wait', is_flag=True, default=False, help='Monitor the status of the job, but do not print ' 'while job is in progress.') @click.option('--timeout', required=False, type=int, help='If provided with --monitor, this attempt' ' will time out after the given number of seconds. ' 'Does nothing if --monitor is not sent.') def launch(self, monitor=False, wait=False, timeout=None, **kwargs): """Launch a new ad-hoc command. Runs a user-defined command from Ansible Tower, immediately starts it, and returns back an ID in order for its status to be monitored. =====API DOCS===== Launch a new ad-hoc command. :param monitor: Flag that if set, immediately calls ``monitor`` on the newly launched command rather than exiting with a success. :type monitor: bool :param wait: Flag that if set, monitor the status of the job, but do not print while job is in progress. :type wait: bool :param timeout: If provided with ``monitor`` flag set, this attempt will time out after the given number of seconds. :type timeout: int :param `**kwargs`: Fields needed to create and launch an ad hoc command. :returns: Result of subsequent ``monitor`` call if ``monitor`` flag is on; Result of subsequent ``wait`` call if ``wait`` flag is on; dictionary of "id" and "changed" if none of the two flags are on. :rtype: dict :raises tower_cli.exceptions.TowerCLIError: When ad hoc commands are not available in Tower backend. =====API DOCS===== """ # This feature only exists for versions 2.2 and up r = client.get('/') if 'ad_hoc_commands' not in r.json(): raise exc.TowerCLIError('Your host is running an outdated version' 'of Ansible Tower that can not run ' 'ad-hoc commands (2.2 or earlier)') # Pop the None arguments because we have no .write() method in # inheritance chain for this type of resource. This is needed self._pop_none(kwargs) # Actually start the command. debug.log('Launching the ad-hoc command.', header='details') result = client.post(self.endpoint, data=kwargs) command = result.json() command_id = command['id'] # If we were told to monitor the command once it started, then call # monitor from here. if monitor: return self.monitor(command_id, timeout=timeout) elif wait: return self.wait(command_id, timeout=timeout) # Return the command ID and other response data answer = OrderedDict(( ('changed', True), ('id', command_id), )) answer.update(result.json()) return answer