def run(validation, cancel_event): C.HOST_KEY_CHECKING = False stats = callbacks.AggregateStats() playbook_callbacks = SilentPlaybookCallbacks(cancel_event) runner_callbacks = callbacks.DefaultRunnerCallbacks() playbook = ansible.playbook.PlayBook( playbook=validation['playbook'], host_list='tripleo-ansible-inventory.py', stats=stats, callbacks=playbook_callbacks, runner_callbacks=runner_callbacks) try: result = playbook.run() except ValidationCancelled: result = {} for host in playbook.inventory.list_hosts(): result[host] = { 'failures': 1, 'unreachable': 0, 'description': "Validation was cancelled.", } for host, status in result.items(): success = status['failures'] == 0 and status['unreachable'] == 0 result[host]['success'] = success return result
def __init__(self, host_list=C.DEFAULT_HOST_LIST, module_path=C.DEFAULT_MODULE_PATH, module_name=C.DEFAULT_MODULE_NAME, module_args=C.DEFAULT_MODULE_ARGS, forks=C.DEFAULT_FORKS, timeout=C.DEFAULT_TIMEOUT, pattern=C.DEFAULT_PATTERN, remote_user=C.DEFAULT_REMOTE_USER, remote_pass=C.DEFAULT_REMOTE_PASS, sudo_pass=C.DEFAULT_SUDO_PASS, remote_port=C.DEFAULT_REMOTE_PORT, background=0, basedir=None, setup_cache=None, transport=C.DEFAULT_TRANSPORT, conditional='True', groups={}, callbacks=None, verbose=False, debug=False, sudo=False, extra_vars=None, module_vars=None, is_playbook=False): if setup_cache is None: setup_cache = {} if basedir is None: basedir = os.getcwd() if callbacks is None: callbacks = ans_callbacks.DefaultRunnerCallbacks() self.callbacks = callbacks self.generated_jid = str(random.randint(0, 999999999999)) self.transport = transport self.connector = ansible.connection.Connection(self, self.transport) if type(host_list) == str: self.host_list, self.groups = self.parse_hosts(host_list) else: self.host_list = host_list self.groups = groups self.setup_cache = setup_cache self.conditional = conditional self.module_path = module_path self.module_name = module_name self.forks = int(forks) self.pattern = pattern self.module_args = module_args self.module_vars = module_vars self.extra_vars = extra_vars self.timeout = timeout self.debug = debug self.verbose = verbose self.remote_user = remote_user self.remote_pass = remote_pass self.remote_port = remote_port self.background = background self.basedir = basedir self.sudo = sudo self.sudo_pass = sudo_pass self.is_playbook = is_playbook euid = pwd.getpwuid(os.geteuid())[0] if self.transport == 'local' and self.remote_user != euid: raise Exception("User mismatch: expected %s, but is %s" % (self.remote_user, euid)) if type(self.module_args) not in [str, unicode, dict]: raise Exception("module_args must be a string or dict: %s" % self.module_args) self._tmp_paths = {} random.seed()
def conf(self): stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.DefaultRunnerCallbacks() res = ansible.playbook.PlayBook( playbook=self.playbook, #'/etc/ansible/playbooks/user.yml', stats=stats, #输出详细结果 callbacks=playbook_cb, runner_callbacks=runner_cb, host_list=self.host_list, extra_vars=self.module_args).run() data = json.dumps(res, indent=4) data_list = [] for k, v in json.loads(data).items(): data = {} for x, y in v.items(): data['ip'] = k data[x] = y data_list.append(data) if data_list: return data_list else: return False
def playbook_run(playbook): playbooks_path = current_app.config.get('playbooks_path') inventory_path = os.path.join(playbooks_path, 'inventory') callbacks_path = os.path.join(playbooks_path, 'callback_plugins') os.environ.update({ 'SAI_REMOTE_ADDR': request.remote_addr, 'SAI_HTTP_HOST': request.host, 'SAI_QUERY_STRING': request.query_string, 'SAI_REQUEST_URI': request.path, 'SAI_PATH_INFO': request.path, 'SAI_REMOTE_USER': request.remote_user if request.remote_user else '', 'SAI_PLAYBOOK': playbook, }) if request.method.upper() == 'POST': keys = [] for key, value in request.form.iteritems(): keys.append(key.upper()) os.environ['SAI_POST_%s' % key.upper()] = value os.environ['SAI_POST_KEYS'] = ','.join(keys) try: subset = (request.args.get('subset').replace(',',':') .replace(";",":").lstrip('@')) subset_split = subset.split(':') except AttributeError: subset = None subset_split = [] only_tags = str(request.args.get('tags', 'all')).split(',') try: skip_tags = request.args.get('skip_tags').split(',') except AttributeError: skip_tags = None try: inventory = ansible.inventory.Inventory(inventory_path) except errors.AnsibleError as e: if not os.path.isdir(inventory_path): msg = ('The path to the inventory directory ' '(%s) does not exist.' % inventory_path) else: msg = '%s' % e current_app.logger.error(msg) return (jsonify(playbook=playbook, hosts=[], tags=only_tags, skip_tags=skip_tags, subset=subset_split, state='error', msg='Inventory directory missing or non-parsable inventory ' 'file'), 500) else: inventory.subset(subset) if len(inventory.list_hosts()) == 0: current_app.logger.error('No hosts matched within the ' 'inventory directory (%s).' % inventory_path) return (jsonify(playbook=playbook, hosts=inventory.list_hosts(), tags=only_tags, skip_tags=skip_tags, subset=subset_split, state='error', msg='No hosts matched'), 400) files = ['%s%s' % (playbook, ext) for ext in C.YAML_FILENAME_EXTENSIONS] for possible_file in files: playbook_file = os.path.join(playbooks_path, possible_file) if not os.path.isfile(playbook_file): playbook_file = None else: break if playbook_file is None: current_app.logger.error('Playbook (%s) not found' % playbook) return (jsonify(playbook=playbook, hosts=inventory.list_hosts(), tags=only_tags, skip_tags=skip_tags, subset=subset_split, state='error', msg='Playbook not found'), 404) inventory.set_playbook_basedir(playbooks_path) stats = callbacks.AggregateStats() playbook_cb = PlaybookCallbacks() runner_cb = callbacks.DefaultRunnerCallbacks() pb = ansible.playbook.PlayBook( playbook=playbook_file, inventory=inventory, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, only_tags=only_tags, skip_tags=skip_tags, ) t = PlaybookRun(sai.app, playbook_cb, pb) t.start() return (jsonify(playbook=playbook, hosts=inventory.list_hosts(), tags=only_tags, skip_tags=skip_tags, subset=subset_split, state='accepted', msg='accepted'), 202)
def __init__(self, host_list=C.DEFAULT_HOST_LIST, module_path=C.DEFAULT_MODULE_PATH, module_name=C.DEFAULT_MODULE_NAME, module_args=C.DEFAULT_MODULE_ARGS, forks=C.DEFAULT_FORKS, timeout=C.DEFAULT_TIMEOUT, pattern=C.DEFAULT_PATTERN, remote_user=C.DEFAULT_REMOTE_USER, remote_pass=C.DEFAULT_REMOTE_PASS, remote_port=C.DEFAULT_REMOTE_PORT, private_key_file=C.DEFAULT_PRIVATE_KEY_FILE, sudo_pass=C.DEFAULT_SUDO_PASS, background=0, basedir=None, setup_cache=None, transport=C.DEFAULT_TRANSPORT, conditional='True', callbacks=None, debug=False, sudo=False, sudo_user=C.DEFAULT_SUDO_USER, module_vars=None, is_playbook=False, inventory=None): """ host_list : path to a host list file, like /etc/ansible/hosts module_path : path to modules, like /usr/share/ansible module_name : which module to run (string) module_args : args to pass to the module (string) forks : desired level of paralellism (hosts to run on at a time) timeout : connection timeout, such as a SSH timeout, in seconds pattern : pattern or groups to select from in inventory remote_user : connect as this remote username remote_pass : supply this password (if not using keys) remote_port : use this default remote port (if not set by the inventory system) private_key_file : use this private key as your auth key sudo_user : If you want to sudo to a user other than root. sudo_pass : sudo password if using sudo and sudo requires a password background : run asynchronously with a cap of this many # of seconds (if not 0) basedir : paths used by modules if not absolute are relative to here setup_cache : this is a internalism that is going away transport : transport mode (paramiko, local) conditional : only execute if this string, evaluated, is True callbacks : output callback class sudo : log in as remote user and immediately sudo to root module_vars : provides additional variables to a template. FIXME: factor this out is_playbook : indicates Runner is being used by a playbook. affects behavior in various ways. inventory : inventory object, if host_list is not provided """ if setup_cache is None: setup_cache = {} if basedir is None: basedir = os.getcwd() if callbacks is None: callbacks = ans_callbacks.DefaultRunnerCallbacks() self.callbacks = callbacks self.generated_jid = str(random.randint(0, 999999999999)) self.sudo_user = sudo_user self.transport = transport self.connector = connection.Connection(self, self.transport, self.sudo_user) if inventory is None: self.inventory = ansible.inventory.Inventory(host_list) else: self.inventory = inventory if module_vars is None: module_vars = {} self.setup_cache = setup_cache self.conditional = conditional self.module_path = module_path self.module_name = module_name self.forks = int(forks) self.pattern = pattern self.module_args = module_args self.module_vars = module_vars self.timeout = timeout self.debug = debug self.remote_user = remote_user self.remote_pass = remote_pass self.remote_port = remote_port self.private_key_file = private_key_file self.background = background self.basedir = basedir self.sudo = sudo self.sudo_pass = sudo_pass self.is_playbook = is_playbook euid = pwd.getpwuid(os.geteuid())[0] if self.transport == 'local' and self.remote_user != euid: raise Exception("User mismatch: expected %s, but is %s" % (self.remote_user, euid)) if type(self.module_args) not in [str, unicode, dict]: raise Exception("module_args must be a string or dict: %s" % self.module_args) self._tmp_paths = {} random.seed()
def setup_cluster(self, cluster): """Configures the cluster according to the node_kind to ansible group matching. This method is idempotent and therefore can be called multiple times without corrupting the cluster configuration. :param cluster: cluster to configure :type cluster: :py:class:`elasticluster.cluster.Cluster` :return: True on success, False otherwise. Please note, if nothing has to be configures True is returned :raises: `AnsibleError` if the playbook can not be found or playbook is corrupt """ inventory_path = self._build_inventory(cluster) private_key_file = cluster.user_key_private # update ansible constants ansible_constants.HOST_KEY_CHECKING = False ansible_constants.DEFAULT_PRIVATE_KEY_FILE = private_key_file ansible_constants.DEFAULT_SUDO_USER = self._sudo_user ansible_constants.ANSIBLE_SSH_PIPELINING = self.ssh_pipelining # check paths if not inventory_path: # No inventory file has been created, maybe an # invalid calss has been specified in config file? Or none? # assume it is fine. elasticluster.log.info("No setup required for this cluster.") return True if not os.path.exists(inventory_path): raise AnsibleError("inventory file `%s` could not be found" % inventory_path) # ANTONIO: These should probably be configuration error # instead, and should probably checked inside __init__(). if not os.path.exists(self._playbook_path): raise AnsibleError("playbook `%s` could not be found" % self._playbook_path) if not os.path.isfile(self._playbook_path): raise AnsibleError("the playbook `%s` is not a file" % self._playbook_path) elasticluster.log.debug("Using playbook file %s.", self._playbook_path) stats = anscb.AggregateStats() playbook_cb = ElasticlusterPbCallbacks(verbose=0) runner_cb = anscb.DefaultRunnerCallbacks() if elasticluster.log.level <= logging.INFO: playbook_cb = anscb.PlaybookCallbacks() runner_cb = anscb.PlaybookRunnerCallbacks(stats) pb = PlayBook( playbook=self._playbook_path, host_list=inventory_path, callbacks=playbook_cb, runner_callbacks=runner_cb, forks=10, stats=stats, become=self._sudo, become_user=self._sudo_user, private_key_file=private_key_file, ) try: status = pb.run() except AnsibleError as e: elasticluster.log.error( "could not execute ansible playbooks. message=`%s`", str(e)) return False # Check ansible status. cluster_failures = False for host, hoststatus in status.items(): if hoststatus['unreachable']: elasticluster.log.error( "Host `%s` is unreachable, " "please re-run elasticluster setup", host) cluster_failures = True if hoststatus['failures']: elasticluster.log.error( "Host `%s` had %d failures: please re-run elasticluster " "setup or check the Ansible playbook `%s`" % (host, hoststatus['failures'], self._playbook_path)) cluster_failures = True if not cluster_failures: elasticluster.log.info("Cluster correctly configured.") # ANTONIO: TODO: We should return an object to identify if # the cluster was correctly configured, if we had # temporary errors or permanent errors. return True return False
sudo_pass=C.DEFAULT_SUDO_PASS, remote_port=C.DEFAULT_REMOTE_PORT, background=0, basedir=None, setup_cache=None, transport=C.DEFAULT_TRANSPORT, conditional='True', groups={}, callbacks=None, verbose=False, <<<<<<< HEAD debug=False, sudo=False, extra_vars=None, module_vars=None, is_playbook=False): ======= debug=False, sudo=False, extra_vars=None, module_vars=None, inventory=None): >>>>>>> remote if setup_cache is None: setup_cache = {} if basedir is None: basedir = os.getcwd() if callbacks is None: callbacks = ans_callbacks.DefaultRunnerCallbacks() self.callbacks = callbacks self.generated_jid = str(random.randint(0, 999999999999)) self.transport = transport self.connector = ansible.connection.Connection(self, self.transport) if inventory is None: self.inventory = ansible.inventory.Inventory(host_list, extra_vars) else: self.inventory = inventory self.setup_cache = setup_cache self.conditional = conditional self.module_path = module_path