Python 自制的Ansible模块有;设置错误:没有名为FabricVcon的模块; 问题
在测试我自己的Ansible模块时,我遇到了一个特殊的错误:Python 自制的Ansible模块有;设置错误:没有名为FabricVcon的模块; 问题,python,python-2.7,automation,ansible,cisco,Python,Python 2.7,Automation,Ansible,Cisco,在测试我自己的Ansible模块时,我遇到了一个特殊的错误:“安装错误:没有名为FabricVcon的模块” 然而,当用Python测试模块的基本API(也是自制的)时,代码是无错误的。我很困惑,因为我在其他基础API中使用的Ansible模块模板是相同的,只是交换了相关信息。以前的所有类似模块都可以工作。为了清楚起见,我开发的Ansible模块使用了我开发的API Python文件。该Python API文件实现了一个官方支持的Cisco Python库 编辑:问题的一部分在于错误代码本身。u
“安装错误:没有名为FabricVcon的模块”
然而,当用Python测试模块的基本API(也是自制的)时,代码是无错误的。我很困惑,因为我在其他基础API中使用的Ansible模块模板是相同的,只是交换了相关信息。以前的所有类似模块都可以工作。为了清楚起见,我开发的Ansible模块使用了我开发的API Python文件。该Python API文件实现了一个官方支持的Cisco Python库 编辑:问题的一部分在于错误代码本身。ucsmsdk基类是FabricVCon,而错误告诉我它找不到FabricVCon。区别在于名称中的第二个C。在发布问题之前,我对代码进行了更改,以确保使用了FabricVCon,但错误仍然存在 上下文 我目前正在使用Ansible通过Python中的ucsmsdk自动创建和修改服务配置文件模板。我一直在为我自己的CiscoUcs团队的ucsm_API和ucsm ansible回购协议做贡献,使用他们的文件作为我自己工作的指南。我已经安装了我自己的repo中的文件,并且运行正常,除了这一个。下面我已经为这个问题添加了相关的代码,但是如果您发现需要更多的工作,请参阅我的 代码 test_fabric.yml 织物_vcon.py (最后注释掉的是我对Python代码本身的测试) 解决方案 原来Ansible是在
/~/.local/lib/python2.7/site packages/ucsm_api-0.9.0.0-py2.7.egg/ucsm_api
中查找ucsm_api文件,而不是
/usr/lib/python2.7/site packages/ucsm_api-0.9.0.0-py2.7.egg/ucsm_api
删除本地版本并从计算机版本复制解决了问题
我是怎么发现它的
我嵌入了行导入pdb;pdb.set_trace()
在结构模块文件的setup_fabric_vcon(服务器、模块)
函数中,仅在导入语句之后
运行python/[property\u path]/fabric\u vcon\u module.py/[property\u path]/args\u fabric.json
并在pdb中逐行移动表明错误来自fabric\u vcon\u创建(handle=server,**args\u mo)
行
我重新运行pdb以进入该函数,对该函数的调用向我显示了正在访问的库的文件位置
JSON文件
解决方案
原来Ansible是在/~/.local/lib/python2.7/site packages/ucsm_api-0.9.0.0-py2.7.egg/ucsm_api
中查找ucsm_api文件,而不是
/usr/lib/python2.7/site packages/ucsm_api-0.9.0.0-py2.7.egg/ucsm_api
删除本地版本并从计算机版本复制解决了问题
我是怎么发现它的
我嵌入了行导入pdb;pdb.set_trace()
在结构模块文件的setup_fabric_vcon(服务器、模块)
函数中,仅在导入语句之后
运行python/[property\u path]/fabric\u vcon\u module.py/[property\u path]/args\u fabric.json
并在pdb中逐行移动表明错误来自fabric\u vcon\u创建(handle=server,**args\u mo)
行
我重新运行pdb以进入该函数,对该函数的调用向我显示了正在访问的库的文件位置
JSON文件
您是否确认正在使用与Ansible相同的路径设置运行相同的Python?@techraf-是的。我对我的问题进行了编辑,以提供一些相关的补充信息。“编辑过”吗?日志历史记录中没有任何编辑。@techraf,请再次检查。它们确实是刚刚发布的。你确认过你正在使用与Ansible相同的路径设置运行相同的Python吗?@techraf-是的,我确认过。我对我的问题进行了编辑,以提供一些相关的补充信息。“编辑过”吗?日志历史记录中没有任何编辑。@techraf,请再次检查。他们实际上是刚刚发布的。
---
- name: test the test the fabric_vcon_module
connection: local
hosts: localhost
tasks:
- name: Make the fabric vcon now
fabric_vcon_module:
id: "1"
ls_server_dn: "org-root/org-VM/ls-SCALEIO"
fabric: "NONE"
inst_type: "manual"
placement: "physical"
select: "all"
share: "shared"
transport: "ethernet, fc"
state: present
ucs_ip: "IP"
ucs_username: "USER"
ucs_password: "PWD"
"""
This module intends on creating higher level api calls for establishing an
Fabric Vcon
"""
from ucsmsdk.ucsexception import UcsOperationError
def fabric_vcon_create(handle, id, ls_server_dn, fabric='NONE',
inst_type="manual", placement="physical", select="all",
share="shared", transport="ethernet", **kwargs):
"""
create fabric vcon
Args:
handle (UcsHandle)
id (string): '1' or '2' or '3' or '4'
ls_server_dn (string):
fabric (string): 'A' or 'B' or 'any' or 'NONE'
inst_type (string): 'auto' or 'manual' or 'policy'
placement (string): 'auto' or 'physical'
select (string): 'all' or 'assigned-only' or 'dynamic-only' or
'exclude-dynamic' or 'exclude-unassigned' or
'exclude-usnic' or 'unassigned-only' or 'usnic-only'
share (string): 'different-transport' or 'exclusive-only' or
'exclusive-preferred' or 'same-transport' or 'shared'
transport (string):
Returns:
FabricVCon: managed object
Raises:
UcsOperationError: if LsServer is not present
Example:
"""
from ucsmsdk.mometa.fabric.FabricVCon import FabricVCon
obj = handle.query_dn(ls_server_dn)
if not obj:
raise UcsOperationError("fabric_vcon_create", "LsServer '%s' does not \
exist" % ls_server_dn)
mo = FabricVCon(parent_mo_or_dn=obj, id=id, fabric=fabric,
inst_type=inst_type, placement=placement, select=select,
share=share, transport=transport)
mo.set_prop_multiple(**kwargs)
handle.add_mo(mo, modify_present=True)
handle.commit()
return mo
def fabric_vcon_get(handle, id, ls_server_dn, caller="fabric_vcon_get"):
"""
get fabric vcon
Args:
handle (UcsHandle)
id (string):
ls_server_dn (string):
caller (string):
Returns:
FabricVCon: managed object
Raises:
UcsOperationError: if the FabricVCon is not present
Example:
"""
dn = ls_server_dn + "/vcon-" + id
mo = handle.query_dn(dn)
if mo is None:
raise UcsOperationError(caller, "FabricVCon '%s' does not exist" % dn)
return mo
def fabric_vcon_exists(handle, id, ls_server_dn, **kwargs):
"""
checks if fabric vcon exists
Args:
handle(UcsHandle)
id (string): ls server name
ls_server_dn (string): location to place ls server
**kwargs: key-value pair of managed object(MO) property and value, Use
'print(ucscoreutils.get_meta_info(<classid>).config_props)'
to get all configurable properties of class
Returns:
(True/False, FabricVCon mo/None)
Raises:
None
Example:
"""
try:
mo = fabric_vcon_get(handle=handle, id=id, ls_server_dn=ls_server_dn,
caller="fabric_vcon_exists")
except UcsOperationError:
return (False, None)
mo_exists = mo.check_prop_match(**kwargs)
return (mo_exists, mo if mo_exists else None)
def fabric_vcon_modify(handle, id, ls_server_dn, **kwargs):
"""
modifies fabric vcon
Args:
handle (UcsHandle)
id (string):
ls_server_dn (string):
**kwargs:
Returns:
FabricVCon: managed object
Raises:
UcsOperationError: if FabricVCon is not present
Example:
"""
mo = fabric_vcon_get(handle=handle, id=id, ls_server_dn=ls_server_dn,
caller="fabric_vcon_modify")
mo.set_prop_multiple(**kwargs)
handle.set_mo(mo)
handle.commit()
return mo
def fabric_vcon_delete(handle, id, ls_server_dn):
"""
deletes fabric vcon
Args:
handle (UcsHandle)
id (String): ls server name
ls_server_dn (string): ls server's full name
Returns:
None
Raises:
UcsOperationError: if FabricVCon is not present
Example:
"""
mo = fabric_vcon_get(handle=handle, id=id, ls_server_dn=ls_server_dn,
caller="fabric_vcon_delete")
handle.remove_mo()
handle.commit()
"""
if __name__ == "__main__":
from ucsmsdk.ucshandle import UcsHandle
handle = UcsHandle("10.94.254.136","ansible","elbisna1*")
handle.login()
fabric_vcon_create(handle, "4" ,"org-root/org-DHS-VM/ls-DS-ESX-C2-SCALEIO", fabric='NONE',
inst_type="manual", placement="physical", select="all",
share="shared", transport="ethernet")
print fabric_vcon_exists(handle, "4" ,"org-root/org-DHS-VM/ls-DS-ESX-C2-SCALEIO")
print fabric_vcon_get(handle, "4" ,"org-root/org-DHS-VM/ls-DS-ESX-C2-SCALEIO")
fabric_vcon_modify(handle, "4" ,"org-root/org-DHS-VM/ls-DS-ESX-C2-SCALEIO", inst_type="auto")
fabric_vcon_delete(handle, "4" ,"org-root/org-DHS-VM/ls-DS-ESX-C2-SCALEIO")
"""
#!/usr/bin/env python
from ansible.module_utils.basic import *
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: cisco_ucs_ls_server
short_description: configures ls server on a cisco ucs server profile
version_added: 0.9.0.0
description:
- configures ls server on a cisco ucs server profile
options:
state:
description:
- if C(present), will perform create/add/enable operation
- if C(absent), will perform delete/remove/disable operation
required: false
choices: ['present', 'absent']
default: "present"
id:
version_added: "1.0(1e)"
description: boot policy name
required: true
choices: ['1', '2', '3', '4']
ls_server_dn:
version_added: "1.0(1e)"
description:
required: false
fabric:
version_added: "1.0(1e)"
description:
required: false
choices: ['A', 'B', 'any', 'NONE']
inst_type:
version_added: "1.0(1e)"
description:
required: false
choices: ['auto', 'manual', 'policy']
placement:
version_added: "1.0(1e)"
description:
required: false
choices: ['auto', 'physical']
select:
version_added: "1.0(1e)"
description:
required: false
choices: ['all', 'assigned-only', 'dynamic-only', 'exclude-dynamic', 'exclude-unassigned',
'exclude-usnic', 'unassigned-only', 'usnic-only']
share:
version_added: "1.0(1e)"
description:
required: false
choices: ['different-transport', 'exclusive-only', 'exclusive-preferred', 'same-transport', 'shared']
transport:
version_added: "1.0(1e)"
description:
required: false
requirements: ['ucsmsdk', 'ucsm_apis']
author: "Cisco Systems Inc(ucs-python@cisco.com)"
'''
EXAMPLES = '''
- name:
fabric_vcon_module:
id: "1"
ls_server_dn: "org-root/ls-spt-test"
fabric: "B"
inst_type: "manual"
select: "assigned-only"
share: "different-transport"
state: "present"
ucs_ip: "192.168.1.1"
ucs_username: "admin"
ucs_password: "password"
'''
#Arguments object for the Managed Object in question
def _argument_mo():
return dict(
id=dict(required=True, type='str', choices=['1', '2', '3', '4']),
ls_server_dn=dict(required=True, type='str'),
fabric=dict(type='str', choices=['A', 'B', 'any', 'NONE'], default="NONE"),
inst_type=dict(type='str', choices=['auto', 'manual', 'policy'], default="manual"),
placement=dict(type='str', choices=['auto', 'physical'], default="physical"),
select=dict(type='str', choices=['all', 'assigned-only', 'dynamic-only', 'exclude-dynamic',
'exclude-unassigned', 'exclude-usnic', 'unassigned-only', 'usnic-only'],
default="all"),
share=dict(type='str', choices=['different-transport', 'exclusive-only',
'exclusive-preferred', 'same-transport', 'shared'], default="shared"),
transport=dict(type='str', default="ethernet")
)
#Arguments object unique to the Ansible Module
def _argument_custom():
return dict(
state=dict(default="present",
choices=['present', 'absent'],
type='str'),
)
#Arguments object related to the UcsHandle
def _argument_connection():
return dict(
# UcsHandle
ucs_server=dict(type='dict'),
# Ucs server credentials
ucs_ip=dict(type='str'),
ucs_username=dict(default="admin", type='str'),
ucs_password=dict(type='str', no_log=True),
ucs_port=dict(default=None),
ucs_secure=dict(default=None),
ucs_proxy=dict(default=None)
)
#Creates the AnsibleModule object with the all arguments
def _ansible_module_create():
argument_spec = dict()
argument_spec.update(_argument_connection())
argument_spec.update(_argument_mo())
argument_spec.update(_argument_custom())
return AnsibleModule(argument_spec,
supports_check_mode=True)
#Retrieves non-None mo properties
def _get_mo_params(params):
from ansible.module_utils.cisco_ucs import UcsConnection
args = {}
for key in _argument_mo():
if params.get(key) is None:
continue
args[key] = params.get(key)
return args
def setup_fabric_vcon(server, module):
from ucsm_apis.service_profile.fabric_vcon import fabric_vcon_create
from ucsm_apis.service_profile.fabric_vcon import fabric_vcon_exists
from ucsm_apis.service_profile.fabric_vcon import fabric_vcon_delete
ansible = module.params
args_mo = _get_mo_params(ansible)
exists, mo = fabric_vcon_exists(handle=server, **args_mo)
if ansible["state"] == "present":
if module.check_mode or exists:
return not exists
fabric_vcon_create(handle=server, **args_mo)
else:
if module.check_mode or not exists:
return exists
fabric_vcon_delete(server, mo.name, args_mo['org_dn'])
return True
#Attempts to run the above method and provides error handling if it fails
def setup(server, module):
result = {}
err = False
try:
result["changed"] = setup_fabric_vcon(server, module)
except Exception as e:
err = True
result["msg"] = "setup error: %s " % str(e)
result["changed"] = False
return result, err
#Creates the module and makes the connections, only real work is done in setup
def main():
from ansible.module_utils.cisco_ucs import UcsConnection
module = _ansible_module_create()
conn = UcsConnection(module)
server = conn.login()
result, err = setup(server, module)
conn.logout()
if err:
module.fail_json(**result)
module.exit_json(**result)
if __name__ == '__main__':
main()
{
"ANSIBLE_MODULE_ARGS": {
"id": "1",
"ls_server_dn": "org-root/org-DHS-VM/ls-DS-ESX-C2-SCALEIO",
"fabric": "NONE",
"inst_type": "manual",
"placement": "physical",
"select": "all",
"share": "shared",
"transport": "ethernet, fc",
"state": "present",
"ucs_ip": "10.94.254.136",
"ucs_username": "ansible",
"ucs_password": "elbisna1*"
}
}