diff --git a/lib/ansible/modules/network/cloudengine/ce_interface_ospf.py b/lib/ansible/modules/network/cloudengine/ce_interface_ospf.py new file mode 100644 index 0000000000..da9045acfa --- /dev/null +++ b/lib/ansible/modules/network/cloudengine/ce_interface_ospf.py @@ -0,0 +1,810 @@ +#!/usr/bin/python +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . +# + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.0'} + +DOCUMENTATION = """ +--- +module: ce_interface_ospf +version_added: "2.4" +short_description: Manages configuration of an OSPF interface instanceon HUAWEI CloudEngine switches. +description: + - Manages configuration of an OSPF interface instanceon HUAWEI CloudEngine switches. +author: QijunPan (@CloudEngine-Ansible) +options: + interface: + description: + - Full name of interface, i.e. 40GE1/0/10. + required: true + process_id: + description: + - Specifies a process ID. + The value is an integer ranging from 1 to 4294967295. + required: true + area: + description: + - Ospf area associated with this ospf process. + Valid values are a string, formatted as an IP address + (i.e. "0.0.0.0") or as an integer between 1 and 4294967295. + required: true + cost: + description: + - The cost associated with this interface. + Valid values are an integer in the range from 1 to 65535. + required: false + default: null + hello_interval: + description: + - Time between sending successive hello packets. + Valid values are an integer in the range from 1 to 65535. + required: false + default: null + dead_interval: + description: + - Time interval an ospf neighbor waits for a hello + packet before tearing down adjacencies. Valid values are an + integer in the range from 1 to 235926000. + required: false + default: null + silent_interface: + description: + - Setting to true will prevent this interface from receiving + HELLO packets. Valid values are 'true' and 'false'. + required: false + default: false + auth_mode: + description: + - Specifies the authentication type. + required: false + choices: ['none', 'null', 'hmac-sha256', 'md5', 'hmac-md5', 'simple'] + default: null + auth_text_simple: + description: + - Specifies a password for simple authentication. + The value is a string of 1 to 8 characters. + required: false + default: null + auth_key_id: + description: + - Authentication key id when C(auth_mode) is 'hmac-sha256', 'md5' or 'hmac-md5. + Valid value is an integer is in the range from 1 to 255. + required: false + default: null + auth_text_md5: + description: + - Specifies a password for MD5, HMAC-MD5, or HMAC-SHA256 authentication. + The value is a string of 1 to 255 case-sensitive characters, spaces not supported. + required: false + default: null + state: + description: + - Determines whether the config should be present or not + on the device. + required: false + default: present + choices: ['present','absent'] +""" + +EXAMPLES = ''' +- name: eth_trunk module test + hosts: cloudengine + connection: local + gather_facts: no + vars: + cli: + host: "{{ inventory_hostname }}" + port: "{{ ansible_ssh_port }}" + username: "{{ username }}" + password: "{{ password }}" + transport: cli + + tasks: + - name: Enables OSPF and sets the cost on an interface + ce_interface_ospf: + interface: 10GE1/0/30 + process_id: 1 + area: 100 + cost: 100 + provider: '{{ cli }}' + + - name: Sets the dead interval of the OSPF neighbor + ce_interface_ospf: + interface: 10GE1/0/30 + process_id: 1 + area: 100 + dead_interval: 100 + provider: '{{ cli }}' + + - name: Sets the interval for sending Hello packets on an interface + ce_interface_ospf: + interface: 10GE1/0/30 + process_id: 1 + area: 100 + hello_interval: 2 + provider: '{{ cli }}' + + - name: Disables an interface from receiving and sending OSPF packets + ce_interface_ospf: + interface: 10GE1/0/30 + process_id: 1 + area: 100 + silent_interface: true + provider: '{{ cli }}' +''' + +RETURN = ''' +proposed: + description: k/v pairs of parameters passed into module + returned: verbose mode + type: dict + sample: {"process_id": "1", "area": "0.0.0.100", "interface": "10GE1/0/30", "cost": "100"} +existing: + description: k/v pairs of existing configuration + returned: verbose mode + type: dict + sample: {"process_id": "1", "area": "0.0.0.100"} +end_state: + description: k/v pairs of configuration after module execution + returned: verbose mode + type: dict + sample: {"process_id": "1", "area": "0.0.0.100", "interface": "10GE1/0/30", + "cost": "100", "dead_interval": "40", "hello_interval": "10", + "process_id": "6", "silent_interface": "false", "auth_mode": "none"} +updates: + description: commands sent to the device + returned: always + type: list + sample: ["interface 10GE1/0/30", + "ospf enable 1 area 0.0.0.100", + "ospf cost 100"] +changed: + description: check to see if a change was made on the device + returned: always + type: boolean + sample: true +''' + +from xml.etree import ElementTree +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ce import get_nc_config, set_nc_config, ce_argument_spec + +CE_NC_GET_OSPF = """ + + + + + + %s + + + + + %s + + + %s + + + + + + + + + + + + + + + + + + +""" + +CE_NC_XML_BUILD_PROCESS = """ + + + + + + %s + + + %s + %s + + + + + + + +""" + +CE_NC_XML_BUILD_MERGE_INTF = """ + + + %s + + +""" + +CE_NC_XML_BUILD_DELETE_INTF = """ + + + %s + + +""" +CE_NC_XML_SET_IF_NAME = """ + %s +""" + +CE_NC_XML_SET_HELLO = """ + %s +""" + +CE_NC_XML_SET_DEAD = """ + %s +""" + +CE_NC_XML_SET_SILENT = """ + %s +""" + +CE_NC_XML_SET_COST = """ + %s +""" + +CE_NC_XML_SET_AUTH_MODE = """ + %s +""" + + +CE_NC_XML_SET_AUTH_TEXT_SIMPLE = """ + %s +""" + +CE_NC_XML_SET_AUTH_MD5 = """ + %s + %s +""" + + +def get_interface_type(interface): + """Gets the type of interface, such as 10GE, ETH-TRUNK, VLANIF...""" + + 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('4X10GE'): + iftype = '4x10ge' + elif interface.upper().startswith('40GE'): + iftype = '40ge' + elif interface.upper().startswith('100GE'): + iftype = '100ge' + elif interface.upper().startswith('VLANIF'): + iftype = 'vlanif' + elif interface.upper().startswith('LOOPBACK'): + iftype = 'loopback' + elif interface.upper().startswith('METH'): + iftype = 'meth' + elif interface.upper().startswith('ETH-TRUNK'): + iftype = 'eth-trunk' + elif interface.upper().startswith('VBDIF'): + iftype = 'vbdif' + elif interface.upper().startswith('NVE'): + iftype = 'nve' + elif interface.upper().startswith('TUNNEL'): + iftype = 'tunnel' + elif interface.upper().startswith('ETHERNET'): + iftype = 'ethernet' + elif interface.upper().startswith('FCOE-PORT'): + iftype = 'fcoe-port' + elif interface.upper().startswith('FABRIC-PORT'): + iftype = 'fabric-port' + elif interface.upper().startswith('STACK-PORT'): + iftype = 'stack-port' + elif interface.upper().startswith('NULL'): + iftype = 'null' + else: + return None + + return iftype.lower() + + +def is_valid_v4addr(addr): + """check is ipv4 addr is valid""" + + if not addr: + return False + + if addr.find('.') != -1: + addr_list = addr.split('.') + if len(addr_list) != 4: + return False + for each_num in addr_list: + if not each_num.isdigit(): + return False + if int(each_num) > 255: + return False + return True + + return False + + +class InterfaceOSPF(object): + """ + Manages configuration of an OSPF interface instance. + """ + + def __init__(self, argument_spec): + self.spec = argument_spec + self.module = None + self.init_module() + + # module input info + self.interface = self.module.params['interface'] + self.process_id = self.module.params['process_id'] + self.area = self.module.params['area'] + self.cost = self.module.params['cost'] + self.hello_interval = self.module.params['hello_interval'] + self.dead_interval = self.module.params['dead_interval'] + self.silent_interface = self.module.params['silent_interface'] + self.auth_mode = self.module.params['auth_mode'] + self.auth_text_simple = self.module.params['auth_text_simple'] + self.auth_key_id = self.module.params['auth_key_id'] + self.auth_text_md5 = self.module.params['auth_text_md5'] + self.state = self.module.params['state'] + + # ospf info + self.ospf_info = dict() + + # state + self.changed = False + self.updates_cmd = list() + self.results = dict() + self.proposed = dict() + self.existing = dict() + self.end_state = dict() + + def init_module(self): + """init module""" + + self.module = AnsibleModule( + argument_spec=self.spec, supports_check_mode=True) + + def netconf_set_config(self, xml_str, xml_name): + """netconf set config""" + + rcv_xml = set_nc_config(self.module, xml_str) + if "" not in rcv_xml: + self.module.fail_json(msg='Error: %s failed.' % xml_name) + + def get_area_ip(self): + """convert integer to ip address""" + + if not self.area.isdigit(): + return self.area + + addr_int = ['0'] * 4 + addr_int[0] = str(((int(self.area) & 0xFF000000) >> 24) & 0xFF) + addr_int[1] = str(((int(self.area) & 0x00FF0000) >> 16) & 0xFF) + addr_int[2] = str(((int(self.area) & 0x0000FF00) >> 8) & 0XFF) + addr_int[3] = str(int(self.area) & 0xFF) + + return '.'.join(addr_int) + + def get_ospf_dict(self): + """ get one ospf attributes dict.""" + + ospf_info = dict() + conf_str = CE_NC_GET_OSPF % ( + self.process_id, self.get_area_ip(), self.interface) + rcv_xml = get_nc_config(self.module, conf_str) + + if "" in rcv_xml: + return ospf_info + + xml_str = rcv_xml.replace('\r', '').replace('\n', '').\ + replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ + replace('xmlns="http://www.huawei.com/netconf/vrp"', "") + + # get process base info + root = ElementTree.fromstring(xml_str) + ospfsite = root.find("data/ospfv2/ospfv2comm/ospfSites/ospfSite") + if not ospfsite: + self.module.fail_json(msg="Error: ospf process does not exist.") + + for site in ospfsite: + if site.tag in ["processId", "routerId", "vrfName"]: + ospf_info[site.tag] = site.text + + # get areas info + ospf_info["areaId"] = "" + areas = root.find( + "data/ospfv2/ospfv2comm/ospfSites/ospfSite/areas/area") + if areas: + for area in areas: + if area.tag == "areaId": + ospf_info["areaId"] = area.text + break + + # get interface info + ospf_info["interface"] = dict() + intf = root.find( + "data/ospfv2/ospfv2comm/ospfSites/ospfSite/areas/area/interfaces/interface") + if intf: + for attr in intf: + if attr.tag in ["ifName", "networkType", + "helloInterval", "deadInterval", + "silentEnable", "configCost", + "authenticationMode", "authTextSimple", + "keyId", "authTextMd5"]: + ospf_info["interface"][attr.tag] = attr.text + + return ospf_info + + def set_ospf_interface(self): + """set interface ospf enable, and set its ospf attributes""" + + xml_intf = CE_NC_XML_SET_IF_NAME % self.interface + + # ospf view + self.updates_cmd.append("ospf %s" % self.process_id) + self.updates_cmd.append("area %s" % self.get_area_ip()) + if self.silent_interface: + xml_intf += CE_NC_XML_SET_SILENT % str(self.silent_interface).lower() + if self.silent_interface: + self.updates_cmd.append("silent-interface %s" % self.interface) + else: + self.updates_cmd.append("undo silent-interface %s" % self.interface) + + # interface view + self.updates_cmd.append("interface %s" % self.interface) + self.updates_cmd.append("ospf enable process %s area %s" % ( + self.process_id, self.get_area_ip())) + if self.cost: + xml_intf += CE_NC_XML_SET_COST % self.cost + self.updates_cmd.append("ospf cost %s" % self.cost) + if self.hello_interval: + xml_intf += CE_NC_XML_SET_HELLO % self.hello_interval + self.updates_cmd.append("ospf timer hello %s" % + self.hello_interval) + if self.dead_interval: + xml_intf += CE_NC_XML_SET_DEAD % self.dead_interval + self.updates_cmd.append("ospf timer dead %s" % self.dead_interval) + if self.auth_mode: + xml_intf += CE_NC_XML_SET_AUTH_MODE % self.auth_mode + if self.auth_mode == "none": + self.updates_cmd.append("undo ospf authentication-mode") + else: + self.updates_cmd.append("ospf authentication-mode %s" % self.auth_mode) + if self.auth_mode == "simple" and self.auth_text_simple: + xml_intf += CE_NC_XML_SET_AUTH_TEXT_SIMPLE % self.auth_text_simple + self.updates_cmd.pop() + self.updates_cmd.append("ospf authentication-mode %s %s" + % (self.auth_mode, self.auth_text_simple)) + elif self.auth_mode in ["hmac-sha256", "md5", "hmac-md5"] and self.auth_key_id: + xml_intf += CE_NC_XML_SET_AUTH_MD5 % ( + self.auth_key_id, self.auth_text_md5) + self.updates_cmd.pop() + self.updates_cmd.append("ospf authentication-mode %s %s %s" + % (self.auth_mode, self.auth_key_id, self.auth_text_md5)) + else: + pass + + xml_str = CE_NC_XML_BUILD_PROCESS % (self.process_id, + self.get_area_ip(), + (CE_NC_XML_BUILD_MERGE_INTF % xml_intf)) + self.netconf_set_config(xml_str, "SET_INTERFACE_OSPF") + self.changed = True + + def merge_ospf_interface(self): + """merge interface ospf attributes""" + + intf_dict = self.ospf_info["interface"] + + # ospf view + xml_ospf = "" + if intf_dict.get("silentEnable") != str(self.silent_interface).lower(): + xml_ospf += CE_NC_XML_SET_SILENT % str(self.silent_interface).lower() + self.updates_cmd.append("ospf %s" % self.process_id) + self.updates_cmd.append("area %s" % self.get_area_ip()) + if self.silent_interface: + self.updates_cmd.append("silent-interface %s" % self.interface) + else: + self.updates_cmd.append("undo silent-interface %s" % self.interface) + + # interface view + xml_intf = "" + self.updates_cmd.append("interface %s" % self.interface) + if self.cost and intf_dict.get("configCost") != self.cost: + xml_intf += CE_NC_XML_SET_COST % self.cost + self.updates_cmd.append("ospf cost %s" % self.cost) + if self.hello_interval and intf_dict.get("helloInterval") != self.hello_interval: + xml_intf += CE_NC_XML_SET_HELLO % self.hello_interval + self.updates_cmd.append("ospf timer hello %s" % + self.hello_interval) + if self.dead_interval and intf_dict.get("deadInterval") != self.dead_interval: + xml_intf += CE_NC_XML_SET_DEAD % self.dead_interval + self.updates_cmd.append("ospf timer dead %s" % self.dead_interval) + if self.auth_mode: + # NOTE: for security, authentication config will always be update + xml_intf += CE_NC_XML_SET_AUTH_MODE % self.auth_mode + if self.auth_mode == "none": + self.updates_cmd.append("undo ospf authentication-mode") + else: + self.updates_cmd.append("ospf authentication-mode %s" % self.auth_mode) + if self.auth_mode == "simple" and self.auth_text_simple: + xml_intf += CE_NC_XML_SET_AUTH_TEXT_SIMPLE % self.auth_text_simple + self.updates_cmd.pop() + self.updates_cmd.append("ospf authentication-mode %s %s" + % (self.auth_mode, self.auth_text_simple)) + elif self.auth_mode in ["hmac-sha256", "md5", "hmac-md5"] and self.auth_key_id: + xml_intf += CE_NC_XML_SET_AUTH_MD5 % ( + self.auth_key_id, self.auth_text_md5) + self.updates_cmd.pop() + self.updates_cmd.append("ospf authentication-mode %s %s %s" + % (self.auth_mode, self.auth_key_id, self.auth_text_md5)) + else: + pass + if not xml_intf: + self.updates_cmd.pop() # remove command: interface + + if not xml_ospf and not xml_intf: + return + + xml_sum = CE_NC_XML_SET_IF_NAME % self.interface + xml_sum += xml_ospf + xml_intf + xml_str = CE_NC_XML_BUILD_PROCESS % (self.process_id, + self.get_area_ip(), + (CE_NC_XML_BUILD_MERGE_INTF % xml_sum)) + self.netconf_set_config(xml_str, "MERGE_INTERFACE_OSPF") + self.changed = True + + def unset_ospf_interface(self): + """set interface ospf disable, and all its ospf attributes will be removed""" + + intf_dict = self.ospf_info["interface"] + xml_sum = "" + xml_intf = CE_NC_XML_SET_IF_NAME % self.interface + if intf_dict.get("silentEnable") == "true": + xml_sum += CE_NC_XML_BUILD_MERGE_INTF % ( + xml_intf + (CE_NC_XML_SET_SILENT % "false")) + self.updates_cmd.append("ospf %s" % self.process_id) + self.updates_cmd.append("area %s" % self.get_area_ip()) + self.updates_cmd.append( + "undo silent-interface %s" % self.interface) + + xml_sum += CE_NC_XML_BUILD_DELETE_INTF % xml_intf + xml_str = CE_NC_XML_BUILD_PROCESS % (self.process_id, + self.get_area_ip(), + xml_sum) + self.netconf_set_config(xml_str, "DELETE_INTERFACE_OSPF") + self.updates_cmd.append("undo ospf cost") + self.updates_cmd.append("undo ospf timer hello") + self.updates_cmd.append("undo ospf timer dead") + self.updates_cmd.append("undo ospf authentication-mode") + self.updates_cmd.append("undo ospf enable %s area %s" % ( + self.process_id, self.get_area_ip())) + self.changed = True + + def check_params(self): + """Check all input params""" + + self.interface = self.interface.replace(" ", "").upper() + + # interface check + if not get_interface_type(self.interface): + self.module.fail_json(msg="Error: interface is invalid.") + + # process_id check + if not self.process_id.isdigit(): + self.module.fail_json(msg="Error: process_id is not digit.") + if int(self.process_id) < 1 or int(self.process_id) > 4294967295: + self.module.fail_json(msg="Error: process_id must be an integer between 1 and 4294967295.") + + # area check + if self.area.isdigit(): + if int(self.area) < 0 or int(self.area) > 4294967295: + self.module.fail_json(msg="Error: area id (Integer) must be between 0 and 4294967295.") + else: + if not is_valid_v4addr(self.area): + self.module.fail_json(msg="Error: area id is invalid.") + + # area authentication check + if self.state == "present": + if self.auth_mode: + if self.auth_mode == "simple": + if self.auth_text_simple and len(self.auth_text_simple) > 8: + self.module.fail_json( + msg="Error: auth_text_simple is not in the range from 1 to 8.") + if self.auth_mode in ["hmac-sha256", "hmac-sha256", "md5"]: + if self.auth_key_id and not self.auth_text_md5: + self.module.fail_json( + msg='Error: auth_key_id and auth_text_md5 should be set at the same time.') + if not self.auth_key_id and self.auth_text_md5: + self.module.fail_json( + msg='Error: auth_key_id and auth_text_md5 should be set at the same time.') + if self.auth_key_id: + if not self.auth_key_id.isdigit(): + self.module.fail_json( + msg="Error: auth_key_id is not digit.") + if int(self.auth_key_id) < 1 or int(self.auth_key_id) > 255: + self.module.fail_json( + msg="Error: auth_key_id is not in the range from 1 to 255.") + if self.auth_text_md5 and len(self.auth_text_md5) > 255: + self.module.fail_json( + msg="Error: auth_text_md5 is not in the range from 1 to 255.") + # cost check + if self.cost: + if not self.cost.isdigit(): + self.module.fail_json(msg="Error: cost is not digit.") + if int(self.cost) < 1 or int(self.cost) > 65535: + self.module.fail_json( + msg="Error: cost is not in the range from 1 to 65535") + + # hello_interval check + if self.hello_interval: + if not self.hello_interval.isdigit(): + self.module.fail_json( + msg="Error: hello_interval is not digit.") + if int(self.hello_interval) < 1 or int(self.hello_interval) > 65535: + self.module.fail_json( + msg="Error: hello_interval is not in the range from 1 to 65535") + + # dead_interval check + if self.dead_interval: + if not self.dead_interval.isdigit(): + self.module.fail_json(msg="Error: dead_interval is not digit.") + if int(self.dead_interval) < 1 or int(self.dead_interval) > 235926000: + self.module.fail_json( + msg="Error: dead_interval is not in the range from 1 to 235926000") + + def get_proposed(self): + """get proposed info""" + + self.proposed["interface"] = self.interface + self.proposed["process_id"] = self.process_id + self.proposed["area"] = self.get_area_ip() + self.proposed["cost"] = self.cost + self.proposed["hello_interval"] = self.hello_interval + self.proposed["dead_interval"] = self.dead_interval + self.proposed["silent_interface"] = self.silent_interface + if self.auth_mode: + self.proposed["auth_mode"] = self.auth_mode + if self.auth_mode == "simple": + self.proposed["auth_text_simple"] = self.auth_text_simple + if self.auth_mode in ["hmac-sha256", "hmac-sha256", "md5"]: + self.proposed["auth_key_id"] = self.auth_key_id + self.proposed["auth_text_md5"] = self.auth_text_md5 + self.proposed["state"] = self.state + + def get_existing(self): + """get existing info""" + + if not self.ospf_info: + return + + if self.ospf_info["interface"]: + self.existing["interface"] = self.interface + self.existing["cost"] = self.ospf_info["interface"].get("configCost") + self.existing["hello_interval"] = self.ospf_info["interface"].get("helloInterval") + self.existing["dead_interval"] = self.ospf_info["interface"].get("deadInterval") + self.existing["silent_interface"] = self.ospf_info["interface"].get("silentEnable") + self.existing["auth_mode"] = self.ospf_info["interface"].get("authenticationMode") + self.existing["auth_text_simple"] = self.ospf_info["interface"].get("authTextSimple") + self.existing["auth_key_id"] = self.ospf_info["interface"].get("keyId") + self.existing["auth_text_md5"] = self.ospf_info["interface"].get("authTextMd5") + self.existing["process_id"] = self.ospf_info["processId"] + self.existing["area"] = self.ospf_info["areaId"] + + def get_end_state(self): + """get end state info""" + + ospf_info = self.get_ospf_dict() + if not ospf_info: + return + + if ospf_info["interface"]: + self.end_state["interface"] = self.interface + self.end_state["cost"] = ospf_info["interface"].get("configCost") + self.end_state["hello_interval"] = ospf_info["interface"].get("helloInterval") + self.end_state["dead_interval"] = ospf_info["interface"].get("deadInterval") + self.end_state["silent_interface"] = ospf_info["interface"].get("silentEnable") + self.end_state["auth_mode"] = ospf_info["interface"].get("authenticationMode") + self.end_state["auth_text_simple"] = ospf_info["interface"].get("authTextSimple") + self.end_state["auth_key_id"] = ospf_info["interface"].get("keyId") + self.end_state["auth_text_md5"] = ospf_info["interface"].get("authTextMd5") + self.end_state["process_id"] = ospf_info["processId"] + self.end_state["area"] = ospf_info["areaId"] + + def work(self): + """worker""" + + self.check_params() + self.ospf_info = self.get_ospf_dict() + self.get_existing() + self.get_proposed() + + # deal present or absent + if self.state == "present": + if not self.ospf_info or not self.ospf_info["interface"]: + # create ospf area and set interface config + self.set_ospf_interface() + else: + # merge interface ospf area config + self.merge_ospf_interface() + else: + if self.ospf_info and self.ospf_info["interface"]: + # delete interface ospf area config + self.unset_ospf_interface() + + self.get_end_state() + 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 main(): + """Module main""" + + argument_spec = dict( + interface=dict(required=True, type='str'), + process_id=dict(required=True, type='str'), + area=dict(required=True, type='str'), + cost=dict(required=False, type='str'), + hello_interval=dict(required=False, type='str'), + dead_interval=dict(required=False, type='str'), + silent_interface=dict(required=False, default=False, type='bool'), + auth_mode=dict(required=False, + choices=['none', 'null', 'hmac-sha256', 'md5', 'hmac-md5', 'simple'], type='str'), + auth_text_simple=dict(required=False, type='str', no_log=True), + auth_key_id=dict(required=False, type='str'), + auth_text_md5=dict(required=False, type='str', no_log=True), + state=dict(required=False, default='present', + choices=['present', 'absent']) + ) + + argument_spec.update(ce_argument_spec) + module = InterfaceOSPF(argument_spec) + module.work() + + +if __name__ == '__main__': + main()