从另一个 Ansible 模块调用一个 Ansible 模块?
Calling an Ansible Module from another Ansible Module?
问题
是否可以通过编程方式从另一个 Ansible 模块调用一个 Ansible 模块?
上下文
我一直在通过 Python (ucsmsdk) 和 Ansible 与 Cisco UCS 合作,以创建一种自动化服务配置文件模板(从现在开始为 SPT)的方法。我已经创建了 apis and modules 符合各自 Git 回购协议中设定的标准。
虽然我能够使用 Ansible 剧本创建这些 SPT,但它需要大量重用属性来创建每个单独的项目并遵循它们的长链 parent/child 关系。我想删除所有这些重用并通过提供我需要的所有参数来简化项目的创建,同时保持它们的结构完整。
下面的示例显示了我想要的当前系统。
当前
tasks:
- name: create ls server
ls_server_module:
name: ex
other_args:
creds:
- name: create VNIC Ether
vnic_ether_module:
name: ex_child
parent: ex
other_args:
creds:
- name: create VNIC Ether If (VLAN)
vnic_ether_if_module:
name: ex_child_child
parent: ex_child
creds:
- name: create VNIC Ether
vnic_ether_module:
name: ex_child_2
parent: ex
other_args:
creds:
想要
tasks:
- name: create template
spt_module:
name: ex
other_args:
creds:
LAN:
VNIC:
- name: ex_child
other_args:
vlans:
- ex_child_child
- name: ex_child_2
other_args:
目前,我唯一的障碍是通过调用这些以动态和编程方式创建对象的模块来诱导一些代码重用。
您不能从其他模块中执行一个模块,因为 Ansible 中的模块是独立的实体,打包在控制器上并传送到远程主机执行。
但是有针对这种情况的动作插件。您可以创建动作插件 spt_module
(它将在 Ansible 控制器上本地执行),它可以根据 lan/vnic
参数依次执行几个不同的模块。
这就是您的操作 (spt_module.py
) 插件的样子(非常简单):
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
def run(self, tmp=None, task_vars=None):
result = super(ActionModule, self).run(tmp, task_vars)
vnic_list = self._task.args['LAN']['VNIC']
common_args = {}
common_args['name'] = self._task.args['name']
res = {}
res['create_server'] = self._execute_module(module_name='ls_server_module', module_args=common_args, task_vars=task_vars, tmp=tmp)
for vnic in vnic_list:
module_args = common_args.copy()
module_args['other_args'] = vnic['other_args']
res['vnic_'+vnic['name']] = self._execute_module(module_name='vnic_ether_module', module_args=module_args, task_vars=task_vars, tmp=tmp)
return res
代码未经测试(可能存在错误、拼写错误)。
问题
是否可以通过编程方式从另一个 Ansible 模块调用一个 Ansible 模块?
上下文
我一直在通过 Python (ucsmsdk) 和 Ansible 与 Cisco UCS 合作,以创建一种自动化服务配置文件模板(从现在开始为 SPT)的方法。我已经创建了 apis and modules 符合各自 Git 回购协议中设定的标准。
虽然我能够使用 Ansible 剧本创建这些 SPT,但它需要大量重用属性来创建每个单独的项目并遵循它们的长链 parent/child 关系。我想删除所有这些重用并通过提供我需要的所有参数来简化项目的创建,同时保持它们的结构完整。
下面的示例显示了我想要的当前系统。
当前
tasks:
- name: create ls server
ls_server_module:
name: ex
other_args:
creds:
- name: create VNIC Ether
vnic_ether_module:
name: ex_child
parent: ex
other_args:
creds:
- name: create VNIC Ether If (VLAN)
vnic_ether_if_module:
name: ex_child_child
parent: ex_child
creds:
- name: create VNIC Ether
vnic_ether_module:
name: ex_child_2
parent: ex
other_args:
creds:
想要
tasks:
- name: create template
spt_module:
name: ex
other_args:
creds:
LAN:
VNIC:
- name: ex_child
other_args:
vlans:
- ex_child_child
- name: ex_child_2
other_args:
目前,我唯一的障碍是通过调用这些以动态和编程方式创建对象的模块来诱导一些代码重用。
您不能从其他模块中执行一个模块,因为 Ansible 中的模块是独立的实体,打包在控制器上并传送到远程主机执行。
但是有针对这种情况的动作插件。您可以创建动作插件 spt_module
(它将在 Ansible 控制器上本地执行),它可以根据 lan/vnic
参数依次执行几个不同的模块。
这就是您的操作 (spt_module.py
) 插件的样子(非常简单):
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
def run(self, tmp=None, task_vars=None):
result = super(ActionModule, self).run(tmp, task_vars)
vnic_list = self._task.args['LAN']['VNIC']
common_args = {}
common_args['name'] = self._task.args['name']
res = {}
res['create_server'] = self._execute_module(module_name='ls_server_module', module_args=common_args, task_vars=task_vars, tmp=tmp)
for vnic in vnic_list:
module_args = common_args.copy()
module_args['other_args'] = vnic['other_args']
res['vnic_'+vnic['name']] = self._execute_module(module_name='vnic_ether_module', module_args=module_args, task_vars=task_vars, tmp=tmp)
return res
代码未经测试(可能存在错误、拼写错误)。