1#!/usr/local/bin/python3.8 2# 3# This file is part of Ansible 4# 5# Ansible is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# Ansible is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 17# 18 19from __future__ import (absolute_import, division, print_function) 20__metaclass__ = type 21 22DOCUMENTATION = ''' 23--- 24module: ce_evpn_global 25short_description: Manages global configuration of EVPN on HUAWEI CloudEngine switches. 26description: 27 - Manages global configuration of EVPN on HUAWEI CloudEngine switches. 28author: Zhijin Zhou (@QijunPan) 29notes: 30 - Before configuring evpn_overlay_enable=disable, delete other EVPN configurations. 31 - Recommended connection is C(network_cli). 32 - This module also works with C(local) connections for legacy playbooks. 33options: 34 evpn_overlay_enable: 35 description: 36 - Configure EVPN as the VXLAN control plane. 37 required: true 38 choices: ['enable','disable'] 39''' 40 41EXAMPLES = ''' 42- name: Evpn global module test 43 hosts: cloudengine 44 connection: local 45 gather_facts: no 46 vars: 47 cli: 48 host: "{{ inventory_hostname }}" 49 port: "{{ ansible_ssh_port }}" 50 username: "{{ username }}" 51 password: "{{ password }}" 52 transport: cli 53 54 tasks: 55 56 - name: Configure EVPN as the VXLAN control plan 57 community.network.ce_evpn_global: 58 evpn_overlay_enable: enable 59 provider: "{{ cli }}" 60 61 - name: Undo EVPN as the VXLAN control plan 62 community.network.ce_evpn_global: 63 evpn_overlay_enable: disable 64 provider: "{{ cli }}" 65''' 66 67RETURN = ''' 68proposed: 69 description: k/v pairs of parameters passed into module 70 returned: always 71 type: dict 72 sample: { 73 "evpn_overlay_enable": "enable" 74 } 75existing: 76 description: k/v pairs of existing attributes on the device 77 returned: always 78 type: dict 79 sample: { 80 "evpn_overlay_enable": "disable" 81 } 82end_state: 83 description: k/v pairs of end attributes on the interface 84 returned: always 85 type: dict 86 sample: { 87 "evpn_overlay_enable": "enable" 88 } 89updates: 90 description: command list sent to the device 91 returned: always 92 type: list 93 sample: [ 94 "evpn-overlay enable", 95 ] 96changed: 97 description: check to see if a change was made on the device 98 returned: always 99 type: bool 100 sample: true 101''' 102 103 104from ansible.module_utils.basic import AnsibleModule 105from ansible_collections.community.network.plugins.module_utils.network.cloudengine.ce import exec_command, load_config 106from ansible_collections.community.network.plugins.module_utils.network.cloudengine.ce import ce_argument_spec 107 108 109class EvpnGlobal(object): 110 """Manage global configuration of EVPN""" 111 112 def __init__(self, argument_spec, ): 113 self.spec = argument_spec 114 self.module = None 115 self.init_module() 116 117 # EVPN global configuration parameters 118 self.overlay_enable = self.module.params['evpn_overlay_enable'] 119 120 self.commands = list() 121 self.global_info = dict() 122 self.conf_exist = False 123 # state 124 self.changed = False 125 self.updates_cmd = list() 126 self.results = dict() 127 self.proposed = dict() 128 self.existing = dict() 129 self.end_state = dict() 130 131 def init_module(self): 132 """init_module""" 133 self.module = AnsibleModule( 134 argument_spec=self.spec, supports_check_mode=True) 135 136 def cli_load_config(self, commands): 137 """load config by cli""" 138 if not self.module.check_mode: 139 load_config(self.module, commands) 140 141 def cli_add_command(self, command, undo=False): 142 """add command to self.update_cmd and self.commands""" 143 if undo and command.lower() not in ["quit", "return"]: 144 cmd = "undo " + command 145 else: 146 cmd = command 147 148 self.commands.append(cmd) # set to device 149 if command.lower() not in ["quit", "return"]: 150 self.updates_cmd.append(cmd) # show updates result 151 152 def get_evpn_global_info(self): 153 """ get current EVPN global configuration""" 154 155 self.global_info['evpnOverLay'] = 'disable' 156 cmd = "display current-configuration | include ^evpn-overlay enable" 157 rc, out, err = exec_command(self.module, cmd) 158 if rc != 0: 159 self.module.fail_json(msg=err) 160 if out: 161 self.global_info['evpnOverLay'] = 'enable' 162 163 def get_existing(self): 164 """get existing config""" 165 self.existing = dict( 166 evpn_overlay_enable=self.global_info['evpnOverLay']) 167 168 def get_proposed(self): 169 """get proposed config""" 170 self.proposed = dict(evpn_overlay_enable=self.overlay_enable) 171 172 def get_end_state(self): 173 """get end config""" 174 self.get_evpn_global_info() 175 self.end_state = dict( 176 evpn_overlay_enable=self.global_info['evpnOverLay']) 177 178 def show_result(self): 179 """ show result""" 180 self.results['changed'] = self.changed 181 self.results['proposed'] = self.proposed 182 self.results['existing'] = self.existing 183 self.results['end_state'] = self.end_state 184 if self.changed: 185 self.results['updates'] = self.updates_cmd 186 else: 187 self.results['updates'] = list() 188 189 self.module.exit_json(**self.results) 190 191 def judge_if_config_exist(self): 192 """ judge whether configuration has existed""" 193 if self.overlay_enable == self.global_info['evpnOverLay']: 194 return True 195 196 return False 197 198 def config_evnp_global(self): 199 """ set global EVPN configuration""" 200 if not self.conf_exist: 201 if self.overlay_enable == 'enable': 202 self.cli_add_command('evpn-overlay enable') 203 else: 204 self.cli_add_command('evpn-overlay enable', True) 205 206 if self.commands: 207 self.cli_load_config(self.commands) 208 self.changed = True 209 210 def work(self): 211 """execute task""" 212 self.get_evpn_global_info() 213 self.get_existing() 214 self.get_proposed() 215 self.conf_exist = self.judge_if_config_exist() 216 217 self.config_evnp_global() 218 219 self.get_end_state() 220 self.show_result() 221 222 223def main(): 224 """main function entry""" 225 226 argument_spec = dict( 227 evpn_overlay_enable=dict( 228 required=True, type='str', choices=['enable', 'disable']), 229 ) 230 argument_spec.update(ce_argument_spec) 231 evpn_global = EvpnGlobal(argument_spec) 232 evpn_global.work() 233 234 235if __name__ == '__main__': 236 main() 237