
    VhS                     X   d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dl
mZ d dlmZ d d	lmZ  G d
 de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z eeeeee      Z eej7                               Z e       Zd Ze dk(  r e        yy)    )absolute_importdivisionprint_functiona^  
module: facts
author: "Egor Zaitsev (@heuels)"
short_description: Collect facts from remote devices running MikroTik RouterOS
description:
  - Collects a base set of device facts from a remote device that is running RouterOS. This module prepends all of the base
    network fact keys with C(ansible_net_<fact>). The facts module will always collect a base set of facts from the device
    and can enable or disable collection of additional facts.
extends_documentation_fragment:
  - community.routeros.attributes
  - community.routeros.attributes.facts
  - community.routeros.attributes.facts_module
  - community.routeros.attributes.idempotent_not_modify_state
attributes:
  platform:
    support: full
    platforms: RouterOS
options:
  gather_subset:
    description:
      - When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument
        include V(all), V(hardware), V(config), V(interfaces), and V(routing).
      - Can specify a list of values to include a larger subset. Values can also be used with an initial V(!) to specify that
        a specific subset should not be collected.
    required: false
    default:
      - '!config'
    type: list
    elements: str
seealso:
  - ref: ansible_collections.community.routeros.docsite.ssh-guide
    description: How to connect to RouterOS devices with SSH.
a=  
---
- name: Collect all facts from the device
  community.routeros.facts:
    gather_subset: all

- name: Collect only the config and default facts
  community.routeros.facts:
    gather_subset:
      - config

- name: Do not collect hardware facts
  community.routeros.facts:
    gather_subset:
      - "!hardware"
a  
ansible_facts:
  description: "Dictionary of IP geolocation facts for a host's IP address."
  returned: always
  type: dict
  contains:
    ansible_net_gather_subset:
      description: The list of fact subsets collected from the device.
      returned: always
      type: list

    # default
    ansible_net_model:
      description: The model name returned from the device.
      returned: O(gather_subset) contains V(default)
      type: str
    ansible_net_serialnum:
      description: The serial number of the remote device.
      returned: O(gather_subset) contains V(default)
      type: str
    ansible_net_version:
      description: The operating system version running on the remote device.
      returned: O(gather_subset) contains V(default)
      type: str
    ansible_net_hostname:
      description: The configured hostname of the device.
      returned: O(gather_subset) contains V(default)
      type: str
    ansible_net_arch:
      description: The CPU architecture of the device.
      returned: O(gather_subset) contains V(default)
      type: str
    ansible_net_uptime:
      description: The uptime of the device.
      returned: O(gather_subset) contains V(default)
      type: str
    ansible_net_cpu_load:
      description: Current CPU load.
      returned: O(gather_subset) contains V(default)
      type: str

    # hardware
    ansible_net_spacefree_mb:
      description: The available disk space on the remote device in MiB.
      returned: O(gather_subset) contains V(hardware)
      type: dict
    ansible_net_spacetotal_mb:
      description: The total disk space on the remote device in MiB.
      returned: O(gather_subset) contains V(hardware)
      type: dict
    ansible_net_memfree_mb:
      description: The available free memory on the remote device in MiB.
      returned: O(gather_subset) contains V(hardware)
      type: int
    ansible_net_memtotal_mb:
      description: The total memory on the remote device in MiB.
      returned: O(gather_subset) contains V(hardware)
      type: int

    # config
    ansible_net_config:
      description: The current active config from the device.
      returned: O(gather_subset) contains V(config)
      type: str

    ansible_net_config_nonverbose:
      description:
        - The current active config from the device in minimal form.
        - This value is idempotent in the sense that if the facts module is run twice and the device's config was not changed
          between the runs, the value is identical. This is achieved by running C(/export) and stripping the timestamp from
          the comment in the first line.
      returned: O(gather_subset) contains V(config)
      type: str
      version_added: 1.2.0

    # interfaces
    ansible_net_all_ipv4_addresses:
      description: All IPv4 addresses configured on the device.
      returned: O(gather_subset) contains V(interfaces)
      type: list
    ansible_net_all_ipv6_addresses:
      description: All IPv6 addresses configured on the device.
      returned: O(gather_subset) contains V(interfaces)
      type: list
    ansible_net_interfaces:
      description: A hash of all interfaces running on the system.
      returned: O(gather_subset) contains V(interfaces)
      type: dict
    ansible_net_neighbors:
      description: The list of neighbors from the remote device.
      returned: O(gather_subset) contains V(interfaces)
      type: dict

    # routing
    ansible_net_bgp_peer:
      description: A dictionary with BGP peer information.
      returned: O(gather_subset) contains V(routing)
      type: dict
    ansible_net_bgp_vpnv4_route:
      description: A dictionary with BGP vpnv4 route information.
      returned: O(gather_subset) contains V(routing)
      type: dict
    ansible_net_bgp_instance:
      description: A dictionary with BGP instance information.
      returned: O(gather_subset) contains V(routing)
      type: dict
    ansible_net_route:
      description: A dictionary for routes in all routing tables.
      returned: O(gather_subset) contains V(routing)
      type: dict
    ansible_net_ospf_instance:
      description: A dictionary with OSPF instances.
      returned: O(gather_subset) contains V(routing)
      type: dict
    ansible_net_ospf_neighbor:
      description: A dictionary with OSPF neighbors.
      returned: O(gather_subset) contains V(routing)
      type: dict
N)run_commands)routeros_argument_spec)AnsibleModule)	iteritemsc                   ,    e Zd Z e       Zd Zd Zd Zy)	FactsBasec                 >    || _         t               | _        d | _        y N)moduledictfacts	responses)selfr   s     l/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/routeros/plugins/modules/facts.py__init__zFactsBase.__init__   s    V
    c                 R    t        | j                  | j                  d      | _        y NF)commandscheck_rc)r   r   COMMANDSr   )r   s    r   populatezFactsBase.populate   s    %dkkDMMTYZr   c                 2    t        | j                  |d      S r   )r   r   )r   cmds     r   runzFactsBase.run   s    DKK#FFr   N)__name__
__module____qualname__listr   r   r   r    r   r   r   r      s    vH
[Gr   r   c                   P     e Zd Zg dZ fdZd Zd Zd Zd Zd Z	d Z
d	 Z xZS )
Default)z%/system identity print without-paging%/system resource print without-pagingz(/system routerboard print without-pagingc                 6   t         t        |           | j                  d   }|r| j	                  |      | j
                  d<   | j                  d   }|rx| j                  |      | j
                  d<   | j                  |      | j
                  d<   | j                  |      | j
                  d<   | j                  |      | j
                  d<   | j                  d   }|r=| j                  |      | j
                  d	<   | j                  |      | j
                  d
<   y y )Nr   hostname   versionarchuptimecpu_load   model	serialnum)superr%   r   r   parse_hostnamer   parse_version
parse_archparse_uptimeparse_cpu_loadparse_modelparse_serialnumr   data	__class__s     r   r   zDefault.populate   s    gt%'~~a %)%8%8%>DJJz"~~a $($6$6t$<DJJy!!%!6DJJv#'#4#4T#:DJJx %)%8%8%>DJJz"~~a "&"2"24"8DJJw&*&:&:4&@DJJ{# r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzname:\s(.*)\s*$r)   researchMgroupr   r:   matchs      r   r2   zDefault.parse_hostname   s/    		,dBDD9;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzversion:\s(.*)\s*$r)   r=   rB   s      r   r3   zDefault.parse_version   s/    		/rtt<;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzmodel:\s(.*)\s*$r)   r=   rB   s      r   r7   zDefault.parse_model   s/    		-tRTT:;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzarchitecture-name:\s(.*)\s*$r)   r=   rB   s      r   r4   zDefault.parse_arch   s/    		94F;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzuptime:\s(.*)\s*$r)   r=   rB   s      r   r5   zDefault.parse_uptime   s/    		.bdd;;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzcpu-load:\s(.*)\s*$r)   r=   rB   s      r   r6   zDefault.parse_cpu_load   s/    		0$=;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzserial-number:\s(.*)\s*$r)   r=   rB   s      r   r8   zDefault.parse_serialnum  s/    		5tRTTB;;q>! r   )r   r    r!   r   r   r2   r3   r7   r4   r5   r6   r8   __classcell__r;   s   @r   r%   r%      s3    HA "
"
"
"
"
"
"r   r%   c                   6     e Zd ZdgZ fdZd Zd Zd Z xZS )Hardwarer&   c                     t         t        |           | j                  d   }|r#| j	                  |       | j                  |       y y )Nr   )r1   rM   r   r   parse_filesystem_infoparse_memory_infor9   s     r   r   zHardware.populate  sB    h&(~~a &&t,""4( r   c                    t        j                  d|t         j                        }|r| j                  |      | j                  d<   t        j                  d|t         j                        }|r| j                  |      | j                  d<   y y )Nzfree-hdd-space:\s(.*)([KMG]iB)spacefree_mbztotal-hdd-space:\s(.*)([KMG]iB)spacetotal_mbr>   r?   r@   to_megabytesr   rB   s      r   rO   zHardware.parse_filesystem_info  sm    		;T244H)-):):5)ADJJ~&		<dBDDI*.*;*;E*BDJJ' r   c                    t        j                  d|t         j                        }|r| j                  |      | j                  d<   t        j                  d|t         j                        }|r| j                  |      | j                  d<   y y )Nz"free-memory:\s(\d+\.?\d*)([KMG]iB)
memfree_mbz#total-memory:\s(\d+\.?\d*)([KMG]iB)memtotal_mbrT   rB   s      r   rP   zHardware.parse_memory_info  sm    		?rttL'+'8'8'?DJJ|$		@$M(,(9(9%(@DJJ}% r   c                 $   |j                  d      dk(  rt        |j                  d            dz  S |j                  d      dk(  rt        |j                  d            S |j                  d      dk(  rt        |j                  d            dz  S y )Nr.   KiBr)   i   MiBGiB)rA   float)r   r:   s     r   rU   zHardware.to_megabytes%  sx    ::a=E!A'$..ZZ]e#A''ZZ]e#A'$..r   )	r   r    r!   r   r   rO   rP   rU   rJ   rK   s   @r   rM   rM     s%     	0H)CAr   rM   c                   J     e Zd ZddgZ ej
                  d      Z fdZ xZS )Configz/export verbosez/exportz,^# [a-z0-9/-][a-z0-9/-]* [0-9:]* by RouterOSc                     t         t        |           | j                  d   }|r|| j                  d<   | j                  d   }|r1t        j                  | j                  d|      }|| j                  d<   y y )Nr   configr)   z
# RouterOSconfig_nonverbose)r1   r_   r   r   r   r>   sub
RM_DATE_REr9   s     r   r   zConfig.populate9  sj    fd$&~~a #'DJJx ~~a 66$//=$?D.2DJJ*+ r   )	r   r    r!   r   r>   compilerd   r   rJ   rK   s   @r   r_   r_   0  s/     	H
 KLJ3 3r   r_   c                        e Zd Zg dZ ej
                  d      Z ej
                  d      Z fdZd Z	d Z
d Zd Zd	 Zd
 Z xZS )
Interfaces)z&/interface print detail without-pagingz'/ip address print detail without-pagingz)/ipv6 address print detail without-pagingz(/ip neighbor print detail without-pagingC([\w\d\-]+)=\"?(\w{3}/\d{2}/\d{4}\s\d{2}:\d{2}:\d{2}|[\w\d\-\.:/]+)
^\s+(?!\d)c                    t         t        |           t               | j                  d<   t               | j                  d<   t               | j                  d<   t               | j                  d<   | j                  d   }|r"| j                  |      }| j                  |       | j                  d   }|r#| j                  |      }| j                  |d       | j                  d   }|r#| j                  |      }| j                  |d	       | j                  d
   }|r(t        | j                  |            | j                  d<   y y )N
interfacesall_ipv4_addressesall_ipv6_addresses	neighborsr   r)   ipv4r.   ipv6   )r1   rg   r   r   r   r"   r   parse_interfacespopulate_interfacesparse_detailpopulate_addresses)r   r:   rk   r;   s      r   r   zInterfaces.populateS  s   j$(*#'6

< +/6

'(+/6

'("&&

;~~a ..t4J$$Z0~~a $$T*D##D&1~~a $$T*D##D&1~~a &*4+<+<T+B&CDJJ{# r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nrk   r	   r   r   r:   keyvalues       r   rs   zInterfaces.populate_interfacesn  s,    #D/ 	2JC,1DJJ|$S)	2r   c                    |D ]  }|d   }|| j                   d   |   vrt               | j                   d   |   |<   |d   j                  d      \  }}t        |j	                         |j	                               }| j                  |j	                         |       | j                   d   |   |   j                  |        y )N	interfacerk   address/)r}   subnet)r   r"   splitr   stripadd_ip_addressappend)r   r:   familyrz   ry   addrr   ips           r   ru   zInterfaces.populate_addressesr  s     	=E$CTZZ5c::8<

<(-f5 +11#6LD&djjl6<<>BB

f5JJ|$S)&188<	=r   c                     |dk(  r| j                   d   j                  |       y | j                   d   j                  |       y )Nro   rl   rm   )r   r   )r   r}   r   s      r   r   zInterfaces.add_ip_address|  s:    VJJ+,33G<JJ+,33G<r   c                     t               }|j                  d      D ]Z  }t        |      dk(  s|d d dk(  r|r t        j                  | j
                  |      s|j                  |       N|dxx   |z  cc<   \ |S N
r      Flagsr"   r   lenr>   rC   WRAPPED_LINE_REr   r   r:   preprocessedlines       r   
preprocesszInterfaces.preprocess  x    vJJt$ 	)D4yA~bqW!4!$2F2F)M##D)R D( 	) r   c                    t               }| j                  |      }|D ]_  }t        t        j                  | j                  |            }d|vr1t        t        j                  | j                  |            ||d   <   a |S )Nname)r   r   r>   findall	DETAIL_RE)r   r:   r   r   parseds        r   rr   zInterfaces.parse_interfaces  su    t$ 	KD"**T^^T:;FV#$(DNND)I$JE&.!		K
 r   c              #      K   | j                  |      }|D ]4  }t        t        j                  | j                  |            }d|vr1| 6 y w)Nr|   )r   r   r>   r   r   )r   r:   r   r   s       r   rt   zInterfaces.parse_detail  sL     t$ 	D"**T^^T:;F&(L		s   AA)r   r    r!   r   r>   re   r   r   r   rs   ru   r   r   rr   rt   rJ   rK   s   @r   rg   rg   G  sQ    H 

abI bjj/OD62==	r   rg   c                        e Zd Zg dZ ej
                  d      Z ej
                  d      Z fdZd Z	d Z
d Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )Routing)z-/routing bgp peer print detail without-pagingz4/routing bgp vpnv4-route print detail without-pagingz1/routing bgp instance print detail without-pagingz%/ip route print detail without-pagingz2/routing ospf instance print detail without-pagingz2/routing ospf neighbor print detail without-pagingrh   ri   c                    t         t        |           t               | j                  d<   t               | j                  d<   t               | j                  d<   t               | j                  d<   t               | j                  d<   t               | j                  d<   | j
                  d   }|r"| j                  |      }| j                  |       | j
                  d   }|r"| j                  |      }| j                  |       | j
                  d	   }|r"| j                  |      }| j                  |       | j
                  d
   }|r"| j                  |      }| j                  |       | j
                  d   }|r"| j                  |      }| j                  |       | j
                  d   }|r#| j                  |      }| j!                  |       y y )Nbgp_peerbgp_vpnv4_routebgp_instancerouteospf_instanceospf_neighborr   r)   r.   rq      r   )r1   r   r   r   r   r   parse_bgp_peerpopulate_bgp_peerparse_vpnv4_routepopulate_vpnv4_routeparse_instancepopulate_bgp_instanceparse_routepopulate_routepopulate_ospf_instanceparse_ospf_neighborpopulate_ospf_neighbor)r   r:   peervpnv4instancer   r;   s         r   r   zRouting.populate  s   gt%'!%

:(,

$%%)V

>""f

7&*f

?#&*f

?#~~a &&t,D""4(~~a **40E%%e,~~a **40H&&x0~~a $$T*E&~~a **40H''1~~a //5H''1 r   c                     t               }|j                  d      D ]Z  }t        |      dk(  s|d d dk(  r|r t        j                  | j
                  |      s|j                  |       N|dxx   |z  cc<   \ |S r   r   r   s       r   r   zRouting.preprocess  r   r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzname=.(\S+\b)r)   r=   rB   s      r   
parse_namezRouting.parse_name  s/    		*D"$$7;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzinterface=([\w\d\-]+)r)   r=   rB   s      r   parse_interfacezRouting.parse_interface  s/    		2D"$$?;;q>! r   c                 t    t        j                  d|t         j                        }|r|j                  d      S y )Nzinstance=([\w\d\-]+)r)   r=   rB   s      r   parse_instance_namezRouting.parse_instance_name  s/    		14>;;q>! r   c                 z    t        j                  d|t         j                        }|r|j                  d      S d}|S )Nzrouting-mark=([\w\d\-]+)r)   mainr=   rB   s      r   parse_routing_markzRouting.parse_routing_mark  s4    		5tRTTB;;q>!ELr   c                     t               }| j                  |      }|D ]P  }| j                  |      }t               ||<   t        j                  | j
                  |      D ]  \  }}|||   |<    R |S r   r   r   r   r>   r   r   r   r:   r   r   r   ry   rz   s          r   r   zRouting.parse_bgp_peer  v    t$ 	)D??4(D&E$K "

4>>4 @ )e#(dC )	)
 r   c                     t               }| j                  |      }|D ]P  }| j                  |      }t               ||<   t        j                  | j
                  |      D ]  \  }}|||   |<    R |S r   r   r   s          r   r   zRouting.parse_instance  r   r   c                     t               }| j                  |      }|D ]P  }| j                  |      }t               ||<   t        j                  | j
                  |      D ]  \  }}|||   |<    R |S r   )r   r   r   r>   r   r   r   s          r   r   zRouting.parse_vpnv4_route  sx    t$ 	)D''-D&E$K "

4>>4 @ )e#(dC )	)
 r   c                     t               }| j                  |      }|D ]P  }| j                  |      }t               ||<   t        j                  | j
                  |      D ]  \  }}|||   |<    R |S r   )r   r   r   r>   r   r   r   s          r   r   zRouting.parse_route  sx    t$ 	)D**40D&E$K "

4>>4 @ )e#(dC )	)
 r   c                     t               }| j                  |      }|D ]P  }| j                  |      }t               ||<   t        j                  | j
                  |      D ]  \  }}|||   |<    R |S r   r   r   s          r   parse_ospf_instancezRouting.parse_ospf_instance  r   r   c                     t               }| j                  |      }|D ]P  }| j                  |      }t               ||<   t        j                  | j
                  |      D ]  \  }}|||   |<    R |S r   )r   r   r   r>   r   r   r   s          r   r   zRouting.parse_ospf_neighbor#  sx    t$ 	)D++D1D&E$K "

4>>4 @ )e#(dC )	)
 r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nr   rw   rx   s       r   r   zRouting.populate_bgp_peer-  s,    #D/ 	0JC*/DJJz"3'	0r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nr   rw   rx   s       r   r   zRouting.populate_vpnv4_route1  s-    #D/ 	7JC16DJJ()#.	7r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nr   rw   rx   s       r   r   zRouting.populate_bgp_instance5  s,    #D/ 	4JC.3DJJ~&s+	4r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nr   rw   rx   s       r   r   zRouting.populate_route9  s,    #D/ 	-JC',DJJw$	-r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nr   rw   rx   s       r   r   zRouting.populate_ospf_instance=  ,    #D/ 	5JC/4DJJ',	5r   c                 N    t        |      D ]  \  }}|| j                  d   |<    y )Nr   rw   rx   s       r   r   zRouting.populate_ospf_neighborA  r   r   )r   r    r!   r   r>   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rJ   rK   s   @r   r   r     s    H 

abI bjj/O2B	"
"
"
074-55r   r   )defaulthardwarerk   ra   routingc                     t        t        dgdd            } | j                  t               t        | d      }|j                  d   }t               }t               }|D ]  }|d	k(  r|j                  t               |j                  d
      r#|dd }|d	k(  r|j                  t               Od}nd}|t        vr|j                  d|z         |r|j                  |       |j                  |        |s|j                  t               |j                  |       |j                  d       t               }t        |      |d<   t               }|D ]  }	|j                  t        |	   |             ! |D ]-  }
|
j                          |j                  |
j                         / t               }t!        |      D ]  \  }	}d|	z  }	|||	<    |j#                  |t$               y)z*main entry point for module execution
    z!configr"   str)r   typeelements)gather_subsetT)argument_specsupports_check_moder   all!r)   NFzBad subset: %s)msgr   zansible_net_%s)ansible_factswarnings)r   updater   r   paramssetVALID_SUBSETS
startswith	fail_jsonadddifference_updater"   r   FACT_SUBSETSr   r   r	   	exit_jsonr   )r   r   r   runable_subsetsexclude_subsetssubsetexcluder   	instancesry   instr   rz   s                r   r   r   S  s    I;VeLM /0/35F MM/2MeOeO (U?""=1S!ABZF&&}5GG&!1F!:;'')(, }-%%o6	"FE!/2E/I 4c*6234  !TZZ ! FM& #
U$"c# =8Dr   __main__)!
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr>   Dansible_collections.community.routeros.plugins.module_utils.routerosr   r   ansible.module_utils.basicr   ansible.module_utils.sixr	   objectr   r%   rM   r_   rg   r   r   r   	frozensetkeysr   r"   r   r   r   r#   r   r   <module>r      s    C B D"v
n 
 ] g 4 .G G 9"i 9"x%y %P3Y 3.V Vrc5i c5L  ,++-.6=E@ zF r   