Best JavaScript code snippet using istanbul
ce_sflow.py
Source:ce_sflow.py
1#!/usr/bin/python2#3# This file is part of Ansible4#5# Ansible is free software: you can redistribute it and/or modify6# it under the terms of the GNU General Public License as published by7# the Free Software Foundation, either version 3 of the License, or8# (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 of12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13# GNU General Public License for more details.14#15# You should have received a copy of the GNU General Public License16# along with Ansible. If not, see <http://www.gnu.org/licenses/>.17#18ANSIBLE_METADATA = {'metadata_version': '1.1',19 'status': ['preview'],20 'supported_by': 'community'}21DOCUMENTATION = """22---23module: ce_sflow24version_added: "2.4"25short_description: Manages sFlow configuration on HUAWEI CloudEngine switches.26description:27 - Configure Sampled Flow (sFlow) to monitor traffic on an interface in real time,28 detect abnormal traffic, and locate the source of attack traffic,29 ensuring stable running of the network.30author: QijunPan (@CloudEngine-Ansible)31options:32 agent_ip:33 description:34 - Specifies the IPv4/IPv6 address of an sFlow agent.35 required: false36 default: null37 source_ip:38 description:39 - Specifies the source IPv4/IPv6 address of sFlow packets.40 required: false41 default: null42 collector_id:43 description:44 - Specifies the ID of an sFlow collector. This ID is used when you specify45 the collector in subsequent sFlow configuration.46 required: false47 default: null48 choices: ['1', '2']49 collector_ip:50 description:51 - Specifies the IPv4/IPv6 address of the sFlow collector.52 required: false53 default: null54 collector_ip_vpn:55 description:56 - Specifies the name of a VPN instance.57 The value is a string of 1 to 31 case-sensitive characters, spaces not supported.58 When double quotation marks are used around the string, spaces are allowed in the string.59 The value C(_public_) is reserved and cannot be used as the VPN instance name.60 required: false61 default: null62 collector_datagram_size:63 description:64 - Specifies the maximum length of sFlow packets sent from an sFlow agent to an sFlow collector.65 The value is an integer, in bytes. It ranges from 1024 to 8100. The default value is 1400.66 required: false67 default: null68 collector_udp_port:69 description:70 - Specifies the UDP destination port number of sFlow packets.71 The value is an integer that ranges from 1 to 65535. The default value is 6343.72 required: false73 default: null74 collector_meth:75 description:76 - Configures the device to send sFlow packets through service interfaces,77 enhancing the sFlow packet forwarding capability.78 The enhanced parameter is optional. No matter whether you configure the enhanced mode,79 the switch determines to send sFlow packets through service cards or management port80 based on the routing information on the collector.81 When the value is meth, the device forwards sFlow packets at the control plane.82 When the value is enhanced, the device forwards sFlow packets at the forwarding plane to83 enhance the sFlow packet forwarding capacity.84 required: false85 default: null86 choices: ['meth', 'enhanced']87 collector_description:88 description:89 - Specifies the description of an sFlow collector.90 The value is a string of 1 to 255 case-sensitive characters without spaces.91 required: false92 default: null93 sflow_interface:94 description:95 - Full name of interface for Flow Sampling or Counter.96 It must be a physical interface, Eth-Trunk, or Layer 2 subinterface.97 required: false98 default: null99 sample_collector:100 description:101 - Indicates the ID list of the collector.102 required: false103 default: null104 sample_rate:105 description:106 - Specifies the flow sampling rate in the format 1/rate.107 The value is an integer and ranges from 1 to 4294967295. The default value is 8192.108 required: false109 default: null110 sample_length:111 description:112 - Specifies the maximum length of sampled packets.113 The value is an integer and ranges from 18 to 512, in bytes. The default value is 128.114 required: false115 default: null116 sample_direction:117 description:118 - Enables flow sampling in the inbound or outbound direction.119 required: false120 default: null121 choices: ['inbound', 'outbound', 'both']122 counter_collector:123 description:124 - Indicates the ID list of the counter collector.125 required: false126 default: null127 counter_interval:128 description:129 - Indicates the counter sampling interval.130 The value is an integer that ranges from 10 to 4294967295, in seconds. The default value is 20.131 required: false132 default: null133 export_route:134 description:135 - Configures the sFlow packets sent by the switch not to carry routing information.136 required: false137 default: null138 choices: ['enable', 'disable']139 rate_limit:140 description:141 - Specifies the rate of sFlow packets sent from a card to the control plane.142 The value is an integer that ranges from 100 to 1500, in pps.143 required: false144 default: null145 rate_limit_slot:146 description:147 - Specifies the slot where the rate of output sFlow packets is limited.148 If this parameter is not specified, the rate of sFlow packets sent from149 all cards to the control plane is limited.150 The value is an integer or a string of characters.151 required: false152 default: null153 forward_enp_slot:154 description:155 - Enable the Embedded Network Processor (ENP) chip function.156 The switch uses the ENP chip to perform sFlow sampling,157 and the maximum sFlow sampling interval is 65535.158 If you set the sampling interval to be larger than 65535,159 the switch automatically restores it to 65535.160 The value is an integer or 'all'.161 required: false162 default: null163 state:164 description:165 - Determines whether the config should be present or not166 on the device.167 required: false168 default: present169 choices: ['present', 'absent']170"""171EXAMPLES = '''172---173- name: sflow module test174 hosts: ce128175 connection: local176 gather_facts: no177 vars:178 cli:179 host: "{{ inventory_hostname }}"180 port: "{{ ansible_ssh_port }}"181 username: "{{ username }}"182 password: "{{ password }}"183 transport: cli184 tasks:185 - name: Configuring sFlow Agent186 ce_sflow:187 agent_ip: 6.6.6.6188 provider: '{{ cli }}'189 - name: Configuring sFlow Collector190 ce_sflow:191 collector_id: 1192 collector_ip: 7.7.7.7193 collector_ip_vpn: vpn1194 collector_description: Collector1195 provider: '{{ cli }}'196 - name: Configure flow sampling.197 ce_sflow:198 sflow_interface: 10GE2/0/2199 sample_collector: 1200 sample_direction: inbound201 provider: '{{ cli }}'202 - name: Configure counter sampling.203 ce_sflow:204 sflow_interface: 10GE2/0/2205 counter_collector: 1206 counter_interval: 1000207 provider: '{{ cli }}'208'''209RETURN = '''210proposed:211 description: k/v pairs of parameters passed into module212 returned: verbose mode213 type: dict214 sample: {"agent_ip": "6.6.6.6", "state": "present"}215existing:216 description: k/v pairs of existing configuration217 returned: verbose mode218 type: dict219 sample: {"agent": {}}220end_state:221 description: k/v pairs of configuration after module execution222 returned: verbose mode223 type: dict224 sample: {"agent": {"family": "ipv4", "ipv4Addr": "1.2.3.4", "ipv6Addr": null}}225updates:226 description: commands sent to the device227 returned: always228 type: list229 sample: ["sflow agent ip 6.6.6.6"]230changed:231 description: check to see if a change was made on the device232 returned: always233 type: boolean234 sample: true235'''236import re237from xml.etree import ElementTree238from ansible.module_utils.basic import AnsibleModule239from ansible.module_utils.ce import get_nc_config, set_nc_config, ce_argument_spec, check_ip_addr240from ansible.module_utils.ce import get_config, load_config241CE_NC_GET_SFLOW = """242<filter type="subtree">243<sflow xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">244 <sources>245 <source>246 <family></family>247 <ipv4Addr></ipv4Addr>248 <ipv6Addr></ipv6Addr>249 </source>250 </sources>251 <agents>252 <agent>253 <family></family>254 <ipv4Addr></ipv4Addr>255 <ipv6Addr></ipv6Addr>256 </agent>257 </agents>258 <collectors>259 <collector>260 <collectorID></collectorID>261 <family></family>262 <ipv4Addr></ipv4Addr>263 <ipv6Addr></ipv6Addr>264 <vrfName></vrfName>265 <datagramSize></datagramSize>266 <port></port>267 <description></description>268 <meth></meth>269 </collector>270 </collectors>271 <samplings>272 <sampling>273 <ifName>%s</ifName>274 <collectorID></collectorID>275 <direction></direction>276 <length></length>277 <rate></rate>278 </sampling>279 </samplings>280 <counters>281 <counter>282 <ifName>%s</ifName>283 <collectorID></collectorID>284 <interval></interval>285 </counter>286 </counters>287 <exports>288 <export>289 <ExportRoute></ExportRoute>290 </export>291 </exports>292</sflow>293</filter>294"""295def is_config_exist(cmp_cfg, test_cfg):296 """is configuration exist?"""297 if not cmp_cfg or not test_cfg:298 return False299 return bool(test_cfg in cmp_cfg)300def is_valid_ip_vpn(vpname):301 """check ip vpn"""302 if not vpname:303 return False304 if vpname == "_public_":305 return False306 if len(vpname) < 1 or len(vpname) > 31:307 return False308 return True309def get_ip_version(address):310 """get ip version fast"""311 if not address:312 return None313 if address.count(':') >= 2 and address.count(":") <= 7:314 return "ipv6"315 elif address.count('.') == 3:316 return "ipv4"317 else:318 return None319def get_interface_type(interface):320 """get the type of interface, such as 10GE, ETH-TRUNK, VLANIF..."""321 if interface is None:322 return None323 if interface.upper().startswith('GE'):324 iftype = 'ge'325 elif interface.upper().startswith('10GE'):326 iftype = '10ge'327 elif interface.upper().startswith('25GE'):328 iftype = '25ge'329 elif interface.upper().startswith('4X10GE'):330 iftype = '4x10ge'331 elif interface.upper().startswith('40GE'):332 iftype = '40ge'333 elif interface.upper().startswith('100GE'):334 iftype = '100ge'335 elif interface.upper().startswith('VLANIF'):336 iftype = 'vlanif'337 elif interface.upper().startswith('LOOPBACK'):338 iftype = 'loopback'339 elif interface.upper().startswith('METH'):340 iftype = 'meth'341 elif interface.upper().startswith('ETH-TRUNK'):342 iftype = 'eth-trunk'343 elif interface.upper().startswith('VBDIF'):344 iftype = 'vbdif'345 elif interface.upper().startswith('NVE'):346 iftype = 'nve'347 elif interface.upper().startswith('TUNNEL'):348 iftype = 'tunnel'349 elif interface.upper().startswith('ETHERNET'):350 iftype = 'ethernet'351 elif interface.upper().startswith('FCOE-PORT'):352 iftype = 'fcoe-port'353 elif interface.upper().startswith('FABRIC-PORT'):354 iftype = 'fabric-port'355 elif interface.upper().startswith('STACK-PORT'):356 iftype = 'stack-port'357 elif interface.upper().startswith('NULL'):358 iftype = 'null'359 else:360 return None361 return iftype.lower()362def get_rate_limit(config):363 """get sflow management-plane export rate-limit info"""364 get = re.findall(r"sflow management-plane export rate-limit ([0-9]+) slot ([0-9]+)", config)365 if not get:366 get = re.findall(r"sflow management-plane export rate-limit ([0-9]+)", config)367 if not get:368 return None369 else:370 return dict(rate_limit=get[0])371 else:372 limit = list()373 for slot in get:374 limit.append(dict(rate_limit=slot[0], slot_id=slot[1]))375 return limit376def get_forward_enp(config):377 """get assign forward enp sflow enable slot info"""378 get = re.findall(r"assign forward enp sflow enable slot (\S+)", config)379 if not get:380 return None381 else:382 return list(get)383class Sflow(object):384 """Manages sFlow"""385 def __init__(self, argument_spec):386 self.spec = argument_spec387 self.module = None388 self.__init_module__()389 # module input info390 self.agent_ip = self.module.params['agent_ip']391 self.agent_version = None392 self.source_ip = self.module.params['source_ip']393 self.source_version = None394 self.export_route = self.module.params['export_route']395 self.rate_limit = self.module.params['rate_limit']396 self.rate_limit_slot = self.module.params['rate_limit_slot']397 self.forward_enp_slot = self.module.params['forward_enp_slot']398 self.collector_id = self.module.params['collector_id']399 self.collector_ip = self.module.params['collector_ip']400 self.collector_version = None401 self.collector_ip_vpn = self.module.params['collector_ip_vpn']402 self.collector_datagram_size = self.module.params['collector_datagram_size']403 self.collector_udp_port = self.module.params['collector_udp_port']404 self.collector_meth = self.module.params['collector_meth']405 self.collector_description = self.module.params['collector_description']406 self.sflow_interface = self.module.params['sflow_interface']407 self.sample_collector = self.module.params['sample_collector'] or list()408 self.sample_rate = self.module.params['sample_rate']409 self.sample_length = self.module.params['sample_length']410 self.sample_direction = self.module.params['sample_direction']411 self.counter_collector = self.module.params['counter_collector'] or list()412 self.counter_interval = self.module.params['counter_interval']413 self.state = self.module.params['state']414 # state415 self.config = "" # current config416 self.sflow_dict = dict()417 self.changed = False418 self.updates_cmd = list()419 self.commands = list()420 self.results = dict()421 self.proposed = dict()422 self.existing = dict()423 self.end_state = dict()424 def __init_module__(self):425 """init module"""426 required_together = [("collector_id", "collector_ip")]427 self.module = AnsibleModule(428 argument_spec=self.spec, required_together=required_together, supports_check_mode=True)429 def check_response(self, con_obj, xml_name):430 """Check if response message is already succeed"""431 xml_str = con_obj.xml432 if "<ok/>" not in xml_str:433 self.module.fail_json(msg='Error: %s failed.' % xml_name)434 def netconf_set_config(self, xml_str, xml_name):435 """netconf set config"""436 rcv_xml = set_nc_config(self.module, xml_str)437 if "<ok/>" not in rcv_xml:438 self.module.fail_json(msg='Error: %s failed.' % xml_name)439 def cli_load_config(self, commands):440 """load config by cli"""441 if not self.module.check_mode:442 load_config(self.module, commands)443 def get_current_config(self):444 """get current configuration"""445 flags = list()446 exp = ""447 if self.rate_limit:448 exp += "assign sflow management-plane export rate-limit %s" % self.rate_limit449 if self.rate_limit_slot:450 exp += " slot %s" % self.rate_limit_slot451 exp += "$"452 if self.forward_enp_slot:453 if exp:454 exp += "|"455 exp += "assign forward enp sflow enable slot %s$" % self.forward_enp_slot456 if exp:457 exp = " | ignore-case include " + exp458 flags.append(exp)459 return get_config(self.module, flags)460 else:461 return ""462 def cli_add_command(self, command, undo=False):463 """add command to self.update_cmd and self.commands"""464 if undo and command.lower() not in ["quit", "return"]:465 cmd = "undo " + command466 else:467 cmd = command468 self.commands.append(cmd) # set to device469 if command.lower() not in ["quit", "return"]:470 self.updates_cmd.append(cmd) # show updates result471 def get_sflow_dict(self):472 """ sflow config dict"""473 sflow_dict = dict(source=list(), agent=dict(), collector=list(),474 sampling=dict(), counter=dict(), export=dict())475 conf_str = CE_NC_GET_SFLOW % (476 self.sflow_interface, self.sflow_interface)477 if not self.collector_meth:478 conf_str = conf_str.replace("<meth></meth>", "")479 rcv_xml = get_nc_config(self.module, conf_str)480 if "<data/>" in rcv_xml:481 return sflow_dict482 xml_str = rcv_xml.replace('\r', '').replace('\n', '').\483 replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\484 replace('xmlns="http://www.huawei.com/netconf/vrp"', "")485 root = ElementTree.fromstring(xml_str)486 # get source info487 srcs = root.findall("data/sflow/sources/source")488 if srcs:489 for src in srcs:490 attrs = dict()491 for attr in src:492 if attr.tag in ["family", "ipv4Addr", "ipv6Addr"]:493 attrs[attr.tag] = attr.text494 sflow_dict["source"].append(attrs)495 # get agent info496 agent = root.find("data/sflow/agents/agent")497 if agent:498 for attr in agent:499 if attr.tag in ["family", "ipv4Addr", "ipv6Addr"]:500 sflow_dict["agent"][attr.tag] = attr.text501 # get collector info502 collectors = root.findall("data/sflow/collectors/collector")503 if collectors:504 for collector in collectors:505 attrs = dict()506 for attr in collector:507 if attr.tag in ["collectorID", "family", "ipv4Addr", "ipv6Addr",508 "vrfName", "datagramSize", "port", "description", "meth"]:509 attrs[attr.tag] = attr.text510 sflow_dict["collector"].append(attrs)511 # get sampling info512 sample = root.find("data/sflow/samplings/sampling")513 if sample:514 for attr in sample:515 if attr.tag in ["ifName", "collectorID", "direction", "length", "rate"]:516 sflow_dict["sampling"][attr.tag] = attr.text517 # get counter info518 counter = root.find("data/sflow/counters/counter")519 if counter:520 for attr in counter:521 if attr.tag in ["ifName", "collectorID", "interval"]:522 sflow_dict["counter"][attr.tag] = attr.text523 # get export info524 export = root.find("data/sflow/exports/export")525 if export:526 for attr in export:527 if attr.tag == "ExportRoute":528 sflow_dict["export"][attr.tag] = attr.text529 return sflow_dict530 def config_agent(self):531 """configures sFlow agent"""532 xml_str = ''533 if not self.agent_ip:534 return xml_str535 self.agent_version = get_ip_version(self.agent_ip)536 if not self.agent_version:537 self.module.fail_json(msg="Error: agent_ip is invalid.")538 if self.state == "present":539 if self.agent_ip != self.sflow_dict["agent"].get("ipv4Addr") \540 and self.agent_ip != self.sflow_dict["agent"].get("ipv6Addr"):541 xml_str += '<agents><agent operation="merge">'542 xml_str += '<family>%s</family>' % self.agent_version543 if self.agent_version == "ipv4":544 xml_str += '<ipv4Addr>%s</ipv4Addr>' % self.agent_ip545 self.updates_cmd.append("sflow agent ip %s" % self.agent_ip)546 else:547 xml_str += '<ipv6Addr>%s</ipv6Addr>' % self.agent_ip548 self.updates_cmd.append("sflow agent ipv6 %s" % self.agent_ip)549 xml_str += '</agent></agents>'550 else:551 if self.agent_ip == self.sflow_dict["agent"].get("ipv4Addr") \552 or self.agent_ip == self.sflow_dict["agent"].get("ipv6Addr"):553 xml_str += '<agents><agent operation="delete"></agent></agents>'554 self.updates_cmd.append("undo sflow agent")555 return xml_str556 def config_source(self):557 """configures the source IP address for sFlow packets"""558 xml_str = ''559 if not self.source_ip:560 return xml_str561 self.source_version = get_ip_version(self.source_ip)562 if not self.source_version:563 self.module.fail_json(msg="Error: source_ip is invalid.")564 src_dict = dict()565 for src in self.sflow_dict["source"]:566 if src.get("family") == self.source_version:567 src_dict = src568 break569 if self.state == "present":570 if self.source_ip != src_dict.get("ipv4Addr") \571 and self.source_ip != src_dict.get("ipv6Addr"):572 xml_str += '<sources><source operation="merge">'573 xml_str += '<family>%s</family>' % self.source_version574 if self.source_version == "ipv4":575 xml_str += '<ipv4Addr>%s</ipv4Addr>' % self.source_ip576 self.updates_cmd.append("sflow source ip %s" % self.source_ip)577 else:578 xml_str += '<ipv6Addr>%s</ipv6Addr>' % self.source_ip579 self.updates_cmd.append(580 "sflow source ipv6 %s" % self.source_ip)581 xml_str += '</source ></sources>'582 else:583 if self.source_ip == src_dict.get("ipv4Addr"):584 xml_str += '<sources><source operation="delete"><family>ipv4</family></source ></sources>'585 self.updates_cmd.append("undo sflow source ip %s" % self.source_ip)586 elif self.source_ip == src_dict.get("ipv6Addr"):587 xml_str += '<sources><source operation="delete"><family>ipv6</family></source ></sources>'588 self.updates_cmd.append("undo sflow source ipv6 %s" % self.source_ip)589 return xml_str590 def config_collector(self):591 """creates an sFlow collector and sets or modifies optional parameters for the sFlow collector"""592 xml_str = ''593 if not self.collector_id:594 return xml_str595 if self.state == "present" and not self.collector_ip:596 return xml_str597 if self.collector_ip:598 self.collector_version = get_ip_version(self.collector_ip)599 if not self.collector_version:600 self.module.fail_json(msg="Error: collector_ip is invalid.")601 # get collector dict602 exist_dict = dict()603 for collector in self.sflow_dict["collector"]:604 if collector.get("collectorID") == self.collector_id:605 exist_dict = collector606 break607 change = False608 if self.state == "present":609 if not exist_dict:610 change = True611 elif self.collector_version != exist_dict.get("family"):612 change = True613 elif self.collector_version == "ipv4" and self.collector_ip != exist_dict.get("ipv4Addr"):614 change = True615 elif self.collector_version == "ipv6" and self.collector_ip != exist_dict.get("ipv6Addr"):616 change = True617 elif self.collector_ip_vpn and self.collector_ip_vpn != exist_dict.get("vrfName"):618 change = True619 elif not self.collector_ip_vpn and exist_dict.get("vrfName") != "_public_":620 change = True621 elif self.collector_udp_port and self.collector_udp_port != exist_dict.get("port"):622 change = True623 elif not self.collector_udp_port and exist_dict.get("port") != "6343":624 change = True625 elif self.collector_datagram_size and self.collector_datagram_size != exist_dict.get("datagramSize"):626 change = True627 elif not self.collector_datagram_size and exist_dict.get("datagramSize") != "1400":628 change = True629 elif self.collector_meth and self.collector_meth != exist_dict.get("meth"):630 change = True631 elif not self.collector_meth and exist_dict.get("meth") and exist_dict.get("meth") != "meth":632 change = True633 elif self.collector_description and self.collector_description != exist_dict.get("description"):634 change = True635 elif not self.collector_description and exist_dict.get("description"):636 change = True637 else:638 pass639 else: # absent640 # collector not exist641 if not exist_dict:642 return xml_str643 if self.collector_version and self.collector_version != exist_dict.get("family"):644 return xml_str645 if self.collector_version == "ipv4" and self.collector_ip != exist_dict.get("ipv4Addr"):646 return xml_str647 if self.collector_version == "ipv6" and self.collector_ip != exist_dict.get("ipv6Addr"):648 return xml_str649 if self.collector_ip_vpn and self.collector_ip_vpn != exist_dict.get("vrfName"):650 return xml_str651 if self.collector_udp_port and self.collector_udp_port != exist_dict.get("port"):652 return xml_str653 if self.collector_datagram_size and self.collector_datagram_size != exist_dict.get("datagramSize"):654 return xml_str655 if self.collector_meth and self.collector_meth != exist_dict.get("meth"):656 return xml_str657 if self.collector_description and self.collector_description != exist_dict.get("description"):658 return xml_str659 change = True660 if not change:661 return xml_str662 # update or delete663 if self.state == "absent":664 xml_str += '<collectors><collector operation="delete"><collectorID>%s</collectorID>' % self.collector_id665 self.updates_cmd.append("undo collector %s" % self.collector_id)666 else:667 xml_str += '<collectors><collector operation="merge"><collectorID>%s</collectorID>' % self.collector_id668 cmd = "sflow collector %s" % self.collector_id669 xml_str += '<family>%s</family>' % self.collector_version670 if self.collector_version == "ipv4":671 cmd += " ip %s" % self.collector_ip672 xml_str += '<ipv4Addr>%s</ipv4Addr>' % self.collector_ip673 else:674 cmd += " ipv6 %s" % self.collector_ip675 xml_str += '<ipv6Addr>%s</ipv6Addr>' % self.collector_ip676 if self.collector_ip_vpn:677 cmd += " vpn-instance %s" % self.collector_ip_vpn678 xml_str += '<vrfName>%s</vrfName>' % self.collector_ip_vpn679 if self.collector_datagram_size:680 cmd += " length %s" % self.collector_datagram_size681 xml_str += '<datagramSize>%s</datagramSize>' % self.collector_datagram_size682 if self.collector_udp_port:683 cmd += " udp-port %s" % self.collector_udp_port684 xml_str += '<port>%s</port>' % self.collector_udp_port685 if self.collector_description:686 cmd += " description %s" % self.collector_description687 xml_str += '<description>%s</description>' % self.collector_description688 else:689 xml_str += '<description></description>'690 if self.collector_meth:691 if self.collector_meth == "enhanced":692 cmd += " enhanced"693 xml_str += '<meth>%s</meth>' % self.collector_meth694 self.updates_cmd.append(cmd)695 xml_str += "</collector></collectors>"696 return xml_str697 def config_sampling(self):698 """configure sflow sampling on an interface"""699 xml_str = ''700 if not self.sflow_interface:701 return xml_str702 if not self.sflow_dict["sampling"] and self.state == "absent":703 return xml_str704 self.updates_cmd.append("interface %s" % self.sflow_interface)705 if self.state == "present":706 xml_str += '<samplings><sampling operation="merge"><ifName>%s</ifName>' % self.sflow_interface707 else:708 xml_str += '<samplings><sampling operation="delete"><ifName>%s</ifName>' % self.sflow_interface709 # sample_collector710 if self.sample_collector:711 if self.sflow_dict["sampling"].get("collectorID") \712 and self.sflow_dict["sampling"].get("collectorID") != "invalid":713 existing = self.sflow_dict["sampling"].get("collectorID").split(',')714 else:715 existing = list()716 if self.state == "present":717 diff = list(set(self.sample_collector) - set(existing))718 if diff:719 self.updates_cmd.append(720 "sflow sampling collector %s" % ' '.join(diff))721 new_set = list(self.sample_collector + existing)722 xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(new_set)))723 else:724 same = list(set(self.sample_collector) & set(existing))725 if same:726 self.updates_cmd.append(727 "undo sflow sampling collector %s" % ' '.join(same))728 xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(same)))729 # sample_rate730 if self.sample_rate:731 exist = bool(self.sample_rate == self.sflow_dict["sampling"].get("rate"))732 if self.state == "present" and not exist:733 self.updates_cmd.append(734 "sflow sampling rate %s" % self.sample_rate)735 xml_str += '<rate>%s</rate>' % self.sample_rate736 elif self.state == "absent" and exist:737 self.updates_cmd.append(738 "undo sflow sampling rate %s" % self.sample_rate)739 xml_str += '<rate>%s</rate>' % self.sample_rate740 # sample_length741 if self.sample_length:742 exist = bool(self.sample_length == self.sflow_dict["sampling"].get("length"))743 if self.state == "present" and not exist:744 self.updates_cmd.append(745 "sflow sampling length %s" % self.sample_length)746 xml_str += '<length>%s</length>' % self.sample_length747 elif self.state == "absent" and exist:748 self.updates_cmd.append(749 "undo sflow sampling length %s" % self.sample_length)750 xml_str += '<length>%s</length>' % self.sample_length751 # sample_direction752 if self.sample_direction:753 direction = list()754 if self.sample_direction == "both":755 direction = ["inbound", "outbound"]756 else:757 direction.append(self.sample_direction)758 existing = list()759 if self.sflow_dict["sampling"].get("direction"):760 if self.sflow_dict["sampling"].get("direction") == "both":761 existing = ["inbound", "outbound"]762 else:763 existing.append(764 self.sflow_dict["sampling"].get("direction"))765 if self.state == "present":766 diff = list(set(direction) - set(existing))767 if diff:768 new_set = list(set(direction + existing))769 self.updates_cmd.append(770 "sflow sampling %s" % ' '.join(diff))771 if len(new_set) > 1:772 new_dir = "both"773 else:774 new_dir = new_set[0]775 xml_str += '<direction>%s</direction>' % new_dir776 else:777 same = list(set(existing) & set(direction))778 if same:779 self.updates_cmd.append("undo sflow sampling %s" % ' '.join(same))780 if len(same) > 1:781 del_dir = "both"782 else:783 del_dir = same[0]784 xml_str += '<direction>%s</direction>' % del_dir785 if xml_str.endswith("</ifName>"):786 self.updates_cmd.pop()787 return ""788 xml_str += '</sampling></samplings>'789 return xml_str790 def config_counter(self):791 """configures sflow counter on an interface"""792 xml_str = ''793 if not self.sflow_interface:794 return xml_str795 if not self.sflow_dict["counter"] and self.state == "absent":796 return xml_str797 self.updates_cmd.append("interface %s" % self.sflow_interface)798 if self.state == "present":799 xml_str += '<counters><counter operation="merge"><ifName>%s</ifName>' % self.sflow_interface800 else:801 xml_str += '<counters><counter operation="delete"><ifName>%s</ifName>' % self.sflow_interface802 # counter_collector803 if self.counter_collector:804 if self.sflow_dict["counter"].get("collectorID") \805 and self.sflow_dict["counter"].get("collectorID") != "invalid":806 existing = self.sflow_dict["counter"].get("collectorID").split(',')807 else:808 existing = list()809 if self.state == "present":810 diff = list(set(self.counter_collector) - set(existing))811 if diff:812 self.updates_cmd.append("sflow counter collector %s" % ' '.join(diff))813 new_set = list(self.counter_collector + existing)814 xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(new_set)))815 else:816 same = list(set(self.counter_collector) & set(existing))817 if same:818 self.updates_cmd.append(819 "undo sflow counter collector %s" % ' '.join(same))820 xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(same)))821 # counter_interval822 if self.counter_interval:823 exist = bool(self.counter_interval == self.sflow_dict["counter"].get("interval"))824 if self.state == "present" and not exist:825 self.updates_cmd.append(826 "sflow counter interval %s" % self.counter_interval)827 xml_str += '<interval>%s</interval>' % self.counter_interval828 elif self.state == "absent" and exist:829 self.updates_cmd.append(830 "undo sflow counter interval %s" % self.counter_interval)831 xml_str += '<interval>%s</interval>' % self.counter_interval832 if xml_str.endswith("</ifName>"):833 self.updates_cmd.pop()834 return ""835 xml_str += '</counter></counters>'836 return xml_str837 def config_export(self):838 """configure sflow export"""839 xml_str = ''840 if not self.export_route:841 return xml_str842 if self.export_route == "enable":843 if self.sflow_dict["export"] and self.sflow_dict["export"].get("ExportRoute") == "disable":844 xml_str = '<exports><export operation="delete"><ExportRoute>disable</ExportRoute></export></exports>'845 self.updates_cmd.append("undo sflow export extended-route-data disable")846 else: # disable847 if not self.sflow_dict["export"] or self.sflow_dict["export"].get("ExportRoute") != "disable":848 xml_str = '<exports><export operation="create"><ExportRoute>disable</ExportRoute></export></exports>'849 self.updates_cmd.append("sflow export extended-route-data disable")850 return xml_str851 def config_assign(self):852 """configure assign"""853 # assign sflow management-plane export rate-limit rate-limit [ slot slot-id ]854 if self.rate_limit:855 cmd = "assign sflow management-plane export rate-limit %s" % self.rate_limit856 if self.rate_limit_slot:857 cmd += " slot %s" % self.rate_limit_slot858 exist = is_config_exist(self.config, cmd)859 if self.state == "present" and not exist:860 self.cli_add_command(cmd)861 elif self.state == "absent" and exist:862 self.cli_add_command(cmd, undo=True)863 # assign forward enp sflow enable slot { slot-id | all }864 if self.forward_enp_slot:865 cmd = "assign forward enp sflow enable slot %s" % self.forward_enp_slot866 exist = is_config_exist(self.config, cmd)867 if self.state == "present" and not exist:868 self.cli_add_command(cmd)869 elif self.state == "absent" and exist:870 self.cli_add_command(cmd, undo=True)871 def netconf_load_config(self, xml_str):872 """load sflow config by netconf"""873 if not xml_str:874 return875 xml_cfg = """876 <config>877 <sflow xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">878 %s879 </sflow>880 </config>""" % xml_str881 self.netconf_set_config(xml_cfg, "SET_SFLOW")882 self.changed = True883 def check_params(self):884 """Check all input params"""885 # check agent_ip886 if self.agent_ip:887 self.agent_ip = self.agent_ip.upper()888 if not check_ip_addr(self.agent_ip):889 self.module.fail_json(msg="Error: agent_ip is invalid.")890 # check source_ip891 if self.source_ip:892 self.source_ip = self.source_ip.upper()893 if not check_ip_addr(self.source_ip):894 self.module.fail_json(msg="Error: source_ip is invalid.")895 # check collector896 if self.collector_id:897 # check collector_ip and collector_ip_vpn898 if self.collector_ip:899 self.collector_ip = self.collector_ip.upper()900 if not check_ip_addr(self.collector_ip):901 self.module.fail_json(902 msg="Error: collector_ip is invalid.")903 if self.collector_ip_vpn and not is_valid_ip_vpn(self.collector_ip_vpn):904 self.module.fail_json(905 msg="Error: collector_ip_vpn is invalid.")906 # check collector_datagram_size ranges from 1024 to 8100907 if self.collector_datagram_size:908 if not self.collector_datagram_size.isdigit():909 self.module.fail_json(910 msg="Error: collector_datagram_size is not digit.")911 if int(self.collector_datagram_size) < 1024 or int(self.collector_datagram_size) > 8100:912 self.module.fail_json(913 msg="Error: collector_datagram_size is not ranges from 1024 to 8100.")914 # check collector_udp_port ranges from 1 to 65535915 if self.collector_udp_port:916 if not self.collector_udp_port.isdigit():917 self.module.fail_json(918 msg="Error: collector_udp_port is not digit.")919 if int(self.collector_udp_port) < 1 or int(self.collector_udp_port) > 65535:920 self.module.fail_json(921 msg="Error: collector_udp_port is not ranges from 1 to 65535.")922 # check collector_description 1 to 255 case-sensitive characters923 if self.collector_description:924 if self.collector_description.count(" "):925 self.module.fail_json(926 msg="Error: collector_description should without spaces.")927 if len(self.collector_description) < 1 or len(self.collector_description) > 255:928 self.module.fail_json(929 msg="Error: collector_description is not ranges from 1 to 255.")930 # check sflow_interface931 if self.sflow_interface:932 intf_type = get_interface_type(self.sflow_interface)933 if not intf_type:934 self.module.fail_json(msg="Error: intf_type is invalid.")935 if intf_type not in ['ge', '10ge', '25ge', '4x10ge', '40ge', '100ge', 'eth-trunk']:936 self.module.fail_json(937 msg="Error: interface %s is not support sFlow." % self.sflow_interface)938 # check sample_collector939 if self.sample_collector:940 self.sample_collector.sort()941 if self.sample_collector not in [["1"], ["2"], ["1", "2"]]:942 self.module.fail_json(943 msg="Error: sample_collector is invalid.")944 # check sample_rate ranges from 1 to 4294967295945 if self.sample_rate:946 if not self.sample_rate.isdigit():947 self.module.fail_json(948 msg="Error: sample_rate is not digit.")949 if int(self.sample_rate) < 1 or int(self.sample_rate) > 4294967295:950 self.module.fail_json(951 msg="Error: sample_rate is not ranges from 1 to 4294967295.")952 # check sample_length ranges from 18 to 512953 if self.sample_length:954 if not self.sample_length.isdigit():955 self.module.fail_json(956 msg="Error: sample_rate is not digit.")957 if int(self.sample_length) < 18 or int(self.sample_length) > 512:958 self.module.fail_json(959 msg="Error: sample_length is not ranges from 18 to 512.")960 # check counter_collector961 if self.counter_collector:962 self.counter_collector.sort()963 if self.counter_collector not in [["1"], ["2"], ["1", "2"]]:964 self.module.fail_json(965 msg="Error: counter_collector is invalid.")966 # counter_interval ranges from 10 to 4294967295967 if self.counter_interval:968 if not self.counter_interval.isdigit():969 self.module.fail_json(970 msg="Error: counter_interval is not digit.")971 if int(self.counter_interval) < 10 or int(self.counter_interval) > 4294967295:972 self.module.fail_json(973 msg="Error: sample_length is not ranges from 10 to 4294967295.")974 # check rate_limit ranges from 100 to 1500 and check rate_limit_slot975 if self.rate_limit:976 if not self.rate_limit.isdigit():977 self.module.fail_json(msg="Error: rate_limit is not digit.")978 if int(self.rate_limit) < 100 or int(self.rate_limit) > 1500:979 self.module.fail_json(980 msg="Error: rate_limit is not ranges from 100 to 1500.")981 if self.rate_limit_slot and not self.rate_limit_slot.isdigit():982 self.module.fail_json(983 msg="Error: rate_limit_slot is not digit.")984 # check forward_enp_slot985 if self.forward_enp_slot:986 self.forward_enp_slot.lower()987 if not self.forward_enp_slot.isdigit() and self.forward_enp_slot != "all":988 self.module.fail_json(989 msg="Error: forward_enp_slot is invalid.")990 def get_proposed(self):991 """get proposed info"""992 # base config993 if self.agent_ip:994 self.proposed["agent_ip"] = self.agent_ip995 if self.source_ip:996 self.proposed["source_ip"] = self.source_ip997 if self.export_route:998 self.proposed["export_route"] = self.export_route999 if self.rate_limit:1000 self.proposed["rate_limit"] = self.rate_limit1001 self.proposed["rate_limit_slot"] = self.rate_limit_slot1002 if self.forward_enp_slot:1003 self.proposed["forward_enp_slot"] = self.forward_enp_slot1004 if self.collector_id:1005 self.proposed["collector_id"] = self.collector_id1006 if self.collector_ip:1007 self.proposed["collector_ip"] = self.collector_ip1008 self.proposed["collector_ip_vpn"] = self.collector_ip_vpn1009 if self.collector_datagram_size:1010 self.proposed[1011 "collector_datagram_size"] = self.collector_datagram_size1012 if self.collector_udp_port:1013 self.proposed["collector_udp_port"] = self.collector_udp_port1014 if self.collector_meth:1015 self.proposed["collector_meth"] = self.collector_meth1016 if self.collector_description:1017 self.proposed[1018 "collector_description"] = self.collector_description1019 # sample and counter config1020 if self.sflow_interface:1021 self.proposed["sflow_interface"] = self.sflow_interface1022 if self.sample_collector:1023 self.proposed["sample_collector"] = self.sample_collector1024 if self.sample_rate:1025 self.proposed["sample_rate"] = self.sample_rate1026 if self.sample_length:1027 self.proposed["sample_length"] = self.sample_length1028 if self.sample_direction:1029 self.proposed["sample_direction"] = self.sample_direction1030 if self.counter_collector:1031 self.proposed["counter_collector"] = self.counter_collector1032 if self.counter_interval:1033 self.proposed["counter_interval"] = self.counter_interval1034 self.proposed["state"] = self.state1035 def get_existing(self):1036 """get existing info"""1037 if self.config:1038 if self.rate_limit:1039 self.existing["rate_limit"] = get_rate_limit(self.config)1040 if self.forward_enp_slot:1041 self.existing["forward_enp_slot"] = get_forward_enp(1042 self.config)1043 if not self.sflow_dict:1044 return1045 if self.agent_ip:1046 self.existing["agent"] = self.sflow_dict["agent"]1047 if self.source_ip:1048 self.existing["source"] = self.sflow_dict["source"]1049 if self.collector_id:1050 self.existing["collector"] = self.sflow_dict["collector"]1051 if self.export_route:1052 self.existing["export"] = self.sflow_dict["export"]1053 if self.sflow_interface:1054 self.existing["sampling"] = self.sflow_dict["sampling"]1055 self.existing["counter"] = self.sflow_dict["counter"]1056 def get_end_state(self):1057 """get end state info"""1058 config = self.get_current_config()1059 if config:1060 if self.rate_limit:1061 self.end_state["rate_limit"] = get_rate_limit(config)1062 if self.forward_enp_slot:1063 self.end_state["forward_enp_slot"] = get_forward_enp(config)1064 sflow_dict = self.get_sflow_dict()1065 if not sflow_dict:1066 return1067 if self.agent_ip:1068 self.end_state["agent"] = sflow_dict["agent"]1069 if self.source_ip:1070 self.end_state["source"] = sflow_dict["source"]1071 if self.collector_id:1072 self.end_state["collector"] = sflow_dict["collector"]1073 if self.export_route:1074 self.end_state["export"] = sflow_dict["export"]1075 if self.sflow_interface:1076 self.end_state["sampling"] = sflow_dict["sampling"]1077 self.end_state["counter"] = sflow_dict["counter"]1078 def work(self):1079 """worker"""1080 self.check_params()1081 self.sflow_dict = self.get_sflow_dict()1082 self.config = self.get_current_config()1083 self.get_existing()1084 self.get_proposed()1085 # deal present or absent1086 xml_str = ''1087 if self.export_route:1088 xml_str += self.config_export()1089 if self.agent_ip:1090 xml_str += self.config_agent()1091 if self.source_ip:1092 xml_str += self.config_source()1093 if self.state == "present":1094 if self.collector_id and self.collector_ip:1095 xml_str += self.config_collector()1096 if self.sflow_interface:1097 xml_str += self.config_sampling()1098 xml_str += self.config_counter()1099 else:1100 if self.sflow_interface:1101 xml_str += self.config_sampling()1102 xml_str += self.config_counter()1103 if self.collector_id:1104 xml_str += self.config_collector()1105 if self.rate_limit or self.forward_enp_slot:1106 self.config_assign()1107 if self.commands:1108 self.cli_load_config(self.commands)1109 self.changed = True1110 if xml_str:1111 self.netconf_load_config(xml_str)1112 self.changed = True1113 self.get_end_state()1114 self.results['changed'] = self.changed1115 self.results['proposed'] = self.proposed1116 self.results['existing'] = self.existing1117 self.results['end_state'] = self.end_state1118 if self.changed:1119 self.results['updates'] = self.updates_cmd1120 else:1121 self.results['updates'] = list()1122 self.module.exit_json(**self.results)1123def main():1124 """Module main"""1125 argument_spec = dict(1126 agent_ip=dict(required=False, type='str'),1127 source_ip=dict(required=False, type='str'),1128 export_route=dict(required=False, type='str',1129 choices=['enable', 'disable']),1130 rate_limit=dict(required=False, type='str'),1131 rate_limit_slot=dict(required=False, type='str'),1132 forward_enp_slot=dict(required=False, type='str'),1133 collector_id=dict(required=False, type='str', choices=['1', '2']),1134 collector_ip=dict(required=False, type='str'),1135 collector_ip_vpn=dict(required=False, type='str'),1136 collector_datagram_size=dict(required=False, type='str'),1137 collector_udp_port=dict(required=False, type='str'),1138 collector_meth=dict(required=False, type='str',1139 choices=['meth', 'enhanced']),1140 collector_description=dict(required=False, type='str'),1141 sflow_interface=dict(required=False, type='str'),1142 sample_collector=dict(required=False, type='list'),1143 sample_rate=dict(required=False, type='str'),1144 sample_length=dict(required=False, type='str'),1145 sample_direction=dict(required=False, type='str',1146 choices=['inbound', 'outbound', 'both']),1147 counter_collector=dict(required=False, type='list'),1148 counter_interval=dict(required=False, type='str'),1149 state=dict(required=False, default='present',1150 choices=['present', 'absent'])1151 )1152 argument_spec.update(ce_argument_spec)1153 module = Sflow(argument_spec)1154 module.work()1155if __name__ == '__main__':...
test_collector.py
Source:test_collector.py
1# This file is part of Ansible2# -*- coding: utf-8 -*-3#4#5# Ansible is free software: you can redistribute it and/or modify6# it under the terms of the GNU General Public License as published by7# the Free Software Foundation, either version 3 of the License, or8# (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 of12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13# GNU General Public License for more details.14#15# You should have received a copy of the GNU General Public License16# along with Ansible. If not, see <http://www.gnu.org/licenses/>.17#18# Make coding more python3-ish19from __future__ import (absolute_import, division)20__metaclass__ = type21from collections import defaultdict22# for testing23from ansible.compat.tests import unittest24from ansible.module_utils.facts import collector25from ansible.module_utils.facts import default_collectors26class TestFindCollectorsForPlatform(unittest.TestCase):27 def test(self):28 compat_platforms = [{'system': 'Generic'}]29 res = collector.find_collectors_for_platform(default_collectors.collectors,30 compat_platforms)31 for coll_class in res:32 self.assertIn(coll_class._platform, ('Generic'))33 def test_linux(self):34 compat_platforms = [{'system': 'Linux'}]35 res = collector.find_collectors_for_platform(default_collectors.collectors,36 compat_platforms)37 for coll_class in res:38 self.assertIn(coll_class._platform, ('Linux'))39 def test_linux_or_generic(self):40 compat_platforms = [{'system': 'Generic'}, {'system': 'Linux'}]41 res = collector.find_collectors_for_platform(default_collectors.collectors,42 compat_platforms)43 for coll_class in res:44 self.assertIn(coll_class._platform, ('Generic', 'Linux'))45class TestSelectCollectorNames(unittest.TestCase):46 def test(self):47 collector_names = set(['distribution', 'all_ipv4_addresses',48 'local', 'pkg_mgr'])49 all_fact_subsets = self._all_fact_subsets()50 all_collector_classes = self._all_collector_classes()51 res = collector.select_collector_classes(collector_names,52 all_fact_subsets,53 all_collector_classes)54 expected = [default_collectors.DistributionFactCollector,55 default_collectors.PkgMgrFactCollector]56 self.assertEqual(res, expected)57 def test_reverse(self):58 collector_names = set(['distribution', 'all_ipv4_addresses',59 'local', 'pkg_mgr'])60 all_fact_subsets = self._all_fact_subsets()61 all_collector_classes = self._all_collector_classes()62 all_collector_classes.reverse()63 res = collector.select_collector_classes(collector_names,64 all_fact_subsets,65 all_collector_classes)66 expected = [default_collectors.PkgMgrFactCollector,67 default_collectors.DistributionFactCollector]68 self.assertEqual(res, expected)69 def test_default_collectors(self):70 platform_info = {'system': 'Generic'}71 compat_platforms = [platform_info]72 collectors_for_platform = collector.find_collectors_for_platform(default_collectors.collectors,73 compat_platforms)74 all_fact_subsets, aliases_map = collector.build_fact_id_to_collector_map(collectors_for_platform)75 all_valid_subsets = frozenset(all_fact_subsets.keys())76 collector_names = collector.get_collector_names(valid_subsets=all_valid_subsets,77 aliases_map=aliases_map,78 platform_info=platform_info)79 collector.select_collector_classes(collector_names,80 all_fact_subsets,81 default_collectors.collectors)82 def _all_collector_classes(self):83 return [default_collectors.DistributionFactCollector,84 default_collectors.PkgMgrFactCollector,85 default_collectors.LinuxNetworkCollector]86 def _all_fact_subsets(self, data=None):87 all_fact_subsets = defaultdict(list)88 _data = {'pkg_mgr': [default_collectors.PkgMgrFactCollector],89 'distribution': [default_collectors.DistributionFactCollector],90 'network': [default_collectors.LinuxNetworkCollector]}91 data = data or _data92 for key, value in data.items():93 all_fact_subsets[key] = value94 return all_fact_subsets95class TestGetCollectorNames(unittest.TestCase):96 def test_none(self):97 res = collector.get_collector_names()98 self.assertIsInstance(res, set)99 self.assertEqual(res, set([]))100 def test_empty_sets(self):101 res = collector.get_collector_names(valid_subsets=frozenset([]),102 minimal_gather_subset=frozenset([]),103 gather_subset=[])104 self.assertIsInstance(res, set)105 self.assertEqual(res, set([]))106 def test_empty_valid_and_min_with_all_gather_subset(self):107 res = collector.get_collector_names(valid_subsets=frozenset([]),108 minimal_gather_subset=frozenset([]),109 gather_subset=['all'])110 self.assertIsInstance(res, set)111 self.assertEqual(res, set([]))112 def test_one_valid_with_all_gather_subset(self):113 valid_subsets = frozenset(['my_fact'])114 res = collector.get_collector_names(valid_subsets=valid_subsets,115 minimal_gather_subset=frozenset([]),116 gather_subset=['all'])117 self.assertIsInstance(res, set)118 self.assertEqual(res, set(['my_fact']))119 def _compare_res(self, gather_subset1, gather_subset2,120 valid_subsets=None, min_subset=None):121 valid_subsets = valid_subsets or frozenset()122 minimal_gather_subset = min_subset or frozenset()123 res1 = collector.get_collector_names(valid_subsets=valid_subsets,124 minimal_gather_subset=minimal_gather_subset,125 gather_subset=gather_subset1)126 res2 = collector.get_collector_names(valid_subsets=valid_subsets,127 minimal_gather_subset=minimal_gather_subset,128 gather_subset=gather_subset2)129 return res1, res2130 def test_not_all_other_order(self):131 valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])132 minimal_gather_subset = frozenset(['min_fact'])133 res1, res2 = self._compare_res(['!all', 'whatever'],134 ['whatever', '!all'],135 valid_subsets=valid_subsets,136 min_subset=minimal_gather_subset)137 self.assertEqual(res1, res2)138 self.assertEqual(res1, set(['min_fact', 'whatever']))139 def test_not_all_other_order_min(self):140 valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])141 minimal_gather_subset = frozenset(['min_fact'])142 res1, res2 = self._compare_res(['!min_fact', 'whatever'],143 ['whatever', '!min_fact'],144 valid_subsets=valid_subsets,145 min_subset=minimal_gather_subset)146 self.assertEqual(res1, res2)147 self.assertEqual(res1, set(['whatever']))148 def test_one_minimal_with_all_gather_subset(self):149 my_fact = 'my_fact'150 valid_subsets = frozenset([my_fact])151 minimal_gather_subset = valid_subsets152 res = collector.get_collector_names(valid_subsets=valid_subsets,153 minimal_gather_subset=minimal_gather_subset,154 gather_subset=['all'])155 self.assertIsInstance(res, set)156 self.assertEqual(res, set(['my_fact']))157 def test_with_all_gather_subset(self):158 valid_subsets = frozenset(['my_fact', 'something_else', 'whatever'])159 minimal_gather_subset = frozenset(['my_fact'])160 # even with '!all', the minimal_gather_subset should be returned161 res = collector.get_collector_names(valid_subsets=valid_subsets,162 minimal_gather_subset=minimal_gather_subset,163 gather_subset=['all'])164 self.assertIsInstance(res, set)165 self.assertEqual(res, set(['my_fact', 'something_else', 'whatever']))166 def test_one_minimal_with_not_all_gather_subset(self):167 valid_subsets = frozenset(['my_fact', 'something_else', 'whatever'])168 minimal_gather_subset = frozenset(['my_fact'])169 # even with '!all', the minimal_gather_subset should be returned170 res = collector.get_collector_names(valid_subsets=valid_subsets,171 minimal_gather_subset=minimal_gather_subset,172 gather_subset=['!all'])173 self.assertIsInstance(res, set)174 self.assertEqual(res, set(['my_fact']))175 def test_gather_subset_excludes(self):176 valid_subsets = frozenset(['my_fact', 'something_else', 'whatever'])177 minimal_gather_subset = frozenset(['min_fact', 'min_another'])178 # even with '!all', the minimal_gather_subset should be returned179 res = collector.get_collector_names(valid_subsets=valid_subsets,180 minimal_gather_subset=minimal_gather_subset,181 # gather_subset=set(['all', '!my_fact', '!whatever']))182 # gather_subset=['all', '!my_fact', '!whatever'])183 gather_subset=['!min_fact', '!whatever'])184 self.assertIsInstance(res, set)185 # min_another is in minimal_gather_subset, so always returned186 self.assertEqual(res, set(['min_another']))187 def test_gather_subset_excludes_ordering(self):188 valid_subsets = frozenset(['my_fact', 'something_else', 'whatever'])189 minimal_gather_subset = frozenset(['my_fact'])190 res = collector.get_collector_names(valid_subsets=valid_subsets,191 minimal_gather_subset=minimal_gather_subset,192 gather_subset=['!all', 'whatever'])193 self.assertIsInstance(res, set)194 # excludes are higher precedence than includes, so !all excludes everything195 # and then minimal_gather_subset is added. so '!all', 'other' == '!all'196 self.assertEqual(res, set(['my_fact', 'whatever']))197 def test_gather_subset_excludes_min(self):198 valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])199 minimal_gather_subset = frozenset(['min_fact'])200 res = collector.get_collector_names(valid_subsets=valid_subsets,201 minimal_gather_subset=minimal_gather_subset,202 gather_subset=['whatever', '!min'])203 self.assertIsInstance(res, set)204 # excludes are higher precedence than includes, so !all excludes everything205 # and then minimal_gather_subset is added. so '!all', 'other' == '!all'206 self.assertEqual(res, set(['whatever']))207 def test_gather_subset_excludes_min_and_all(self):208 valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])209 minimal_gather_subset = frozenset(['min_fact'])210 res = collector.get_collector_names(valid_subsets=valid_subsets,211 minimal_gather_subset=minimal_gather_subset,212 gather_subset=['whatever', '!all', '!min'])213 self.assertIsInstance(res, set)214 # excludes are higher precedence than includes, so !all excludes everything215 # and then minimal_gather_subset is added. so '!all', 'other' == '!all'216 self.assertEqual(res, set(['whatever']))217 def test_invaid_gather_subset(self):218 valid_subsets = frozenset(['my_fact', 'something_else'])219 minimal_gather_subset = frozenset(['my_fact'])220 self.assertRaisesRegexp(TypeError,221 'Bad subset .* given to Ansible.*allowed\:.*all,.*my_fact.*',222 collector.get_collector_names,223 valid_subsets=valid_subsets,224 minimal_gather_subset=minimal_gather_subset,225 gather_subset=['my_fact', 'not_a_valid_gather_subset'])226class TestCollectorClassesFromGatherSubset(unittest.TestCase):227 def _classes(self,228 all_collector_classes=None,229 valid_subsets=None,230 minimal_gather_subset=None,231 gather_subset=None,232 gather_timeout=None):233 return collector.collector_classes_from_gather_subset(all_collector_classes=all_collector_classes,234 valid_subsets=valid_subsets,235 minimal_gather_subset=minimal_gather_subset,236 gather_subset=gather_subset,237 gather_timeout=gather_timeout)238 def test_no_args(self):239 res = self._classes()240 self.assertIsInstance(res, list)241 self.assertEqual(res, [])242 def test(self):243 res = self._classes(all_collector_classes=default_collectors.collectors,244 gather_subset=['!all'])245 self.assertIsInstance(res, list)246 self.assertEqual(res, [])247 def test_env(self):248 res = self._classes(all_collector_classes=default_collectors.collectors,249 gather_subset=['env'])250 self.assertIsInstance(res, list)251 self.assertEqual(res, [default_collectors.EnvFactCollector])252 def test_facter(self):253 res = self._classes(all_collector_classes=default_collectors.collectors,254 gather_subset=set(['env', 'facter']))255 self.assertIsInstance(res, list)256 self.assertEqual(set(res),257 set([default_collectors.EnvFactCollector,258 default_collectors.FacterFactCollector]))259 def test_facter_ohai(self):260 res = self._classes(all_collector_classes=default_collectors.collectors,261 gather_subset=set(['env', 'facter', 'ohai']))262 self.assertIsInstance(res, list)263 self.assertEqual(set(res),264 set([default_collectors.EnvFactCollector,265 default_collectors.FacterFactCollector,266 default_collectors.OhaiFactCollector]))267 def test_just_facter(self):268 res = self._classes(all_collector_classes=default_collectors.collectors,269 gather_subset=set(['facter']))270 self.assertIsInstance(res, list)271 self.assertEqual(set(res),272 set([default_collectors.FacterFactCollector]))273 def test_collector_specified_multiple_times(self):274 res = self._classes(all_collector_classes=default_collectors.collectors,275 gather_subset=['platform', 'all', 'machine'])276 self.assertIsInstance(res, list)277 self.assertIn(default_collectors.PlatformFactCollector,278 res)279 def test_unknown_collector(self):280 # something claims 'unknown_collector' is a valid gather_subset, but there is281 # no FactCollector mapped to 'unknown_collector'282 self.assertRaisesRegexp(TypeError,283 'Bad subset.*unknown_collector.*given to Ansible.*allowed\:.*all,.*env.*',284 self._classes,285 all_collector_classes=default_collectors.collectors,...
test_collectors.py
Source:test_collectors.py
...38from ansible.module_utils.facts.network.base import NetworkCollector39from ansible.module_utils.facts.hardware.base import HardwareCollector40class CollectorException(Exception):41 pass42class ExceptionThrowingCollector(collector.BaseFactCollector):43 name = 'exc_throwing'44 def __init__(self, collectors=None, namespace=None, exception=None):45 super(ExceptionThrowingCollector, self).__init__(collectors, namespace)46 self._exception = exception or CollectorException('collection failed')47 def collect(self, module=None, collected_facts=None):48 raise self._exception49class TestExceptionThrowingCollector(BaseFactsTest):50 __test__ = True51 gather_subset = ['exc_throwing']52 valid_subsets = ['exc_throwing']53 collector_class = ExceptionThrowingCollector54 def test_collect(self):55 module = self._mock_module()56 fact_collector = self.collector_class()57 self.assertRaises(CollectorException,58 fact_collector.collect,59 module=module,60 collected_facts=self.collected_facts)61 def test_collect_with_namespace(self):62 module = self._mock_module()63 fact_collector = self.collector_class()64 self.assertRaises(CollectorException,65 fact_collector.collect_with_namespace,66 module=module,67 collected_facts=self.collected_facts)68class TestApparmorFacts(BaseFactsTest):69 __test__ = True70 gather_subset = ['!all', 'apparmor']71 valid_subsets = ['apparmor']72 fact_namespace = 'ansible_apparmor'73 collector_class = ApparmorFactCollector74 def test_collect(self):75 facts_dict = super(TestApparmorFacts, self).test_collect()76 self.assertIn('status', facts_dict['apparmor'])77class TestCapsFacts(BaseFactsTest):78 __test__ = True79 gather_subset = ['!all', 'caps']80 valid_subsets = ['caps']81 fact_namespace = 'ansible_system_capabilities'82 collector_class = SystemCapabilitiesFactCollector83 def _mock_module(self):84 mock_module = Mock()85 mock_module.params = {'gather_subset': self.gather_subset,86 'gather_timeout': 10,87 'filter': '*'}88 mock_module.get_bin_path = Mock(return_value='/usr/sbin/capsh')89 mock_module.run_command = Mock(return_value=(0, 'Current: =ep', ''))90 return mock_module91class TestCmdLineFacts(BaseFactsTest):92 __test__ = True93 gather_subset = ['!all', 'cmdline']94 valid_subsets = ['cmdline']95 fact_namespace = 'ansible_cmdline'96 collector_class = CmdLineFactCollector97 def test_parse_proc_cmdline_uefi(self):98 uefi_cmdline = r'initrd=\70ef65e1a04a47aea04f7b5145ea3537\4.10.0-19-generic\initrd root=UUID=50973b75-4a66-4bf0-9764-2b7614489e64 ro quiet'99 expected = {'initrd': r'\70ef65e1a04a47aea04f7b5145ea3537\4.10.0-19-generic\initrd',100 'root': 'UUID=50973b75-4a66-4bf0-9764-2b7614489e64',101 'quiet': True,102 'ro': True}103 fact_collector = self.collector_class()104 facts_dict = fact_collector._parse_proc_cmdline(uefi_cmdline)105 self.assertDictEqual(facts_dict, expected)106 def test_parse_proc_cmdline_fedora(self):107 cmdline_fedora = r'BOOT_IMAGE=/vmlinuz-4.10.16-200.fc25.x86_64 root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root rd.luks.uuid=luks-c80b7537-358b-4a07-b88c-c59ef187479b rd.lvm.lv=fedora/swap rhgb quiet LANG=en_US.UTF-8' # noqa108 expected = {'BOOT_IMAGE': '/vmlinuz-4.10.16-200.fc25.x86_64',109 'LANG': 'en_US.UTF-8',110 'quiet': True,111 'rd.luks.uuid': 'luks-c80b7537-358b-4a07-b88c-c59ef187479b',112 'rd.lvm.lv': 'fedora/swap',113 'rhgb': True,114 'ro': True,115 'root': '/dev/mapper/fedora-root'}116 fact_collector = self.collector_class()117 facts_dict = fact_collector._parse_proc_cmdline(cmdline_fedora)118 self.assertDictEqual(facts_dict, expected)119 def test_parse_proc_cmdline_dup_console(self):120 example = r'BOOT_IMAGE=/boot/vmlinuz-4.4.0-72-generic root=UUID=e12e46d9-06c9-4a64-a7b3-60e24b062d90 ro console=tty1 console=ttyS0'121 # FIXME: Two 'console' keywords? Using a dict for the fact value here loses info. Currently the 'last' one wins122 expected = {'BOOT_IMAGE': '/boot/vmlinuz-4.4.0-72-generic',123 'root': 'UUID=e12e46d9-06c9-4a64-a7b3-60e24b062d90',124 'ro': True,125 'console': 'ttyS0'}126 fact_collector = self.collector_class()127 facts_dict = fact_collector._parse_proc_cmdline(example)128 # TODO: fails because we lose a 'console'129 self.assertDictEqual(facts_dict, expected)130class TestDistributionFacts(BaseFactsTest):131 __test__ = True132 gather_subset = ['!all', 'distribution']133 valid_subsets = ['distribution']134 fact_namespace = 'ansible_distribution'135 collector_class = DistributionFactCollector136class TestDnsFacts(BaseFactsTest):137 __test__ = True138 gather_subset = ['!all', 'dns']139 valid_subsets = ['dns']140 fact_namespace = 'ansible_dns'141 collector_class = DnsFactCollector142class TestEnvFacts(BaseFactsTest):143 __test__ = True144 gather_subset = ['!all', 'env']145 valid_subsets = ['env']146 fact_namespace = 'ansible_env'147 collector_class = EnvFactCollector148 def test_collect(self):149 facts_dict = super(TestEnvFacts, self).test_collect()150 self.assertIn('HOME', facts_dict['env'])151class TestFipsFacts(BaseFactsTest):152 __test__ = True153 gather_subset = ['!all', 'fips']154 valid_subsets = ['fips']155 fact_namespace = 'ansible_fips'156 collector_class = FipsFactCollector157class TestHardwareCollector(BaseFactsTest):158 __test__ = True159 gather_subset = ['!all', 'hardware']160 valid_subsets = ['hardware']161 fact_namespace = 'ansible_hardware'162 collector_class = HardwareCollector163 collected_facts = {'ansible_architecture': 'x86_64'}164class TestNetworkCollector(BaseFactsTest):165 __test__ = True166 gather_subset = ['!all', 'network']167 valid_subsets = ['network']168 fact_namespace = 'ansible_network'169 collector_class = NetworkCollector170class TestPkgMgrFacts(BaseFactsTest):171 __test__ = True172 gather_subset = ['!all', 'pkg_mgr']173 valid_subsets = ['pkg_mgr']174 fact_namespace = 'ansible_pkgmgr'175 collector_class = PkgMgrFactCollector176 def test_collect(self):177 module = self._mock_module()178 fact_collector = self.collector_class()179 facts_dict = fact_collector.collect(module=module, collected_facts=self.collected_facts)180 self.assertIsInstance(facts_dict, dict)181 self.assertIn('pkg_mgr', facts_dict)182class TestOpenBSDPkgMgrFacts(BaseFactsTest):183 __test__ = True184 gather_subset = ['!all', 'pkg_mgr']185 valid_subsets = ['pkg_mgr']186 fact_namespace = 'ansible_pkgmgr'187 collector_class = OpenBSDPkgMgrFactCollector188 def test_collect(self):189 module = self._mock_module()190 fact_collector = self.collector_class()191 facts_dict = fact_collector.collect(module=module, collected_facts=self.collected_facts)192 self.assertIsInstance(facts_dict, dict)193 self.assertIn('pkg_mgr', facts_dict)194 self.assertEqual(facts_dict['pkg_mgr'], 'openbsd_pkg')195class TestPlatformFactCollector(BaseFactsTest):196 __test__ = True197 gather_subset = ['!all', 'platform']198 valid_subsets = ['platform']199 fact_namespace = 'ansible_platform'200 collector_class = PlatformFactCollector201class TestPythonFactCollector(BaseFactsTest):202 __test__ = True203 gather_subset = ['!all', 'python']204 valid_subsets = ['python']205 fact_namespace = 'ansible_python'206 collector_class = PythonFactCollector207class TestSelinuxFacts(BaseFactsTest):208 __test__ = True209 gather_subset = ['!all', 'selinux']210 valid_subsets = ['selinux']211 fact_namespace = 'ansible_selinux'212 collector_class = SelinuxFactCollector213 def test_no_selinux(self):214 with patch('ansible.module_utils.facts.system.selinux.HAVE_SELINUX', False):215 module = self._mock_module()216 fact_collector = self.collector_class()217 facts_dict = fact_collector.collect(module=module)218 self.assertIsInstance(facts_dict, dict)219 self.assertEqual(facts_dict['selinux']['status'], 'Missing selinux Python library')220 return facts_dict221class TestServiceMgrFacts(BaseFactsTest):222 __test__ = True223 gather_subset = ['!all', 'service_mgr']224 valid_subsets = ['service_mgr']225 fact_namespace = 'ansible_service_mgr'226 collector_class = ServiceMgrFactCollector227 # TODO: dedupe some of this test code228 @patch('ansible.module_utils.facts.system.service_mgr.get_file_content', return_value=None)229 def test_no_proc1(self, mock_gfc):230 # no /proc/1/comm, ps returns non-0231 # should fallback to 'service'232 module = self._mock_module()233 module.run_command = Mock(return_value=(1, '', 'wat'))234 fact_collector = self.collector_class()235 facts_dict = fact_collector.collect(module=module)236 self.assertIsInstance(facts_dict, dict)237 self.assertEqual(facts_dict['service_mgr'], 'service')238 @patch('ansible.module_utils.facts.system.service_mgr.get_file_content', return_value=None)239 def test_no_proc1_ps_random_init(self, mock_gfc):240 # no /proc/1/comm, ps returns '/sbin/sys11' which we dont know241 # should end up return 'sys11'242 module = self._mock_module()243 module.run_command = Mock(return_value=(0, '/sbin/sys11', ''))244 fact_collector = self.collector_class()245 facts_dict = fact_collector.collect(module=module)246 self.assertIsInstance(facts_dict, dict)247 self.assertEqual(facts_dict['service_mgr'], 'sys11')248 @patch('ansible.module_utils.facts.system.service_mgr.get_file_content', return_value=None)249 def test_clowncar(self, mock_gfc):250 # no /proc/1/comm, ps fails, distro and system are clowncar251 # should end up return 'sys11'252 module = self._mock_module()253 module.run_command = Mock(return_value=(1, '', ''))254 collected_facts = {'distribution': 'clowncar',255 'system': 'ClownCarOS'}256 fact_collector = self.collector_class()257 facts_dict = fact_collector.collect(module=module,258 collected_facts=collected_facts)259 self.assertIsInstance(facts_dict, dict)260 self.assertEqual(facts_dict['service_mgr'], 'service')261 # TODO: reenable these tests when we can mock more easily262# @patch('ansible.module_utils.facts.system.service_mgr.get_file_content', return_value=None)263# def test_sunos_fallback(self, mock_gfc):264# # no /proc/1/comm, ps fails, 'system' is SunOS265# # should end up return 'smf'?266# module = self._mock_module()267# # FIXME: the result here is a kluge to at least cover more of service_mgr.collect268# # TODO: remove269# # FIXME: have to force a pid for results here to get into any of the system/distro checks270# module.run_command = Mock(return_value=(1, ' 37 ', ''))271# collected_facts = {'system': 'SunOS'}272# fact_collector = self.collector_class(module=module)273# facts_dict = fact_collector.collect(collected_facts=collected_facts)274# print('facts_dict: %s' % facts_dict)275# self.assertIsInstance(facts_dict, dict)276# self.assertEqual(facts_dict['service_mgr'], 'smf')277# @patch('ansible.module_utils.facts.system.service_mgr.get_file_content', return_value=None)278# def test_aix_fallback(self, mock_gfc):279# # no /proc/1/comm, ps fails, 'system' is SunOS280# # should end up return 'smf'?281# module = self._mock_module()282# module.run_command = Mock(return_value=(1, '', ''))283# collected_facts = {'system': 'AIX'}284# fact_collector = self.collector_class(module=module)285# facts_dict = fact_collector.collect(collected_facts=collected_facts)286# print('facts_dict: %s' % facts_dict)287# self.assertIsInstance(facts_dict, dict)288# self.assertEqual(facts_dict['service_mgr'], 'src')289# @patch('ansible.module_utils.facts.system.service_mgr.get_file_content', return_value=None)290# def test_linux_fallback(self, mock_gfc):291# # no /proc/1/comm, ps fails, 'system' is SunOS292# # should end up return 'smf'?293# module = self._mock_module()294# module.run_command = Mock(return_value=(1, ' 37 ', ''))295# collected_facts = {'system': 'Linux'}296# fact_collector = self.collector_class(module=module)297# facts_dict = fact_collector.collect(collected_facts=collected_facts)298# print('facts_dict: %s' % facts_dict)299# self.assertIsInstance(facts_dict, dict)300# self.assertEqual(facts_dict['service_mgr'], 'sdfadf')301class TestSshPubKeyFactCollector(BaseFactsTest):302 __test__ = True303 gather_subset = ['!all', 'ssh_pub_keys']304 valid_subsets = ['ssh_pub_keys']305 fact_namespace = 'ansible_ssh_pub_leys'306 collector_class = SshPubKeyFactCollector307class TestUserFactCollector(BaseFactsTest):308 __test__ = True309 gather_subset = ['!all', 'user']310 valid_subsets = ['user']311 fact_namespace = 'ansible_user'312 collector_class = UserFactCollector313class TestVirtualFacts(BaseFactsTest):314 __test__ = True315 gather_subset = ['!all', 'virtual']316 valid_subsets = ['virtual']317 fact_namespace = 'ansible_virtual'...
test_ansible_collector.py
Source:test_ansible_collector.py
...92 collector_obj = collector_class()93 collectors.append(collector_obj)94 # Add a collector that knows what gather_subset we used so it it can provide a fact95 collector_meta_data_collector = \96 ansible_collector.CollectorMetaDataCollector(gather_subset=gather_subset,97 module_setup=True)98 collectors.append(collector_meta_data_collector)99 return collectors100ns = namespace.PrefixFactNamespace('ansible_facts', 'ansible_')101# FIXME: this is brute force, but hopefully enough to get some refactoring to make facts testable102class TestInPlace(unittest.TestCase):103 def _mock_module(self, gather_subset=None):104 return mock_module(gather_subset=gather_subset)105 def _collectors(self, module,106 all_collector_classes=None,107 minimal_gather_subset=None):108 return _collectors(module=module,109 all_collector_classes=all_collector_classes,110 minimal_gather_subset=minimal_gather_subset)111 def test(self):112 gather_subset = ['all']113 mock_module = self._mock_module(gather_subset=gather_subset)114 all_collector_classes = [EnvFactCollector]115 collectors = self._collectors(mock_module,116 all_collector_classes=all_collector_classes)117 fact_collector = \118 ansible_collector.AnsibleFactCollector(collectors=collectors,119 namespace=ns)120 res = fact_collector.collect(module=mock_module)121 self.assertIsInstance(res, dict)122 self.assertIn('env', res)123 self.assertIn('gather_subset', res)124 self.assertEqual(res['gather_subset'], ['all'])125 def test1(self):126 gather_subset = ['all']127 mock_module = self._mock_module(gather_subset=gather_subset)128 collectors = self._collectors(mock_module)129 fact_collector = \130 ansible_collector.AnsibleFactCollector(collectors=collectors,131 namespace=ns)132 res = fact_collector.collect(module=mock_module)133 self.assertIsInstance(res, dict)134 # just assert it's not almost empty135 # with run_command and get_file_content mock, many facts are empty, like network136 self.assertGreater(len(res), 20)137 def test_empty_all_collector_classes(self):138 mock_module = self._mock_module()139 all_collector_classes = []140 collectors = self._collectors(mock_module,141 all_collector_classes=all_collector_classes)142 fact_collector = \143 ansible_collector.AnsibleFactCollector(collectors=collectors,144 namespace=ns)145 res = fact_collector.collect()146 self.assertIsInstance(res, dict)147 # just assert it's not almost empty148 self.assertLess(len(res), 3)149# def test_facts_class(self):150# mock_module = self._mock_module()151# Facts(mock_module)152# def test_facts_class_load_on_init_false(self):153# mock_module = self._mock_module()154# Facts(mock_module, load_on_init=False)155# # FIXME: assert something156class TestCollectedFacts(unittest.TestCase):157 gather_subset = ['all', '!facter', '!ohai']158 min_fact_count = 30159 max_fact_count = 1000160 # TODO: add ansible_cmdline, ansible_*_pubkey* back when TempFactCollector goes away161 expected_facts = ['date_time',162 'user_id', 'distribution',163 'gather_subset', 'module_setup',164 'env']165 not_expected_facts = ['facter', 'ohai']166 def _mock_module(self, gather_subset=None):167 return mock_module(gather_subset=self.gather_subset)168 def setUp(self):169 mock_module = self._mock_module()170 collectors = self._collectors(mock_module)171 fact_collector = \172 ansible_collector.AnsibleFactCollector(collectors=collectors,173 namespace=ns)174 self.facts = fact_collector.collect(module=mock_module)175 def _collectors(self, module,176 all_collector_classes=None,177 minimal_gather_subset=None):178 return _collectors(module=module,179 all_collector_classes=all_collector_classes,180 minimal_gather_subset=minimal_gather_subset)181 def test_basics(self):182 self._assert_basics(self.facts)183 def test_expected_facts(self):184 self._assert_expected_facts(self.facts)185 def test_not_expected_facts(self):186 self._assert_not_expected_facts(self.facts)187 def _assert_basics(self, facts):188 self.assertIsInstance(facts, dict)189 # just assert it's not almost empty190 self.assertGreaterEqual(len(facts), self.min_fact_count)191 # and that is not huge number of keys192 self.assertLess(len(facts), self.max_fact_count)193 # everything starts with ansible_ namespace194 def _assert_ansible_namespace(self, facts):195 # FIXME: kluge for non-namespace fact196 facts.pop('module_setup', None)197 facts.pop('gather_subset', None)198 for fact_key in facts:199 self.assertTrue(fact_key.startswith('ansible_'),200 'The fact name "%s" does not startwith "ansible_"' % fact_key)201 def _assert_expected_facts(self, facts):202 facts_keys = sorted(facts.keys())203 for expected_fact in self.expected_facts:204 self.assertIn(expected_fact, facts_keys)205 def _assert_not_expected_facts(self, facts):206 facts_keys = sorted(facts.keys())207 for not_expected_fact in self.not_expected_facts:208 self.assertNotIn(not_expected_fact, facts_keys)209class ExceptionThrowingCollector(collector.BaseFactCollector):210 def collect(self, module=None, collected_facts=None):211 raise Exception('A collector failed')212class TestExceptionCollectedFacts(TestCollectedFacts):213 def _collectors(self, module,214 all_collector_classes=None,215 minimal_gather_subset=None):216 collectors = _collectors(module=module,217 all_collector_classes=all_collector_classes,218 minimal_gather_subset=minimal_gather_subset)219 c = [ExceptionThrowingCollector()] + collectors220 return c221class TestOnlyExceptionCollector(TestCollectedFacts):222 expected_facts = []223 min_fact_count = 0224 def _collectors(self, module,225 all_collector_classes=None,226 minimal_gather_subset=None):227 return [ExceptionThrowingCollector()]228class TestMinimalCollectedFacts(TestCollectedFacts):229 gather_subset = ['!all']230 min_fact_count = 1231 max_fact_count = 10232 expected_facts = ['gather_subset',233 'module_setup']234 not_expected_facts = ['lsb']235class TestFacterCollectedFacts(TestCollectedFacts):236 gather_subset = ['!all', 'facter']237 min_fact_count = 1238 max_fact_count = 10239 expected_facts = ['gather_subset',240 'module_setup']241 not_expected_facts = ['lsb']242class TestOhaiCollectedFacts(TestCollectedFacts):243 gather_subset = ['!all', 'ohai']244 min_fact_count = 1245 max_fact_count = 10246 expected_facts = ['gather_subset',247 'module_setup']248 not_expected_facts = ['lsb']249class TestPkgMgrFacts(TestCollectedFacts):250 gather_subset = ['pkg_mgr']251 min_fact_count = 1252 max_fact_count = 10253 expected_facts = ['gather_subset',254 'module_setup',255 'pkg_mgr']256class TestOpenBSDPkgMgrFacts(TestPkgMgrFacts):257 def test_is_openbsd_pkg(self):258 self.assertIn('pkg_mgr', self.facts)259 self.assertEqual(self.facts['pkg_mgr'], 'openbsd_pkg')260 def setUp(self):261 self.patcher = patch('platform.system')262 mock_platform = self.patcher.start()263 mock_platform.return_value = 'OpenBSD'264 mock_module = self._mock_module()265 collectors = self._collectors(mock_module)266 fact_collector = \267 ansible_collector.AnsibleFactCollector(collectors=collectors,268 namespace=ns)269 self.facts = fact_collector.collect(module=mock_module)270 def tearDown(self):...
collector.py
Source:collector.py
...25class StateChangeObserver(Base):26 @abstractmethod27 def __call__(self, _collector : 'Collector', _prev_state : 'Collector.State', _new_state : 'Collector.State') -> None:28 pass29class Collector(Serializable):30 """Base class for all data collection types.31 When adding new collector - inherit from this class and implement below32 abstract methods:33 _collect_impl - this is the heart of the collector (what it does i.e. collect)34 get_type - type can be CONTINUOUS or SNAPSHOT35 get_required_resources - what resources this collector needs.36 _get_json - collector specific serialization.37 """38 MAX_TIME = float(30 * 24 * 60 * 60)39 MAX_CNT = int(1e9)40 class Type(Enum):41 SNAPSHOT = 042 CONTINUOUS = 143 class State(Enum):...
default_collectors.py
Source:default_collectors.py
1#2# This file is part of Ansible3#4# Ansible is free software: you can redistribute it and/or modify5# it under the terms of the GNU General Public License as published by6# the Free Software Foundation, either version 3 of the License, or7# (at your option) any later version.8#9# Ansible is distributed in the hope that it will be useful,10# but WITHOUT ANY WARRANTY; without even the implied warranty of11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12# GNU General Public License for more details.13#14# You should have received a copy of the GNU General Public License15# along with Ansible. If not, see <http://www.gnu.org/licenses/>.16from __future__ import (absolute_import, division, print_function)17__metaclass__ = type18from ansible.module_utils.facts.other.facter import FacterFactCollector19from ansible.module_utils.facts.other.ohai import OhaiFactCollector20from ansible.module_utils.facts.system.apparmor import ApparmorFactCollector21from ansible.module_utils.facts.system.caps import SystemCapabilitiesFactCollector22from ansible.module_utils.facts.system.cmdline import CmdLineFactCollector23from ansible.module_utils.facts.system.distribution import DistributionFactCollector24from ansible.module_utils.facts.system.date_time import DateTimeFactCollector25from ansible.module_utils.facts.system.env import EnvFactCollector26from ansible.module_utils.facts.system.dns import DnsFactCollector27from ansible.module_utils.facts.system.fips import FipsFactCollector28from ansible.module_utils.facts.system.local import LocalFactCollector29from ansible.module_utils.facts.system.lsb import LSBFactCollector30from ansible.module_utils.facts.system.pkg_mgr import PkgMgrFactCollector31from ansible.module_utils.facts.system.pkg_mgr import OpenBSDPkgMgrFactCollector32from ansible.module_utils.facts.system.platform import PlatformFactCollector33from ansible.module_utils.facts.system.python import PythonFactCollector34from ansible.module_utils.facts.system.selinux import SelinuxFactCollector35from ansible.module_utils.facts.system.service_mgr import ServiceMgrFactCollector36from ansible.module_utils.facts.system.ssh_pub_keys import SshPubKeyFactCollector37from ansible.module_utils.facts.system.user import UserFactCollector38from ansible.module_utils.facts.hardware.base import HardwareCollector39from ansible.module_utils.facts.hardware.aix import AIXHardwareCollector40from ansible.module_utils.facts.hardware.darwin import DarwinHardwareCollector41from ansible.module_utils.facts.hardware.dragonfly import DragonFlyHardwareCollector42from ansible.module_utils.facts.hardware.freebsd import FreeBSDHardwareCollector43from ansible.module_utils.facts.hardware.hpux import HPUXHardwareCollector44from ansible.module_utils.facts.hardware.hurd import HurdHardwareCollector45from ansible.module_utils.facts.hardware.linux import LinuxHardwareCollector46from ansible.module_utils.facts.hardware.netbsd import NetBSDHardwareCollector47from ansible.module_utils.facts.hardware.openbsd import OpenBSDHardwareCollector48from ansible.module_utils.facts.hardware.sunos import SunOSHardwareCollector49from ansible.module_utils.facts.network.base import NetworkCollector50from ansible.module_utils.facts.network.aix import AIXNetworkCollector51from ansible.module_utils.facts.network.darwin import DarwinNetworkCollector52from ansible.module_utils.facts.network.dragonfly import DragonFlyNetworkCollector53from ansible.module_utils.facts.network.freebsd import FreeBSDNetworkCollector54from ansible.module_utils.facts.network.hpux import HPUXNetworkCollector55from ansible.module_utils.facts.network.hurd import HurdNetworkCollector56from ansible.module_utils.facts.network.linux import LinuxNetworkCollector57from ansible.module_utils.facts.network.netbsd import NetBSDNetworkCollector58from ansible.module_utils.facts.network.openbsd import OpenBSDNetworkCollector59from ansible.module_utils.facts.network.sunos import SunOSNetworkCollector60from ansible.module_utils.facts.virtual.base import VirtualCollector61from ansible.module_utils.facts.virtual.dragonfly import DragonFlyVirtualCollector62from ansible.module_utils.facts.virtual.freebsd import FreeBSDVirtualCollector63from ansible.module_utils.facts.virtual.hpux import HPUXVirtualCollector64from ansible.module_utils.facts.virtual.linux import LinuxVirtualCollector65from ansible.module_utils.facts.virtual.netbsd import NetBSDVirtualCollector66from ansible.module_utils.facts.virtual.openbsd import OpenBSDVirtualCollector67from ansible.module_utils.facts.virtual.sunos import SunOSVirtualCollector68# these should always be first due to most other facts depending on them69_base = [70 PlatformFactCollector,71 DistributionFactCollector,72 LSBFactCollector73]74# These restrict what is possible in others75_restrictive = [76 SelinuxFactCollector,77 ApparmorFactCollector,78 FipsFactCollector79]80# general info, not required but probably useful for other facts81_general = [82 PythonFactCollector,83 SystemCapabilitiesFactCollector,84 PkgMgrFactCollector,85 OpenBSDPkgMgrFactCollector,86 ServiceMgrFactCollector,87 CmdLineFactCollector,88 DateTimeFactCollector,89 EnvFactCollector,90 SshPubKeyFactCollector,91 UserFactCollector92]93# virtual, this might also limit hardware/networking94_virtual = [95 VirtualCollector,96 DragonFlyVirtualCollector,97 FreeBSDVirtualCollector,98 LinuxVirtualCollector,99 OpenBSDVirtualCollector,100 NetBSDVirtualCollector,101 SunOSVirtualCollector,102 HPUXVirtualCollector103]104_hardware = [105 HardwareCollector,106 AIXHardwareCollector,107 DarwinHardwareCollector,108 DragonFlyHardwareCollector,109 FreeBSDHardwareCollector,110 HPUXHardwareCollector,111 HurdHardwareCollector,112 LinuxHardwareCollector,113 NetBSDHardwareCollector,114 OpenBSDHardwareCollector,115 SunOSHardwareCollector116]117_network = [118 DnsFactCollector,119 NetworkCollector,120 AIXNetworkCollector,121 DarwinNetworkCollector,122 DragonFlyNetworkCollector,123 FreeBSDNetworkCollector,124 HPUXNetworkCollector,125 HurdNetworkCollector,126 LinuxNetworkCollector,127 NetBSDNetworkCollector,128 OpenBSDNetworkCollector,129 SunOSNetworkCollector130]131# other fact sources132_extra_facts = [133 LocalFactCollector,134 FacterFactCollector,135 OhaiFactCollector136]137# TODO: make config driven...
trigger.py
Source:trigger.py
1# pylint: disable=missing-function-docstring,missing-class-docstring,abstract-method2# python imports3from __future__ import absolute_import4from typing import List, Callable, Optional5# local imports6import logger_manager as log7from rapid_diag.collector.collector import Collector, CollectorList8from rapid_diag.collector.collector import CollectorStateObserver9from rapid_diag.collector.resource import Resource10_LOGGER = log.setup_logging("trigger")11class TriggerStateChangeObserver(CollectorStateObserver):12 def __init__(self, collector : Collector, obs : CollectorStateObserver):13 CollectorStateObserver.__init__(self)14 self.collector : Collector = collector15 self.obs : List[CollectorStateObserver] = obs16 self.is_timedout : bool = False17 def __call__(self, collector : Collector, prev_state : Collector.State, new_state : Collector.State) -> None:18 if new_state == Collector.State.TIMEOUT:19 if isinstance(collector, Trigger):20 _LOGGER.debug("timeout called %s", str(id(self.collector)))21 self.is_timedout = True22 def get_timeout_status(self) -> bool:23 return self.is_timedout24 def save(self, run_info_path : Optional[str] = None) -> None:25 pass26class Trigger(Collector):27 def __init__(self, collectors : Optional[List[Collector]]):28 Collector.__init__(self)29 self.conflicts : bool = False30 self.collectors : CollectorList = CollectorList([] if collectors is None else collectors)31 def add(self, collector : Collector) -> None:32 self.collectors.append(collector)33 def remove(self, collector : Collector) -> bool:34 try:35 index = self.collectors.index(collector)36 self.collectors = CollectorList(self.collectors[:index] + self.collectors[index+1:])37 except ValueError:38 return False39 return True40 def apply_to_self(self, functor : Callable, depth : int = 0) -> None:41 Collector.apply_to_self(self, functor, depth)42 for collector in self.collectors:43 collector.apply_to_self(functor, depth + 1)44 def get_required_resources(self) -> List[Resource]:45 resources = []46 for collector in self.collectors:47 resources.extend(collector.get_required_resources())48 return resources49 def _filter_collectors_helper(self, conflicting_resources : List[Resource]) -> None:50 for i in reversed(range(len(self.collectors))):51 collector = self.collectors[i]52 if isinstance(collector, Trigger):53 collector._filter_collectors_helper(conflicting_resources) # pylint: disable=protected-access54 elif set(collector.get_required_resources()).intersection(conflicting_resources):55 self.conflicts = True56 del self.collectors[i]57 def filter_collectors(self, run_context : Collector.RunContext) -> None:58 conflicting_resources : List[Resource] = \59 run_context.task_handler.get_conflicting_resources(run_context.server_name, self.collectors) # type: ignore60 if len(conflicting_resources) > 0:61 _LOGGER.debug("Resources conflicting with the trigger are %s",62 " ".join(([str(cr) for cr in conflicting_resources])))...
getCollectorWidgetTranslation.py
Source:getCollectorWidgetTranslation.py
1##parameters=widget=None2# $Id$3"""returns the translation corresponding to a field type (for translation)"""4widget2msgid = {5 'submit': 'collector_field_button',6 'checkbox': 'collector_field_checkbox',7 'comment': 'collector_field_comment',8 'date': 'collector_field_date',9 'email': 'collector_field_email',10 'file': 'collector_field_file',11 'float': 'collector_field_float',12 'hidden': 'collector_field_hiddenstring',13 'identifier': 'collector_field_identifier',14 'int': 'collector_field_integer',15 'password': 'collector_field_password',16 'phone': 'collector_field_phonenumber',17 'radio': 'collector_field_radiobutton',18 'reset': 'collector_field_resetbutton',19 'selection': 'collector_field_selection',20 'separator': 'collector_field_separator',21 'string': 'collector_field_string',22 'string_ro': 'collector_field_string_ro',23 'text': 'collector_field_textarea',24 'title': 'collector_field_title',25 'url': 'collector_field_url',26 'vradio': 'collector_field_vradiobutton',27 }28def mcat(s):29 return context.translation_service.translateDefault(s)30if widget and widget2msgid.has_key(widget):31 return mcat(widget2msgid.get(widget))32else:...
Using AI Code Generation
1var collector = new istanbul.Collector();2collector.add(global.__coverage__);3var reporter = new istanbul.Reporter();4reporter.add('lcov');5reporter.write(collector, true, function() {6 console.log('All reports generated');7});
Using AI Code Generation
1var istanbul = require('istanbul');2var collector = new istanbul.Collector();3var istanbul = require('istanbul');4var report = istanbul.Report.create('html');5var report = istanbul.Report.create('json');6var report = istanbul.Report.create('text');7var report = istanbul.Report.create('text-summary');8var istanbul = require('istanbul');9var store = istanbul.Store.create('fs');10var istanbul = require('istanbul');11var utils = istanbul.utils;12utils.addDerivedInfoForFile(coverage, fileCoverage);13var istanbul = require('istanbul');14var libReport = istanbul.libReport;15libReport.create('html');16var istanbul = require('istanbul');17var libHook = istanbul.libHook;18libHook.hookRequire();19var istanbul = require('istanbul');20var libCoverage = istanbul.libCoverage;21libCoverage.createCoverageMap();22var istanbul = require('istanbul');23var libInstrument = istanbul.libInstrument;24libInstrument.createInstrumenter();25var istanbul = require('istanbul');26var instrumenter = new istanbul.Instrumenter();27var istanbul = require('istanbul');28var hook = new istanbul.Hook();29var istanbul = require('istanbul');30var coverage = new istanbul.Coverage();31var istanbul = require('istanbul');32var collector = new istanbul.Collector();33var istanbul = require('istanbul');34var report = istanbul.Report.create('html');35var report = istanbul.Report.create('json');36var report = istanbul.Report.create('text');
Using AI Code Generation
1var istanbul = require('istanbul');2var collector = new istanbul.Collector();3collector.add(__coverage__);4var istanbul = require('istanbul');5var collector = new istanbul.Collector();6collector.add(__coverage__);7var reporter = new istanbul.Reporter();8reporter.addAll(['html', 'lcovonly']);9reporter.write(collector, true, function () {10 console.log('All reports generated');11});12var istanbul = require('istanbul');13var hook = istanbul.hook;14hook.hookRequire();15hook.hookRunInThisContext();16hook.hookRunInContext();17var istanbul = require('istanbul');18var instrumenter = new istanbul.Instrumenter();19instrumenter.instrument('var foo = 1;', 'path/to/file.js', function (err, code) {20});21var istanbul = require('istanbul');22var store = new istanbul.Store();23store.set('key', 'value');24store.map(function (key, value) {25 return value + 'bar';26var istanbul = require('istanbul');
Using AI Code Generation
1var Collector = require('istanbul').Collector;2var collector = new Collector();3var istanbul = require('istanbul');4var Report = istanbul.Report;5var report = Report.create('html', {6});7var coverage = require('./coverage/coverage.json');8collector.add(coverage);9report.writeReport(collector, true);10var coverage = require('./coverage/coverage.json');11collector.add(coverage);12report.writeReport(collector, true);
Using AI Code Generation
1var istanbul = require('istanbul');2var collector = new istanbul.Collector();3var hook = require('istanbul').hook;4var report = require('istanbul').Report;5var fs = require('fs');6var path = require('path');7var Mocha = require('mocha');8var chai = require('chai');9var chaiHttp = require('chai-http');10var server = require('../server');11var expect = chai.expect;12var assert = chai.assert;13var should = chai.should();14var describe = Mocha.describe;15var it = Mocha.it;16var before = Mocha.before;17var beforeEach = Mocha.beforeEach;18var after = Mocha.after;19var afterEach = Mocha.afterEach;20var app = require('../app');21var user = require('../routes/user');22var note = require('../routes/note');23var label = require('../routes/label');24var userController = require('../controller/userController');25var noteController = require('../controller/noteController');26var labelController = require('../controller/labelController');
Using AI Code Generation
1var collector = new istanbul.Collector();2collector.add(coverage);3collector.add(global.__coverage__);4var report = istanbul.Report.create('html', {5});6report.writeReport(collector, true);
Using AI Code Generation
1var istanbul = require('istanbul');2var collector = new istanbul.Collector();3var reporter = new istanbul.Reporter();4collector.add(coverage);5reporter.add('lcov');6reporter.write(collector, true, function() {7 console.log('All reports generated');8});
Using AI Code Generation
1var Collector = require('istanbul').Collector,2 Report = require('istanbul').Report,3 collector = new Collector();4collector.add(JSON.parse(fs.readFileSync('coverage.json', 'utf8')));5var report = Report.create('text');6report.on('done', function () {7});8report.writeReport(collector, true);
Using AI Code Generation
1require('istanbul').Collector.add(__coverage__);2require('fs').writeFileSync(3 JSON.stringify(__coverage__),4);5module.exports = function(config) {6 config.set({7 preprocessors: {8 },9 coverageReporter: {10 }11 });12};13module.exports = function(grunt) {14 grunt.initConfig({15 mochaTest: {16 test: {17 options: {18 },19 }20 }21 });22 grunt.loadNpmTasks('grunt-mocha-test');23 grunt.registerTask('test', ['mochaTest']);24};25var gulp = require('gulp');26var mocha = require('gulp-mocha');27var istanbul = require('gulp-istanbul');28gulp.task('pre-test', function() {29 return gulp.src(['lib/**/*.js'])30 .pipe(istanbul())31 .pipe(istanbul.hookRequire());32});33gulp.task('test', ['pre-test'], function() {34 return gulp.src(['test
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!