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

时间:2015-03-09 13:12:46

标签: python ansible ansible-playbook

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

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

我看到两种方式:

  1. 我会检查当前的ansible_os_family。 我不知道怎么做 得到它?
  2. 我会在python-ansible中找到方法执行此操作 条件
  3. 我创建了一个允许获取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"
        ]
    }
    

2 个答案:

答案 0 :(得分:1)

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

或许可以在ansible group中发布问题,我希望您能得到更自信的是/否答案。

答案 1 :(得分:0)

您应该直接when直接include,例如

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

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

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