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