自定义 Ansible 模块给参数额外的参数错误
Custom Ansible module is giving param extra params error
我正在尝试在 amazon-ec2 中实现类似主机名的模块和我的目标机器。但是当我 运行 时,脚本会给我以下错误:
[ansible-user@ansible-master ~]$ ansible node1 -m edit_hostname.py -a node2
ERROR! this task 'edit_hostname.py' has extra params, which is only allowed in the following modules: meta, group_by, add_host, include_tasks, import_role, raw, set_fact, command, win_shell, import_tasks, script, shell, include_vars, include_role, include, win_command
我的模块是这样的:
#!/usr/bin/python
from ansible.module_utils.basic import *
try:
import json
except ImportError:
import simplejson as json
def write_to_file(module, hostname, hostname_file):
try:
with open(hostname_file, 'w+') as f:
try:
f.write("%s\n" %hostname)
finally:
f.close()
except Exception:
err = get_exception()
module.fail_json(msg="failed to write to the /etc/hostname file")
def main():
hostname_file = '/etc/hostname'
module = AnsibleModule(argument_spec=dict(name=dict(required=True, type=str)))
name = module.params['name']
write_to _file(module, name, hostname_file)
module.exit_json(changed=True, meta=name)
if __name__ == "__main__":
main()
我不知道我在哪里犯了错误。任何帮助将不胜感激。谢谢你。
在开发新模块时,我会推荐使用boilerplate described in the documentation。这也表明您需要使用 AnsibleModule
来定义参数。
在您的 main
中,您应该添加如下内容:
def main():
# define available arguments/parameters a user can pass to the module
module_args = dict(
name=dict(type='str', required=True)
)
# seed the result dict in the object
# we primarily care about changed and state
# change is if this module effectively modified the target
# state will include any data that you want your module to pass back
# for consumption, for example, in a subsequent task
result = dict(
changed=False,
original_hostname='',
hostname=''
)
module = AnsibleModule(
argument_spec=module_args
supports_check_mode=False
)
# manipulate or modify the state as needed (this is going to be the
# part where your module will do what it needs to do)
result['original_hostname'] = module.params['name']
result['hostname'] = 'goodbye'
# use whatever logic you need to determine whether or not this module
# made any modifications to your target
result['changed'] = True
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
module.exit_json(**result)
然后,你可以这样调用模块:
ansible node1 -m mymodule.py -a "name=myname"
ERROR! this task 'edit_hostname.py' has extra params, which is only allowed in the following modules: meta, group_by, add_host, include_tasks, import_role, raw, set_fact, command, win_shell, import_tasks, script, shell, include_vars, include_role, include, win_command
正如您的错误消息所解释的,只有有限数量的模块支持匿名默认参数。在您的自定义模块中,您创建的参数称为 name
。此外,您不应在模块名称中包含 .py
扩展名。你必须像这样调用你的模块作为一个临时命令:
$ ansible node1 -m edit_hostname -a name=node2
我没有测试您的模块代码,因此您可能还有更多错误需要修复。
与此同时,我仍然强烈建议您按照@Simon 的回答中的建议使用ansible 文档中的默认样板文件。
我正在尝试在 amazon-ec2 中实现类似主机名的模块和我的目标机器。但是当我 运行 时,脚本会给我以下错误:
[ansible-user@ansible-master ~]$ ansible node1 -m edit_hostname.py -a node2
ERROR! this task 'edit_hostname.py' has extra params, which is only allowed in the following modules: meta, group_by, add_host, include_tasks, import_role, raw, set_fact, command, win_shell, import_tasks, script, shell, include_vars, include_role, include, win_command
我的模块是这样的:
#!/usr/bin/python
from ansible.module_utils.basic import *
try:
import json
except ImportError:
import simplejson as json
def write_to_file(module, hostname, hostname_file):
try:
with open(hostname_file, 'w+') as f:
try:
f.write("%s\n" %hostname)
finally:
f.close()
except Exception:
err = get_exception()
module.fail_json(msg="failed to write to the /etc/hostname file")
def main():
hostname_file = '/etc/hostname'
module = AnsibleModule(argument_spec=dict(name=dict(required=True, type=str)))
name = module.params['name']
write_to _file(module, name, hostname_file)
module.exit_json(changed=True, meta=name)
if __name__ == "__main__":
main()
我不知道我在哪里犯了错误。任何帮助将不胜感激。谢谢你。
在开发新模块时,我会推荐使用boilerplate described in the documentation。这也表明您需要使用 AnsibleModule
来定义参数。
在您的 main
中,您应该添加如下内容:
def main():
# define available arguments/parameters a user can pass to the module
module_args = dict(
name=dict(type='str', required=True)
)
# seed the result dict in the object
# we primarily care about changed and state
# change is if this module effectively modified the target
# state will include any data that you want your module to pass back
# for consumption, for example, in a subsequent task
result = dict(
changed=False,
original_hostname='',
hostname=''
)
module = AnsibleModule(
argument_spec=module_args
supports_check_mode=False
)
# manipulate or modify the state as needed (this is going to be the
# part where your module will do what it needs to do)
result['original_hostname'] = module.params['name']
result['hostname'] = 'goodbye'
# use whatever logic you need to determine whether or not this module
# made any modifications to your target
result['changed'] = True
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
module.exit_json(**result)
然后,你可以这样调用模块:
ansible node1 -m mymodule.py -a "name=myname"
ERROR! this task 'edit_hostname.py' has extra params, which is only allowed in the following modules: meta, group_by, add_host, include_tasks, import_role, raw, set_fact, command, win_shell, import_tasks, script, shell, include_vars, include_role, include, win_command
正如您的错误消息所解释的,只有有限数量的模块支持匿名默认参数。在您的自定义模块中,您创建的参数称为 name
。此外,您不应在模块名称中包含 .py
扩展名。你必须像这样调用你的模块作为一个临时命令:
$ ansible node1 -m edit_hostname -a name=node2
我没有测试您的模块代码,因此您可能还有更多错误需要修复。
与此同时,我仍然强烈建议您按照@Simon 的回答中的建议使用ansible 文档中的默认样板文件。