如何让ansible playbook的所有任务限制为ansible_os_family?

How to get all tasks of ansible playbook limit to ansible_os_family?

我需要从 ansible 剧本中获取所有任务的列表并显示它们。

我的问题是像 ansible_os_family == "Debian" 这样的条件没有执行。我看到 所有任务(比如 ansible-playbook rplaybooks/main.yml --list-task)。但是我想要只有那些将被执行的。

我看到两种方式:

  1. 我会检查什么时候到当前 ansible_os_family。 我不知道怎么办 得到它?
  2. 我会在里面找到方法 python-ansible 执行这个 条件

我创建了 class,允许获取 playbook 任务

playbook.py:

import sys
import os
import stat
import json

import ansible.playbook
import ansible.constants as C
import ansible.utils.template
from ansible import errors
from ansible import callbacks
from ansible import utils
from ansible.color import ANSIBLE_COLOR, stringc
from ansible.callbacks import display



if __name__ !='__main__':
            logging.basicConfig(format = u'%(levelname)-8s [%(asctime)s] %(message)s', level = logging.DEBUG, filename = u'/var/log/rderole.log')
class PyPlaybook(object):
    __filtered_tags=['all']
    def _add_inventory(self,hosts=["127.0.0.1"],params={}):
        """ create inventory obj and add it to params """
        playbook=params["playbook"]
        inventory=ansible.inventory.Inventory(hosts)
        inventory.set_playbook_basedir(os.path.dirname(playbook))

        stats = callbacks.AggregateStats()
        playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
        runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)

        params["inventory"]=inventory
        params["stats"]=stats
        params["callbacks"]=playbook_cb
        params["runner_callbacks"]=runner_cb
        return params


    def _playbook_for_hosts(self,hosts=["127.0.0.1"],params={}):
        """ return playbook object with inventory """
        # interface to Playbook class
        """pb=ansible.playbook.PlayBook(
            playbook         = playbook,
            host_list        = host_list,
            module_path      = module_path,
            forks            = forks ,
            timeout          = timeout,
            remote_user      = remote_user,
            remote_pass      = remote_pass,
            sudo_pass        = sudo_pass,
            remote_port      = remote_port,
            transport        = transport,
            private_key_file = private_key_file,
            callbacks        = callbacks,
            runner_callbacks = runner_callbacks,
            stats            = stats,
            sudo             = sudo,
            sudo_user        = sudo_user,
            extra_vars       = extra_vars,
            only_tags        = only_tags,
            skip_tags        = skip_tags,
            subset           = subset,
            inventory        = inventory,
            check            = check,
            diff             = diff,
            any_errors_fatal = any_errors_fatal,
            su               = su,
            su_user          = su_user,
            su_pass          = su_pass ,
            vault_password   = vault_password,
            force_handlers   = force_handlers,
            )"""

        playbook_params=self._add_inventory(hosts,params)
        pb=ansible.playbook.PlayBook(**playbook_params)
        return pb
    def get_tags(self,hosts=["127.0.0.1"],params={}):
        pb=self._playbook_for_hosts(hosts,params)
        playnum = 0
        tags_array={}
        for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs):
            playnum += 1
            play = ansible.playbook.Play(pb, play_ds, play_basedir)
            label = play.name
            matched_tags, unmatched_tags = play.compare_tags(pb.only_tags)
            # Remove skipped tasks
            matched_tags = matched_tags - set(pb.skip_tags)

            unmatched_tags.discard('all')
            unknown_tags = ((set(pb.only_tags) | set(pb.skip_tags)) -
                            (matched_tags | unmatched_tags))

            if unknown_tags:
                continue
            print '  play #%d (%s):' % (playnum, label)

            for task in play.tasks():
                if (set(task.tags).intersection(pb.only_tags) and not
                    set(task.tags).intersection(pb.skip_tags)):
                    if getattr(task, 'name', None) is not None:
                        # meta tasks have no names
                        print ' %s   %s %s' % (task.tags,task.name,task.when)

                        for task_tag in task.tags:
                            #print '>> %s   %s' % (task_tag,task.name)
                            try:
                                tags_array[task_tag].append(task.name)
                            except:
                                tags_array[task_tag]=[]
                                tags_array[task_tag].append(task.name)
            try:
                for tag in self.__filtered_tags:
                    try:
                        del tags_array[tag]
                    except:
                        pass
            except:
                pass
            print json.dumps(tags_array, sort_keys=True, indent=4, separators=(',', ': '))

            return tags_array



if __name__ =='__main__':
    p=PyPlaybook()
    options={'playbook':'/playbooks/rde/main.yml','subset': None,  'private_key_file': None,  'skip_tags': None, 'diff': False, 'check': False, 'remote_user': 'root', 'forks': 5,   'transport': 'local', 'timeout': 10, 'module_path': None}
    #'only_tags':['base'], 'skip_tags':['base']
    #p.run_playbook(["127.0.0.1"],options)
    p.get_tags(["127.0.0.1"],options)

/playbooks/rde/main.yml:

- include: debian.yml 
  when: "ansible_os_family == 'Debian'"
- include: redhat.yml 
  when: "ansible_os_family == 'RedHat'"

redhat.yml

---
- name: Install x2go application RedHat
  yum: name=x2goserver state=present

  when: ansible_os_family == "RedHat"
  tags:
    - remote-access-x2go

debian.yml

---
- name: Add x2go repository
  apt_repository: repo='deb http://ppa.launchpad.net/x2go/stable/ubuntu precise main' state=present
  apt_repository: repo='deb-src http://ppa.launchpad.net/x2go/stable/ubuntu precise main' state=present
  when: ansible_os_family == "Debian"
  tags:
    - remote-access-x2go
- name: Install x2go application
  apt: name=x2goserver update_cache=yes
  apt: name=x2goserver-xsession update_cache=no
  when: ansible_os_family == "Debian"
  tags:
    - remote-access-x2go

python playbook.py

  play #1 (RDE Role):
 ['all', 'remote-access-x2go']   Add x2go repository jinja2_compare ansible_os_family == "Debian"
 ['all', 'remote-access-x2go']   Install x2go application jinja2_compare ansible_os_family == "Debian"
 ['all', 'remote-access-x2go']   Install x2go application RedHat jinja2_compare ansible_os_family == "RedHat"
{   
    "remote-access-x2go": [
        "Add x2go repository",
        "Install x2go application",
        "Install x2go application RedHat"
    ]
}

我认为这不可能。 when 子句的评估被认为是任务执行本身的一部分。唯一的办法就是破解代码。

也许 post ansible group 中的问题,我希望你会得到更自信的 yes/no 答案。

而不是使用 when,您应该直接 include 文件,例如

- include: "{{ ansible_os_family }}.yml"

并确保您已为受支持的系统准备好相关文件。

同时检查:Define Ansible variable in a role with OS specific default which can be easily overridden