如何让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)。但是我想要只有那些将被执行的。
我看到两种方式:
- 我会检查什么时候到当前 ansible_os_family。 我不知道怎么办
得到它?
- 我会在里面找到方法 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
我需要从 ansible 剧本中获取所有任务的列表并显示它们。
我的问题是像 ansible_os_family == "Debian"
这样的条件没有执行。我看到 所有任务(比如 ansible-playbook rplaybooks/main.yml --list-task)。但是我想要只有那些将被执行的。
我看到两种方式:
- 我会检查什么时候到当前 ansible_os_family。 我不知道怎么办 得到它?
- 我会在里面找到方法 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