1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/modules/network/cloudengine/ce_mdn_interface.py
Ansible Core Team aebc1b03fd Initial commit
2020-03-09 09:11:07 +00:00

402 lines
13 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2019 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ce_mdn_interface
short_description: Manages MDN configuration on HUAWEI CloudEngine switches.
description:
- Manages MDN configuration on HUAWEI CloudEngine switches.
author: xuxiaowei0512 (@CloudEngine-Ansible)
options:
lldpenable:
description:
- Set global LLDP enable state.
type: str
choices: ['enabled', 'disabled']
mdnstatus:
description:
- Set interface MDN enable state.
type: str
choices: ['rxOnly', 'disabled']
ifname:
description:
- Interface name.
type: str
state:
description:
- Manage the state of the resource.
default: present
type: str
choices: ['present','absent']
notes:
- This module requires the netconf system service be enabled on
the remote device being managed.
- This module works with connection C(netconf).
'''
EXAMPLES = '''
- name: "Configure global LLDP enable state"
ce_mdn_interface:
lldpenable: enabled
- name: "Configure interface MDN enable state"
ce_mdn_interface:
ifname: 10GE1/0/1
mdnstatus: rxOnly
'''
RETURN = '''
proposed:
description: k/v pairs of parameters passed into module
returned: always
type: dict
sample: {
"lldpenable": "enabled",
"ifname": "10GE1/0/1",
"mdnstatus": "rxOnly",
"state":"present"
}
existing:
description: k/v pairs of existing global LLDP configration
returned: always
type: dict
sample: {
"lldpenable": "enabled",
"ifname": "10GE1/0/1",
"mdnstatus": "disabled"
}
end_state:
description: k/v pairs of global LLDP configration after module execution
returned: always
type: dict
sample: {
"lldpenable": "enabled",
"ifname": "10GE1/0/1",
"mdnstatus": "rxOnly"
}
updates:
description: command sent to the device
returned: always
type: list
sample: [
"interface 10ge 1/0/1",
"lldp mdn enable",
]
changed:
description: check to see if a change was made on the device
returned: always
type: bool
sample: true
'''
import copy
import re
from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.network.cloudengine.ce import set_nc_config, get_nc_config, execute_nc_action
CE_NC_GET_GLOBAL_LLDPENABLE_CONFIG = """
<filter type="subtree">
<lldp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<lldpSys>
<lldpEnable></lldpEnable>
</lldpSys>
</lldp>
</filter>
"""
CE_NC_MERGE_GLOBA_LLDPENABLE_CONFIG = """
<config>
<lldp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<lldpSys operation="merge">
<lldpEnable>%s</lldpEnable>
</lldpSys>
</lldp>
</config>
"""
CE_NC_GET_INTERFACE_MDNENABLE_CONFIG = """
<filter type="subtree">
<lldp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<mdnInterfaces>
<mdnInterface>
<ifName></ifName>
<mdnStatus></mdnStatus>
</mdnInterface>
</mdnInterfaces>
</lldp>
</filter>
"""
CE_NC_MERGE_INTERFACE_MDNENABLE_CONFIG = """
<config>
<lldp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<mdnInterfaces>
<mdnInterface operation="merge">
<ifName>%s</ifName>
<mdnStatus>%s</mdnStatus>
</mdnInterface>
</mdnInterfaces>
</lldp>
</config>
"""
def get_interface_type(interface):
"""Gets the type of interface, such as 10GE, ..."""
if interface is None:
return None
iftype = None
if interface.upper().startswith('GE'):
iftype = 'ge'
elif interface.upper().startswith('10GE'):
iftype = '10ge'
elif interface.upper().startswith('25GE'):
iftype = '25ge'
elif interface.upper().startswith('40GE'):
iftype = '40ge'
elif interface.upper().startswith('100GE'):
iftype = '100ge'
elif interface.upper().startswith('PORT-GROUP'):
iftype = 'stack-Port'
elif interface.upper().startswith('NULL'):
iftype = 'null'
else:
return None
return iftype.lower()
class Interface_mdn(object):
"""Manage global lldp enable configration"""
def __init__(self, argument_spec):
self.spec = argument_spec
self.module = None
self.init_module()
# LLDP global configration info
self.lldpenable = self.module.params['lldpenable'] or None
self.ifname = self.module.params['ifname']
self.mdnstatus = self.module.params['mdnstatus'] or None
self.state = self.module.params['state']
self.lldp_conf = dict()
self.conf_exsit = False
self.enable_flag = 0
self.check_params()
# state
self.changed = False
self.proposed_changed = dict()
self.updates_cmd = list()
self.results = dict()
self.proposed = dict()
self.existing = dict()
self.end_state = dict()
def check_params(self):
"""Check all input params"""
if self.ifname:
intf_type = get_interface_type(self.ifname)
if not intf_type:
self.module.fail_json(
msg='Error: ifname name of %s '
'is error.' % self.ifname)
if (len(self.ifname) < 1) or (len(self.ifname) > 63):
self.module.fail_json(
msg='Error: Ifname length is beetween 1 and 63.')
def init_module(self):
"""Init module object"""
self.module = AnsibleModule(
argument_spec=self.spec, supports_check_mode=True)
def check_response(self, xml_str, xml_name):
"""Check if response message is already succeed"""
if "<ok/>" not in xml_str:
self.module.fail_json(msg='Error: %s failed.' % xml_name)
def config_interface_mdn(self):
"""Configure lldp enabled and interface mdn enabled parameters"""
if self.state == 'present':
if self.enable_flag == 0 and self.lldpenable == 'enabled':
xml_str = CE_NC_MERGE_GLOBA_LLDPENABLE_CONFIG % self.lldpenable
ret_xml = set_nc_config(self.module, xml_str)
self.check_response(ret_xml, "LLDP_ENABLE_CONFIG")
self.changed = True
elif self.enable_flag == 1 and self.lldpenable == 'disabled':
xml_str = CE_NC_MERGE_GLOBA_LLDPENABLE_CONFIG % self.lldpenable
ret_xml = set_nc_config(self.module, xml_str)
self.check_response(ret_xml, "LLDP_ENABLE_CONFIG")
self.changed = True
elif self.enable_flag == 1 and self.conf_exsit:
xml_str = CE_NC_MERGE_INTERFACE_MDNENABLE_CONFIG % (self.ifname, self.mdnstatus)
ret_xml = set_nc_config(self.module, xml_str)
self.check_response(ret_xml, "INTERFACE_MDN_ENABLE_CONFIG")
self.changed = True
def show_result(self):
"""Show result"""
self.results['changed'] = self.changed
self.results['proposed'] = self.proposed
self.results['existing'] = self.existing
self.results['end_state'] = self.end_state
if self.changed:
self.results['updates'] = self.updates_cmd
else:
self.results['updates'] = list()
self.module.exit_json(**self.results)
def get_interface_mdn_exist_config(self):
"""Get lldp existed configure"""
lldp_config = list()
lldp_dict = dict()
conf_enable_str = CE_NC_GET_GLOBAL_LLDPENABLE_CONFIG
conf_enable_obj = get_nc_config(self.module, conf_enable_str)
xml_enable_str = conf_enable_obj.replace('\r', '').replace('\n', '').\
replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
# get lldp enable config info
root_enable = ElementTree.fromstring(xml_enable_str)
ntpsite_enable = root_enable.findall("lldp/lldpSys")
for nexthop_enable in ntpsite_enable:
for ele_enable in nexthop_enable:
if ele_enable.tag in ["lldpEnable"]:
lldp_dict[ele_enable.tag] = ele_enable.text
if self.state == "present":
if lldp_dict['lldpEnable'] == 'enabled':
self.enable_flag = 1
lldp_config.append(dict(lldpenable=lldp_dict['lldpEnable']))
if self.enable_flag == 1:
conf_str = CE_NC_GET_INTERFACE_MDNENABLE_CONFIG
conf_obj = get_nc_config(self.module, conf_str)
if "<data/>" in conf_obj:
return lldp_config
xml_str = conf_obj.replace('\r', '').replace('\n', '').\
replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
replace('xmlns="http://www.huawei.com/netconf/vrp"', "")
# get all ntp config info
root = ElementTree.fromstring(xml_str)
ntpsite = root.findall("lldp/mdnInterfaces/mdnInterface")
for nexthop in ntpsite:
for ele in nexthop:
if ele.tag in ["ifName", "mdnStatus"]:
lldp_dict[ele.tag] = ele.text
if self.state == "present":
cur_interface_mdn_cfg = dict(ifname=lldp_dict['ifName'], mdnstatus=lldp_dict['mdnStatus'])
exp_interface_mdn_cfg = dict(ifname=self.ifname, mdnstatus=self.mdnstatus)
if self.ifname == lldp_dict['ifName']:
if cur_interface_mdn_cfg != exp_interface_mdn_cfg:
self.conf_exsit = True
lldp_config.append(dict(ifname=lldp_dict['ifName'], mdnstatus=lldp_dict['mdnStatus']))
return lldp_config
lldp_config.append(dict(ifname=lldp_dict['ifName'], mdnstatus=lldp_dict['mdnStatus']))
return lldp_config
def get_existing(self):
"""Get existing info"""
self.existing = self.get_interface_mdn_exist_config()
def get_proposed(self):
"""Get proposed info"""
if self.lldpenable:
self.proposed = dict(lldpenable=self.lldpenable)
if self.enable_flag == 1:
if self.ifname:
self.proposed = dict(ifname=self.ifname, mdnstatus=self.mdnstatus)
def get_end_state(self):
"""Get end state info"""
self.end_state = self.get_interface_mdn_exist_config()
def get_update_cmd(self):
"""Get updated commands"""
update_list = list()
if self.state == "present":
if self.lldpenable == "enabled":
cli_str = "lldp enable"
update_list.append(cli_str)
if self.ifname:
cli_str = "%s %s" % ("interface", self.ifname)
update_list.append(cli_str)
if self.mdnstatus:
if self.mdnstatus == "rxOnly":
cli_str = "lldp mdn enable"
update_list.append(cli_str)
else:
cli_str = "undo lldp mdn enable"
update_list.append(cli_str)
elif self.lldpenable == "disabled":
cli_str = "undo lldp enable"
update_list.append(cli_str)
else:
if self.enable_flag == 1:
if self.ifname:
cli_str = "%s %s" % ("interface", self.ifname)
update_list.append(cli_str)
if self.mdnstatus:
if self.mdnstatus == "rxOnly":
cli_str = "lldp mdn enable"
update_list.append(cli_str)
else:
cli_str = "undo lldp mdn enable"
update_list.append(cli_str)
self.updates_cmd.append(update_list)
def work(self):
"""Excute task"""
self.check_params()
self.get_existing()
self.get_proposed()
self.config_interface_mdn()
self.get_update_cmd()
self.get_end_state()
self.show_result()
def main():
"""Main function entry"""
argument_spec = dict(
lldpenable=dict(type='str', choices=['enabled', 'disabled']),
mdnstatus=dict(type='str', choices=['rxOnly', 'disabled']),
ifname=dict(type='str'),
state=dict(choices=['absent', 'present'], default='present'),
)
lldp_obj = Interface_mdn(argument_spec)
lldp_obj.work()
if __name__ == '__main__':
main()