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_snmp_target_host 26version_added: "2.4" 27short_description: Manages SNMP target host configuration on HUAWEI CloudEngine switches. 28description: 29 - Manages SNMP target host configurations on HUAWEI CloudEngine switches. 30author: 31 - wangdezhuang (@QijunPan) 32notes: 33 - This module requires the netconf system service be enabled on the remote device being managed. 34 - Recommended connection is C(netconf). 35 - This module also works with C(local) connections for legacy playbooks. 36options: 37 version: 38 description: 39 - Version(s) Supported by SNMP Engine. 40 choices: ['none', 'v1', 'v2c', 'v3', 'v1v2c', 'v1v3', 'v2cv3', 'all'] 41 connect_port: 42 description: 43 - Udp port used by SNMP agent to connect the Network management. 44 host_name: 45 description: 46 - Unique name to identify target host entry. 47 address: 48 description: 49 - Network Address. 50 notify_type: 51 description: 52 - To configure notify type as trap or inform. 53 choices: ['trap','inform'] 54 vpn_name: 55 description: 56 - VPN instance Name. 57 recv_port: 58 description: 59 - UDP Port number used by network management to receive alarm messages. 60 security_model: 61 description: 62 - Security Model. 63 choices: ['v1','v2c', 'v3'] 64 security_name: 65 description: 66 - Security Name. 67 security_name_v3: 68 description: 69 - Security Name V3. 70 security_level: 71 description: 72 - Security level indicating whether to use authentication and encryption. 73 choices: ['noAuthNoPriv','authentication', 'privacy'] 74 is_public_net: 75 description: 76 - To enable or disable Public Net-manager for target Host. 77 default: no_use 78 choices: ['no_use','true','false'] 79 interface_name: 80 description: 81 - Name of the interface to send the trap message. 82''' 83 84EXAMPLES = ''' 85 86- name: CloudEngine snmp target host test 87 hosts: cloudengine 88 connection: local 89 gather_facts: no 90 vars: 91 cli: 92 host: "{{ inventory_hostname }}" 93 port: "{{ ansible_ssh_port }}" 94 username: "{{ username }}" 95 password: "{{ password }}" 96 transport: cli 97 98 tasks: 99 100 - name: "Config SNMP version" 101 ce_snmp_target_host: 102 state: present 103 version: v2cv3 104 provider: "{{ cli }}" 105 106 - name: "Config SNMP target host" 107 ce_snmp_target_host: 108 state: present 109 host_name: test1 110 address: 1.1.1.1 111 notify_type: trap 112 vpn_name: js 113 security_model: v2c 114 security_name: wdz 115 provider: "{{ cli }}" 116''' 117 118RETURN = ''' 119changed: 120 description: check to see if a change was made on the device 121 returned: always 122 type: bool 123 sample: true 124proposed: 125 description: k/v pairs of parameters passed into module 126 returned: always 127 type: dict 128 sample: {"address": "10.135.182.158", "host_name": "test2", 129 "notify_type": "trap", "security_level": "authentication", 130 "security_model": "v3", "security_name_v3": "wdz", 131 "state": "present", "vpn_name": "js"} 132existing: 133 description: k/v pairs of existing aaa server 134 returned: always 135 type: dict 136 sample: {} 137end_state: 138 description: k/v pairs of aaa params after module execution 139 returned: always 140 type: dict 141 sample: {"target host info": [{"address": "10.135.182.158", "domain": "snmpUDPDomain", 142 "nmsName": "test2", "notifyType": "trap", 143 "securityLevel": "authentication", "securityModel": "v3", 144 "securityNameV3": "wdz", "vpnInstanceName": "js"}]} 145updates: 146 description: command sent to the device 147 returned: always 148 type: list 149 sample: ["snmp-agent target-host host-name test2 trap address udp-domain 10.135.182.158 vpn-instance js params securityname wdz v3 authentication"] 150''' 151 152from xml.etree import ElementTree 153from ansible.module_utils.basic import AnsibleModule 154from ansible.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, \ 155 ce_argument_spec, load_config, check_ip_addr 156 157# get snmp version 158CE_GET_SNMP_VERSION = """ 159 <filter type="subtree"> 160 <snmp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> 161 <engine> 162 <version></version> 163 </engine> 164 </snmp> 165 </filter> 166""" 167# merge snmp version 168CE_MERGE_SNMP_VERSION = """ 169 <config> 170 <snmp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> 171 <engine operation="merge"> 172 <version>%s</version> 173 </engine> 174 </snmp> 175 </config> 176""" 177 178# get snmp target host 179CE_GET_SNMP_TARGET_HOST_HEADER = """ 180 <filter type="subtree"> 181 <snmp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> 182 <targetHosts> 183 <targetHost> 184 <nmsName></nmsName> 185""" 186CE_GET_SNMP_TARGET_HOST_TAIL = """ 187 </targetHost> 188 </targetHosts> 189 </snmp> 190 </filter> 191""" 192 193# merge snmp target host 194CE_MERGE_SNMP_TARGET_HOST_HEADER = """ 195 <config> 196 <snmp xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> 197 <targetHosts> 198 <targetHost operation="merge"> 199 <nmsName>%s</nmsName> 200""" 201CE_MERGE_SNMP_TARGET_HOST_TAIL = """ 202 </targetHost> 203 </targetHosts> 204 </snmp> 205 </config> 206""" 207 208# create snmp target host 209CE_CREATE_SNMP_TARGET_HOST_HEADER = """ 210 <config> 211 <snmp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> 212 <targetHosts> 213 <targetHost operation="create"> 214 <nmsName>%s</nmsName> 215""" 216CE_CREATE_SNMP_TARGET_HOST_TAIL = """ 217 </targetHost> 218 </targetHosts> 219 </snmp> 220 </config> 221""" 222 223# delete snmp target host 224CE_DELETE_SNMP_TARGET_HOST_HEADER = """ 225 <config> 226 <snmp xmlns="http://www.huawei.com/netconf/vrp" format-version="1.0" content-version="1.0"> 227 <targetHosts> 228 <targetHost operation="delete"> 229 <nmsName>%s</nmsName> 230""" 231CE_DELETE_SNMP_TARGET_HOST_TAIL = """ 232 </targetHost> 233 </targetHosts> 234 </snmp> 235 </config> 236""" 237 238# get snmp listen port 239CE_GET_SNMP_PORT = """ 240 <filter type="subtree"> 241 <snmp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> 242 <systemCfg> 243 <snmpListenPort></snmpListenPort> 244 </systemCfg> 245 </snmp> 246 </filter> 247""" 248 249# merge snmp listen port 250CE_MERGE_SNMP_PORT = """ 251 <config> 252 <snmp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0"> 253 <systemCfg operation="merge"> 254 <snmpListenPort>%s</snmpListenPort> 255 </systemCfg> 256 </snmp> 257 </config> 258""" 259 260 261INTERFACE_TYPE = ['ethernet', 'eth-trunk', 'tunnel', 'null', 'loopback', 262 'vlanif', '100ge', '40ge', 'mtunnel', '10ge', 'ge', 'meth', 'vbdif', 'nve'] 263 264 265class SnmpTargetHost(object): 266 """ Manages SNMP target host configuration """ 267 268 def __init__(self, **kwargs): 269 """ Class init """ 270 271 # module 272 argument_spec = kwargs["argument_spec"] 273 self.spec = argument_spec 274 required_together = [("address", "notify_type"), ("address", "notify_type")] 275 required_if = [ 276 ["security_model", "v1", ["security_name"]], 277 ["security_model", "v2c", ["security_name"]], 278 ["security_model", "v3", ["security_name_v3"]] 279 ] 280 self.module = AnsibleModule( 281 argument_spec=argument_spec, 282 required_together=required_together, 283 required_if=required_if, 284 supports_check_mode=True 285 ) 286 287 # module args 288 self.state = self.module.params['state'] 289 self.version = self.module.params['version'] 290 self.connect_port = self.module.params['connect_port'] 291 self.host_name = self.module.params['host_name'] 292 self.domain = "snmpUDPDomain" 293 self.address = self.module.params['address'] 294 self.notify_type = self.module.params['notify_type'] 295 self.vpn_name = self.module.params['vpn_name'] 296 self.recv_port = self.module.params['recv_port'] 297 self.security_model = self.module.params['security_model'] 298 self.security_name = self.module.params['security_name'] 299 self.security_name_v3 = self.module.params['security_name_v3'] 300 self.security_level = self.module.params['security_level'] 301 self.is_public_net = self.module.params['is_public_net'] 302 self.interface_name = self.module.params['interface_name'] 303 304 # config 305 self.cur_cli_cfg = dict() 306 self.cur_netconf_cfg = dict() 307 self.end_netconf_cfg = dict() 308 309 # state 310 self.changed = False 311 self.updates_cmd = list() 312 self.results = dict() 313 self.proposed = dict() 314 self.existing = dict() 315 self.end_state = dict() 316 317 def netconf_get_config(self, conf_str): 318 """ Get configure by netconf """ 319 320 xml_str = get_nc_config(self.module, conf_str) 321 322 return xml_str 323 324 def netconf_set_config(self, conf_str): 325 """ Set configure by netconf """ 326 327 xml_str = set_nc_config(self.module, conf_str) 328 329 return xml_str 330 331 def check_cli_args(self): 332 """ Check invalid cli args """ 333 334 if self.connect_port: 335 if int(self.connect_port) != 161 and (int(self.connect_port) > 65535 or int(self.connect_port) < 1025): 336 self.module.fail_json( 337 msg='Error: The value of connect_port %s is out of [161, 1025 - 65535].' % self.connect_port) 338 339 def check_netconf_args(self, result): 340 """ Check invalid netconf args """ 341 342 need_cfg = True 343 same_flag = True 344 delete_flag = False 345 result["target_host_info"] = [] 346 347 if self.host_name: 348 349 if len(self.host_name) > 32 or len(self.host_name) < 1: 350 self.module.fail_json( 351 msg='Error: The len of host_name is out of [1 - 32].') 352 353 if self.vpn_name and self.is_public_net != 'no_use': 354 if self.is_public_net == "true": 355 self.module.fail_json( 356 msg='Error: Do not support vpn_name and is_public_net at the same time.') 357 358 conf_str = CE_GET_SNMP_TARGET_HOST_HEADER 359 360 if self.domain: 361 conf_str += "<domain></domain>" 362 363 if self.address: 364 if not check_ip_addr(ipaddr=self.address): 365 self.module.fail_json( 366 msg='Error: The host address [%s] is invalid.' % self.address) 367 conf_str += "<address></address>" 368 369 if self.notify_type: 370 conf_str += "<notifyType></notifyType>" 371 372 if self.vpn_name: 373 if len(self.vpn_name) > 31 or len(self.vpn_name) < 1: 374 self.module.fail_json( 375 msg='Error: The len of vpn_name is out of [1 - 31].') 376 conf_str += "<vpnInstanceName></vpnInstanceName>" 377 378 if self.recv_port: 379 if int(self.recv_port) > 65535 or int(self.recv_port) < 0: 380 self.module.fail_json( 381 msg='Error: The value of recv_port is out of [0 - 65535].') 382 conf_str += "<portNumber></portNumber>" 383 384 if self.security_model: 385 conf_str += "<securityModel></securityModel>" 386 387 if self.security_name: 388 if len(self.security_name) > 32 or len(self.security_name) < 1: 389 self.module.fail_json( 390 msg='Error: The len of security_name is out of [1 - 32].') 391 conf_str += "<securityName></securityName>" 392 393 if self.security_name_v3: 394 if len(self.security_name_v3) > 32 or len(self.security_name_v3) < 1: 395 self.module.fail_json( 396 msg='Error: The len of security_name_v3 is out of [1 - 32].') 397 conf_str += "<securityNameV3></securityNameV3>" 398 399 if self.security_level: 400 conf_str += "<securityLevel></securityLevel>" 401 402 if self.is_public_net != 'no_use': 403 conf_str += "<isPublicNet></isPublicNet>" 404 405 if self.interface_name: 406 if len(self.interface_name) > 63 or len(self.interface_name) < 1: 407 self.module.fail_json( 408 msg='Error: The len of interface_name is out of [1 - 63].') 409 410 find_flag = False 411 for item in INTERFACE_TYPE: 412 if item in self.interface_name.lower(): 413 find_flag = True 414 break 415 if not find_flag: 416 self.module.fail_json( 417 msg='Error: Please input full name of interface_name.') 418 419 conf_str += "<interface-name></interface-name>" 420 421 conf_str += CE_GET_SNMP_TARGET_HOST_TAIL 422 recv_xml = self.netconf_get_config(conf_str=conf_str) 423 424 if "<data/>" in recv_xml: 425 if self.state == "present": 426 same_flag = False 427 else: 428 delete_flag = False 429 else: 430 xml_str = recv_xml.replace('\r', '').replace('\n', '').\ 431 replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ 432 replace('xmlns="http://www.huawei.com/netconf/vrp"', "") 433 434 root = ElementTree.fromstring(xml_str) 435 target_host_info = root.findall( 436 "snmp/targetHosts/targetHost") 437 if target_host_info: 438 for tmp in target_host_info: 439 tmp_dict = dict() 440 for site in tmp: 441 if site.tag in ["nmsName", "domain", "address", "notifyType", "vpnInstanceName", 442 "portNumber", "securityModel", "securityName", "securityNameV3", 443 "securityLevel", "isPublicNet", "interface-name"]: 444 tmp_dict[site.tag] = site.text 445 446 result["target_host_info"].append(tmp_dict) 447 448 if result["target_host_info"]: 449 for tmp in result["target_host_info"]: 450 451 same_flag = True 452 453 if "nmsName" in tmp.keys(): 454 if tmp["nmsName"] != self.host_name: 455 same_flag = False 456 else: 457 delete_flag = True 458 459 if "domain" in tmp.keys(): 460 if tmp["domain"] != self.domain: 461 same_flag = False 462 463 if "address" in tmp.keys(): 464 if tmp["address"] != self.address: 465 same_flag = False 466 467 if "notifyType" in tmp.keys(): 468 if tmp["notifyType"] != self.notify_type: 469 same_flag = False 470 471 if "vpnInstanceName" in tmp.keys(): 472 if tmp["vpnInstanceName"] != self.vpn_name: 473 same_flag = False 474 475 if "portNumber" in tmp.keys(): 476 if tmp["portNumber"] != self.recv_port: 477 same_flag = False 478 479 if "securityModel" in tmp.keys(): 480 if tmp["securityModel"] != self.security_model: 481 same_flag = False 482 483 if "securityName" in tmp.keys(): 484 if tmp["securityName"] != self.security_name: 485 same_flag = False 486 487 if "securityNameV3" in tmp.keys(): 488 if tmp["securityNameV3"] != self.security_name_v3: 489 same_flag = False 490 491 if "securityLevel" in tmp.keys(): 492 if tmp["securityLevel"] != self.security_level: 493 same_flag = False 494 495 if "isPublicNet" in tmp.keys(): 496 if tmp["isPublicNet"] != self.is_public_net: 497 same_flag = False 498 499 if "interface-name" in tmp.keys(): 500 if tmp.get("interface-name") is not None: 501 if tmp["interface-name"].lower() != self.interface_name.lower(): 502 same_flag = False 503 else: 504 same_flag = False 505 506 if same_flag: 507 break 508 509 if self.state == "present": 510 need_cfg = True 511 if same_flag: 512 need_cfg = False 513 else: 514 need_cfg = False 515 if delete_flag: 516 need_cfg = True 517 518 result["need_cfg"] = need_cfg 519 520 def cli_load_config(self, commands): 521 """ Load configure by cli """ 522 523 if not self.module.check_mode: 524 load_config(self.module, commands) 525 526 def get_snmp_version(self): 527 """ Get snmp version """ 528 529 version = None 530 conf_str = CE_GET_SNMP_VERSION 531 recv_xml = self.netconf_get_config(conf_str=conf_str) 532 533 if "<data/>" in recv_xml: 534 pass 535 536 else: 537 xml_str = recv_xml.replace('\r', '').replace('\n', '').\ 538 replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ 539 replace('xmlns="http://www.huawei.com/netconf/vrp"', "") 540 541 root = ElementTree.fromstring(xml_str) 542 version_info = root.find("snmp/engine") 543 if version_info: 544 for site in version_info: 545 if site.tag in ["version"]: 546 version = site.text 547 548 return version 549 550 def xml_get_connect_port(self): 551 """ Get connect port by xml """ 552 tmp_cfg = None 553 conf_str = CE_GET_SNMP_PORT 554 recv_xml = self.netconf_get_config(conf_str=conf_str) 555 if "<data/>" in recv_xml: 556 pass 557 else: 558 xml_str = recv_xml.replace('\r', '').replace('\n', '').\ 559 replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\ 560 replace('xmlns="http://www.huawei.com/netconf/vrp"', "") 561 562 root = ElementTree.fromstring(xml_str) 563 snmp_port_info = root.findall("snmp/systemCfg/snmpListenPort") 564 565 if snmp_port_info: 566 tmp_cfg = snmp_port_info[0].text 567 return tmp_cfg 568 569 def get_proposed(self): 570 """ Get proposed state """ 571 572 self.proposed["state"] = self.state 573 574 if self.version: 575 self.proposed["version"] = self.version 576 if self.connect_port: 577 self.proposed["connect_port"] = self.connect_port 578 if self.host_name: 579 self.proposed["host_name"] = self.host_name 580 if self.address: 581 self.proposed["address"] = self.address 582 if self.notify_type: 583 self.proposed["notify_type"] = self.notify_type 584 if self.vpn_name: 585 self.proposed["vpn_name"] = self.vpn_name 586 if self.recv_port: 587 self.proposed["recv_port"] = self.recv_port 588 if self.security_model: 589 self.proposed["security_model"] = self.security_model 590 if self.security_name: 591 self.proposed["security_name"] = "******" 592 if self.security_name_v3: 593 self.proposed["security_name_v3"] = self.security_name_v3 594 if self.security_level: 595 self.proposed["security_level"] = self.security_level 596 if self.is_public_net != 'no_use': 597 self.proposed["is_public_net"] = self.is_public_net 598 if self.interface_name: 599 self.proposed["interface_name"] = self.interface_name 600 601 def get_existing(self): 602 """ Get existing state """ 603 604 if self.version: 605 version = self.get_snmp_version() 606 if version: 607 self.cur_cli_cfg["version"] = version 608 self.existing["version"] = version 609 610 if self.connect_port: 611 tmp_cfg = self.xml_get_connect_port() 612 if tmp_cfg: 613 self.cur_cli_cfg["connect port"] = tmp_cfg 614 self.existing["connect port"] = tmp_cfg 615 616 if self.host_name: 617 self.existing["target host info"] = self.cur_netconf_cfg[ 618 "target_host_info"] 619 620 def get_end_state(self): 621 """ Get end state """ 622 623 if self.version: 624 version = self.get_snmp_version() 625 if version: 626 self.end_state["version"] = version 627 628 if self.connect_port: 629 tmp_cfg = self.xml_get_connect_port() 630 if tmp_cfg: 631 self.end_state["connect port"] = tmp_cfg 632 633 if self.host_name: 634 self.end_state["target host info"] = self.end_netconf_cfg[ 635 "target_host_info"] 636 if self.existing == self.end_state: 637 self.changed = False 638 self.updates_cmd = list() 639 640 def config_version_cli(self): 641 """ Config version by cli """ 642 643 if "disable" in self.cur_cli_cfg["version"]: 644 cmd = "snmp-agent sys-info version %s" % self.version 645 self.updates_cmd.append(cmd) 646 647 cmds = list() 648 cmds.append(cmd) 649 650 self.cli_load_config(cmds) 651 self.changed = True 652 653 else: 654 if self.version != self.cur_cli_cfg["version"]: 655 cmd = "snmp-agent sys-info version %s disable" % self.cur_cli_cfg[ 656 "version"] 657 self.updates_cmd.append(cmd) 658 cmd = "snmp-agent sys-info version %s" % self.version 659 self.updates_cmd.append(cmd) 660 661 cmds = list() 662 cmds.append(cmd) 663 664 self.cli_load_config(cmds) 665 self.changed = True 666 667 def undo_config_version_cli(self): 668 """ Undo config version by cli """ 669 670 if "disable" in self.cur_cli_cfg["version"]: 671 pass 672 else: 673 cmd = "snmp-agent sys-info version %s disable" % self.cur_cli_cfg[ 674 "version"] 675 676 cmds = list() 677 cmds.append(cmd) 678 679 self.updates_cmd.append(cmd) 680 self.cli_load_config(cmds) 681 self.changed = True 682 683 def config_connect_port_xml(self): 684 """ Config connect port by xml """ 685 686 if "connect port" in self.cur_cli_cfg.keys(): 687 if self.cur_cli_cfg["connect port"] == self.connect_port: 688 pass 689 else: 690 cmd = "snmp-agent udp-port %s" % self.connect_port 691 692 cmds = list() 693 cmds.append(cmd) 694 695 self.updates_cmd.append(cmd) 696 conf_str = CE_MERGE_SNMP_PORT % self.connect_port 697 self.netconf_set_config(conf_str=conf_str) 698 self.changed = True 699 else: 700 cmd = "snmp-agent udp-port %s" % self.connect_port 701 702 cmds = list() 703 cmds.append(cmd) 704 705 self.updates_cmd.append(cmd) 706 conf_str = CE_MERGE_SNMP_PORT % self.connect_port 707 self.netconf_set_config(conf_str=conf_str) 708 self.changed = True 709 710 def undo_config_connect_port_cli(self): 711 """ Undo config connect port by cli """ 712 713 if "connect port" in self.cur_cli_cfg.keys(): 714 if not self.cur_cli_cfg["connect port"]: 715 pass 716 else: 717 cmd = "undo snmp-agent udp-port" 718 719 cmds = list() 720 cmds.append(cmd) 721 722 self.updates_cmd.append(cmd) 723 connect_port = "161" 724 conf_str = CE_MERGE_SNMP_PORT % connect_port 725 self.netconf_set_config(conf_str=conf_str) 726 self.changed = True 727 728 def merge_snmp_target_host(self): 729 """ Merge snmp target host operation """ 730 731 conf_str = CE_MERGE_SNMP_TARGET_HOST_HEADER % self.host_name 732 733 if self.domain: 734 conf_str += "<domain>%s</domain>" % self.domain 735 if self.address: 736 conf_str += "<address>%s</address>" % self.address 737 if self.notify_type: 738 conf_str += "<notifyType>%s</notifyType>" % self.notify_type 739 if self.vpn_name: 740 conf_str += "<vpnInstanceName>%s</vpnInstanceName>" % self.vpn_name 741 if self.recv_port: 742 conf_str += "<portNumber>%s</portNumber>" % self.recv_port 743 if self.security_model: 744 conf_str += "<securityModel>%s</securityModel>" % self.security_model 745 if self.security_name: 746 conf_str += "<securityName>%s</securityName>" % self.security_name 747 if self.security_name_v3: 748 conf_str += "<securityNameV3>%s</securityNameV3>" % self.security_name_v3 749 if self.security_level: 750 conf_str += "<securityLevel>%s</securityLevel>" % self.security_level 751 if self.is_public_net != 'no_use': 752 conf_str += "<isPublicNet>%s</isPublicNet>" % self.is_public_net 753 if self.interface_name: 754 conf_str += "<interface-name>%s</interface-name>" % self.interface_name 755 756 conf_str += CE_MERGE_SNMP_TARGET_HOST_TAIL 757 758 recv_xml = self.netconf_set_config(conf_str=conf_str) 759 760 if "<ok/>" not in recv_xml: 761 self.module.fail_json(msg='Error: Merge snmp target host failed.') 762 763 cmd = "snmp-agent target-host host-name %s " % self.host_name 764 cmd += "%s " % self.notify_type 765 cmd += "address udp-domain %s " % self.address 766 767 if self.recv_port: 768 cmd += "udp-port %s " % self.recv_port 769 if self.interface_name: 770 cmd += "source %s " % self.interface_name 771 if self.vpn_name: 772 cmd += "vpn-instance %s " % self.vpn_name 773 if self.is_public_net == "true": 774 cmd += "public-net " 775 if self.security_model in ["v1", "v2c"] and self.security_name: 776 cmd += "params securityname %s %s " % ( 777 "******", self.security_model) 778 if self.security_model == "v3" and self.security_name_v3: 779 cmd += "params securityname %s %s " % ( 780 self.security_name_v3, self.security_model) 781 if self.security_level and self.security_level in ["authentication", "privacy"]: 782 cmd += "%s" % self.security_level 783 784 self.changed = True 785 self.updates_cmd.append(cmd) 786 787 def delete_snmp_target_host(self): 788 """ Delete snmp target host operation """ 789 790 conf_str = CE_DELETE_SNMP_TARGET_HOST_HEADER % self.host_name 791 792 if self.domain: 793 conf_str += "<domain>%s</domain>" % self.domain 794 if self.address: 795 conf_str += "<address>%s</address>" % self.address 796 if self.notify_type: 797 conf_str += "<notifyType>%s</notifyType>" % self.notify_type 798 if self.vpn_name: 799 conf_str += "<vpnInstanceName>%s</vpnInstanceName>" % self.vpn_name 800 if self.recv_port: 801 conf_str += "<portNumber>%s</portNumber>" % self.recv_port 802 if self.security_model: 803 conf_str += "<securityModel>%s</securityModel>" % self.security_model 804 if self.security_name: 805 conf_str += "<securityName>%s</securityName>" % self.security_name 806 if self.security_name_v3: 807 conf_str += "<securityNameV3>%s</securityNameV3>" % self.security_name_v3 808 if self.security_level: 809 conf_str += "<securityLevel>%s</securityLevel>" % self.security_level 810 if self.is_public_net != 'no_use': 811 conf_str += "<isPublicNet>%s</isPublicNet>" % self.is_public_net 812 if self.interface_name: 813 conf_str += "<interface-name>%s</interface-name>" % self.interface_name 814 815 conf_str += CE_DELETE_SNMP_TARGET_HOST_TAIL 816 817 recv_xml = self.netconf_set_config(conf_str=conf_str) 818 819 if "<ok/>" not in recv_xml: 820 self.module.fail_json(msg='Error: Delete snmp target host failed.') 821 822 if not self.address: 823 cmd = "undo snmp-agent target-host host-name %s " % self.host_name 824 else: 825 if self.notify_type == "trap": 826 cmd = "undo snmp-agent target-host trap address udp-domain %s " % self.address 827 else: 828 cmd = "undo snmp-agent target-host inform address udp-domain %s " % self.address 829 if self.recv_port: 830 cmd += "udp-port %s " % self.recv_port 831 if self.interface_name: 832 cmd += "source %s " % self.interface_name 833 if self.vpn_name: 834 cmd += "vpn-instance %s " % self.vpn_name 835 if self.is_public_net == "true": 836 cmd += "public-net " 837 if self.security_model in ["v1", "v2c"] and self.security_name: 838 cmd += "params securityname %s" % "******" 839 if self.security_model == "v3" and self.security_name_v3: 840 cmd += "params securityname %s" % self.security_name_v3 841 842 self.changed = True 843 self.updates_cmd.append(cmd) 844 845 def merge_snmp_version(self): 846 """ Merge snmp version operation """ 847 848 conf_str = CE_MERGE_SNMP_VERSION % self.version 849 recv_xml = self.netconf_set_config(conf_str=conf_str) 850 851 if "<ok/>" not in recv_xml: 852 self.module.fail_json(msg='Error: Merge snmp version failed.') 853 854 if self.version == "none": 855 cmd = "snmp-agent sys-info version %s disable" % self.cur_cli_cfg[ 856 "version"] 857 self.updates_cmd.append(cmd) 858 elif self.version == "v1v2c": 859 cmd = "snmp-agent sys-info version v1" 860 self.updates_cmd.append(cmd) 861 cmd = "snmp-agent sys-info version v2c" 862 self.updates_cmd.append(cmd) 863 elif self.version == "v1v3": 864 cmd = "snmp-agent sys-info version v1" 865 self.updates_cmd.append(cmd) 866 cmd = "snmp-agent sys-info version v3" 867 self.updates_cmd.append(cmd) 868 elif self.version == "v2cv3": 869 cmd = "snmp-agent sys-info version v2c" 870 self.updates_cmd.append(cmd) 871 cmd = "snmp-agent sys-info version v3" 872 self.updates_cmd.append(cmd) 873 else: 874 cmd = "snmp-agent sys-info version %s" % self.version 875 self.updates_cmd.append(cmd) 876 877 self.changed = True 878 879 def work(self): 880 """ Main work function """ 881 882 self.check_cli_args() 883 self.check_netconf_args(self.cur_netconf_cfg) 884 self.get_proposed() 885 self.get_existing() 886 887 if self.state == "present": 888 if self.version: 889 if self.version != self.cur_cli_cfg["version"]: 890 self.merge_snmp_version() 891 if self.connect_port: 892 self.config_connect_port_xml() 893 if self.cur_netconf_cfg["need_cfg"]: 894 self.merge_snmp_target_host() 895 896 else: 897 if self.connect_port: 898 self.undo_config_connect_port_cli() 899 if self.cur_netconf_cfg["need_cfg"]: 900 self.delete_snmp_target_host() 901 902 self.check_netconf_args(self.end_netconf_cfg) 903 self.get_end_state() 904 905 self.results['changed'] = self.changed 906 self.results['proposed'] = self.proposed 907 self.results['existing'] = self.existing 908 self.results['end_state'] = self.end_state 909 self.results['updates'] = self.updates_cmd 910 911 self.module.exit_json(**self.results) 912 913 914def main(): 915 """ Module main """ 916 917 argument_spec = dict( 918 state=dict(choices=['present', 'absent'], default='present'), 919 version=dict(choices=['none', 'v1', 'v2c', 'v3', 920 'v1v2c', 'v1v3', 'v2cv3', 'all']), 921 connect_port=dict(type='str'), 922 host_name=dict(type='str'), 923 address=dict(type='str'), 924 notify_type=dict(choices=['trap', 'inform']), 925 vpn_name=dict(type='str'), 926 recv_port=dict(type='str'), 927 security_model=dict(choices=['v1', 'v2c', 'v3']), 928 security_name=dict(type='str', no_log=True), 929 security_name_v3=dict(type='str'), 930 security_level=dict( 931 choices=['noAuthNoPriv', 'authentication', 'privacy']), 932 is_public_net=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']), 933 interface_name=dict(type='str') 934 ) 935 936 argument_spec.update(ce_argument_spec) 937 module = SnmpTargetHost(argument_spec=argument_spec) 938 module.work() 939 940 941if __name__ == '__main__': 942 main() 943