PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/states/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/states/ansiblegate.py |
# # Author: Bo Maryniuk <bo@suse.de> # # Copyright 2017 SUSE LLC # 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. r""" Execution of Ansible modules from within states =============================================== With `ansible.call` these states allow individual Ansible module calls to be made via states. To call an Ansible module function use a :mod:`module.run <salt.states.ansible.call>` state: .. code-block:: yaml some_set_of_tasks: ansible: - system.ping - packaging.os.zypper - name: emacs - state: installed """ import logging import os import sys import salt.fileclient import salt.utils.decorators.path from salt.loader.dunder import __file_client__ from salt.utils.decorators import depends log = logging.getLogger(__name__) __virtualname__ = "ansible" def _file_client(): """ Return a file client If the __file_client__ context is set return it, otherwize create a new file client using __opts__. """ if __file_client__: return __file_client__.value() return salt.fileclient.get_file_client(__opts__) @depends("ansible") class AnsibleState: """ Ansible state caller. """ def get_args(self, argset): """ Get args and kwargs from the argset. :param argset: :return: """ args = [] kwargs = {} for element in argset or []: if isinstance(element, dict): kwargs.update(element) else: args.append(element) return args, kwargs def __call__(self, **kwargs): """ Call Ansible module. :return: """ ret = { "name": kwargs.pop("name"), "changes": {}, "comment": "", "result": True, } for mod_name, mod_params in kwargs.items(): args, kwargs = self.get_args(mod_params) try: ans_mod_out = __salt__[f"ansible.{mod_name}"]( **{"__pub_arg": [args, kwargs]} ) except Exception as err: # pylint: disable=broad-except ans_mod_out = 'Module "{}" failed. Error message: ({}) {}'.format( mod_name, err.__class__.__name__, err ) ret["result"] = False ret["changes"][mod_name] = ans_mod_out return ret def __virtual__(): """ Disable, if Ansible is not available around on the Minion. """ # pylint: disable=unnecessary-lambda setattr(sys.modules[__name__], "call", lambda **kwargs: AnsibleState()(**kwargs)) # pylint: enable=unnecessary-lambda return __virtualname__ def _changes(plays): """ Find changes in ansible return data """ changes = {} for play in plays["plays"]: task_changes = {} for task in play["tasks"]: host_changes = {} for host, data in task["hosts"].items(): if data.get("changed", False) is True: host_changes[host] = data.get("diff", data.get("changes", {})) elif any(x in data for x in ["failed", "skipped", "unreachable"]): host_changes[host] = data.get("results", data.get("msg", {})) if host_changes: task_changes[task["task"]["name"]] = host_changes if task_changes: changes[play["play"]["name"]] = task_changes return changes @salt.utils.decorators.path.which("ansible-playbook") def playbooks(name, rundir=None, git_repo=None, git_kwargs=None, ansible_kwargs=None): """ Run Ansible Playbooks :param name: path to playbook. This can be relative to rundir or the git repo :param rundir: location to run ansible-playbook from. :param git_repo: git repository to clone for ansible playbooks. This is cloned using the `git.latest` state, and is cloned to the `rundir` if specified, otherwise it is clone to the `cache_dir` :param git_kwargs: extra kwargs to pass to `git.latest` state module besides the `name` and `target` :param ansible_kwargs: extra kwargs to pass to `ansible.playbooks` execution module besides the `name` and `target` :return: Ansible playbook output. .. code-block:: yaml run nginx install: ansible.playbooks: - name: install.yml - git_repo: git://github.com/gituser/playbook.git - git_kwargs: rev: master """ ret = { "result": False, "changes": {}, "comment": f"Running playbook {name}", "name": name, } if git_repo: if not isinstance(rundir, str) or not os.path.isdir(rundir): with _file_client() as client: rundir = client._extrn_path(git_repo, "base") log.trace("rundir set to %s", rundir) if not isinstance(git_kwargs, dict): log.debug("Setting git_kwargs to empty dict: %s", git_kwargs) git_kwargs = {} __states__["git.latest"](name=git_repo, target=rundir, **git_kwargs) if not isinstance(ansible_kwargs, dict): log.debug("Setting ansible_kwargs to empty dict: %s", ansible_kwargs) ansible_kwargs = {} if __opts__["test"]: checks = __salt__["ansible.playbooks"]( name, rundir=rundir, check=True, diff=True, **ansible_kwargs ) if "stats" not in checks: ret["comment"] = checks.get("stderr", checks) ret["result"] = False ret["changes"] = {} elif all( not check["changed"] and not check["failures"] and not check["unreachable"] for check in checks["stats"].values() ): ret["comment"] = f"No changes to be made from playbook {name}" ret["result"] = True elif any( check["changed"] and not check["failures"] and not check["unreachable"] for check in checks["stats"].values() ): ret["comment"] = f"Changes will be made from playbook {name}" ret["result"] = None ret["changes"] = _changes(checks) else: ret["comment"] = "There were some issues running the playbook {}".format( name ) ret["result"] = False ret["changes"] = _changes(checks) else: results = __salt__["ansible.playbooks"]( name, rundir=rundir, diff=True, **ansible_kwargs ) if "stats" not in results: ret["comment"] = results.get("stderr", results) ret["result"] = False ret["changes"] = {} elif all( not check["changed"] and not check["failures"] and not check["unreachable"] for check in results["stats"].values() ): ret["comment"] = f"No changes to be made from playbook {name}" ret["result"] = True ret["changes"] = _changes(results) else: ret["changes"] = _changes(results) ret["result"] = all( not check["failures"] and not check["unreachable"] for check in results["stats"].values() ) if ret["result"]: ret["comment"] = f"Changes were made by playbook {name}" else: ret["comment"] = f"There were some issues running the playbook {name}" return ret