
    Vh;                     Z   d dl mZmZmZ eZdZdZdZd dl	m
Z
 d dlmZ d dlmZ d dlmZmZ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 eeeee      Z eej?                               Z g Z!d Z"e#dk(  r e"        yy# e$ r Y sw xY w)    )absolute_importdivisionprint_functiona  
module: api_facts
author:
  - "Egor Zaitsev (@heuels)"
  - "Nikolay Dachev (@NikolayDachev)"
  - "Felix Fontein (@felixfontein)"
version_added: 2.1.0
short_description: Collect facts from remote devices running MikroTik RouterOS using the API
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.
  - As opposed to the M(community.routeros.facts) module, it uses the RouterOS API, similar to the M(community.routeros.api)
    module.
extends_documentation_fragment:
  - community.routeros.api
  - community.routeros.attributes
  - community.routeros.attributes.actiongroup_api
  - 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(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:
      - all
    type: list
    elements: str
seealso:
  - module: community.routeros.facts
  - module: community.routeros.api
  - module: community.routeros.api_find_and_modify
  - module: community.routeros.api_info
  - module: community.routeros.api_modify
a`  
---
- name: Collect all facts from the device
  community.routeros.api_facts:
    hostname: 192.168.88.1
    username: admin
    password: password
    gather_subset: all

- name: Do not collect hardware facts
  community.routeros.api_facts:
    hostname: 192.168.88.1
    username: admin
    password: password
    gather_subset:
      - "!hardware"
ay  
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

    # 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
)AnsibleModule)	iteritems)	to_native)api_argument_speccheck_has_library
create_api)LibRouterosErrorc                   "    e Zd Zg Zd Zd Zd Zy)	FactsBasec                 <    || _         || _        i | _        d | _        y N)moduleapifacts	responses)selfr   r   s      p/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/routeros/plugins/modules/api_facts.py__init__zFactsBase.__init__   s    
    c                     g | _         | j                  D ],  }| j                   j                  | j                  |             . y r   )r   COMMANDSappend
query_path)r   paths     r   populatezFactsBase.populate   s7    MM 	9DNN!!$//$"78	9r   c           	      6   | j                   j                         }|D ]  }|j                  |      } 	 t        |      S # t        $ rP}| j
                  j                  dj                  dj                  |      t        |                   g cY d }~S d }~ww xY w)Nz)Error while querying path {path}: {error} )r   error)	r   r   joinlistr   r   warnformatr   )r   r   api_pathpartes        r   r   zFactsBase.query_path   s    88==? 	+D}}T*H	+	>! 	KKHOOXXd^l P   I	s   
? 	BABBBN)__name__
__module____qualname__r   r   r   r    r   r   r   r      s    H9
r   r   c                   4     e Zd ZddgddgddggZ fdZ xZS )Defaultsystemidentityresourcerouterboardc                 `   t         t        |           | j                  d   }|r!|d   j	                  d      | j
                  d<   | j                  d   }|r|d   j	                  d      | j
                  d<   |d   j	                  d      | j
                  d<   |d   j	                  d      | j
                  d<   |d   j	                  d	      | j
                  d
<   | j                  d   }|rC|d   j	                  d      | j
                  d<   |d   j	                  d      | j
                  d<   y y )Nr   namehostname   versionzarchitecture-namearchuptimezcpu-loadcpu_load   modelzserial-number	serialnum)superr.   r   r   getr   r   data	__class__s     r   r   zDefault.populate   s   gt%'~~a %)!W[[%8DJJz"~~a $(GKK	$:DJJy!!%a-@!ADJJv#'7;;x#8DJJx %)!W[[%<DJJz"~~a "&q'++g"6DJJw&*1gkk/&BDJJ{# r   )r)   r*   r+   r   r   __classcell__rB   s   @r   r.   r.      s0     
:	:	=!HC Cr   r.   c                   :     e Zd ZddggZ fdZd Zd Zd Z xZS )Hardwarer/   r1   c                     t         t        |           | j                  d   }|r)| j	                  |d          | j                  |d          y y )Nr   )r>   rF   r   r   parse_filesystem_infoparse_memory_infor@   s     r   r   zHardware.populate   sJ    h&(~~a &&tAw/""47+ r   c                     | j                  |j                  d            | j                  d<   | j                  |j                  d            | j                  d<   y )Nzfree-hdd-spacespacefree_mbztotal-hdd-spacespacetotal_mbto_megabytesr?   r   r   rA   s     r   rH   zHardware.parse_filesystem_info  sH    %)%6%6txx@P7Q%R

>"&*&7&7AR8S&T

?#r   c                     | j                  |j                  d            | j                  d<   | j                  |j                  d            | j                  d<   y )Nzfree-memory
memfree_mbztotal-memorymemtotal_mbrM   rO   s     r   rI   zHardware.parse_memory_info  sF    #'#4#4TXXm5L#M

< $($5$5dhh~6N$O

=!r   c                 *    |y t        |      dz  dz  S )Ni   )float)r   values     r   rN   zHardware.to_megabytes  s    =U|d"T))r   )	r)   r*   r+   r   r   rH   rI   rN   rC   rD   s   @r   rF   rF      s*     
:H,UP*r   rF   c                   V     e Zd ZdgddgddgddggZ fdZd Zd Zd	 Zd
 Zd Z	 xZ
S )
Interfaces	interfaceipaddressipv6neighborc                 J   t         t        |           i | j                  d<   g | j                  d<   g | j                  d<   g | 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   r6   ipv4r;   r[      )
r>   rW   r   r   r   parse_interfacespopulate_interfacesparse_detailpopulate_addressesr#   )r   rA   r^   rB   s      r   r   zInterfaces.populate  s   j$(*#%

< +-

'(+-

'("$

;~~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 )Nr^   r   r   )r   rA   keyrU   s       r   re   zInterfaces.populate_interfaces9  s,    #D/ 	2JC,1DJJ|$S)	2r   c                    |D ]  }|d   }|| j                   d   |   vrg | j                   d   |   |<   |d   j                  d      \  }}|j                         }	 t        |      }t        |j                         |      }| j                  |j                         |       | j                   d   |   |   j                  |        y # t        $ r Y mw xY w)NrX   r^   rZ   /)rZ   subnet)r   splitstripint	Exceptiondictadd_ip_addressr   )r   rA   familyrU   rj   addrrm   rY   s           r   rg   zInterfaces.populate_addresses=  s     	=E$CTZZ5c::8:

<(-f5 +11#6LD&\\^FV djjl6:B

f5JJ|$S)&188<	=  s   C			CCc                     |dk(  r| j                   d   j                  |       y | j                   d   j                  |       y )Nrb   r_   r`   )r   r   )r   rZ   rt   s      r   rs   zInterfaces.add_ip_addressM  s:    VJJ+,33G<JJ+,33G<r   c                 V    i }|D ]!  }d|vr|j                  dd        |||d   <   # |S )Nr4   .idpop)r   rA   r   entrys       r   rd   zInterfaces.parse_interfacesS  sD     	)EU"IIeT"#(E%- 		)
 r   c              #   P   K   |D ]  }d|vr|j                  dd        |  y w)NrX   rx   ry   )r   rA   r{   s      r   rf   zInterfaces.parse_detail\  s3      	E%'IIeT"K		s   $&)r)   r*   r+   r   r   re   rg   rs   rd   rf   rC   rD   s   @r   rW   rW     sH     
	y		z	HD62= =r   rW   c                   T     e Zd Zg dg dg dddgg dg dgZ fdZdd	Zd
 Z xZS )Routing)routingbgppeer)r   r   zvpnv4-route)r   r   instancerY   route)r   ospfr   )r   r   r\   c                 `   t         t        |           i | j                  d<   i | j                  d<   i | j                  d<   i | j                  d<   i | j                  d<   i | j                  d<   | j                  d   }|r$| j                  |d      }| j                  d|       | j                  d	   }|r$| j                  |d
      }| j                  d|       | j                  d   }|r$| j                  |d      }| j                  d|       | j                  d   }|r&| j                  |dd      }| j                  d|       | j                  d   }|r$| j                  |d      }| j                  d|       | j                  d   }|r%| j                  |d      }| j                  d|       y y )Nbgp_peerbgp_vpnv4_routebgp_instancer   ospf_instanceospf_neighborr   r4   r6   rX   r;   rc   zrouting-markmain)fallback      r   )r>   r~   r   r   r   parsepopulate_result)r   rA   r   vpnv4r   r   rB   s         r   r   zRouting.populateo  s   gt%'!#

:(*

$%%'

>" 

7&(

?#&(

?#~~a ::dF+D  T2~~a JJt[1E  !2E:~~a zz$/H  :~~a JJt^fJEE  %0~~a zz$/H  (;~~a zz$
3H  (; r   c                 p    i }|D ].  }|j                  |      xs |}|j                  dd        |||<   0 |S )Nrx   )r?   rz   )r   rA   rj   r   r   liner4   s          r   r   zRouting.parse  sF     	D88C=,HDHHUD!E$K	 r   c                 N    t        |      D ]  \  }}|| j                  |   |<    y r   ri   )r   r4   rA   rj   rU   s        r   r   zRouting.populate_result  s,    #D/ 	*JC$)DJJtS!	*r   r   )r)   r*   r+   r   r   r   r   rC   rD   s   @r   r~   r~   d  s2     	#)&	w''H<B*r   r~   )defaulthardwarer^   r   c                     t        t        dgdd            } | j                  t                      t        | d      }t	        |       t        |      }|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       i }t        |      |d<   g }	|D ]   }
|	j                  t        |
   ||             " |	D ]-  }|j!                          |j                  |j"                         / i }t%        |      D ]  \  }
}d|
z  }
|||
<    |j'                  |t(               y )Nallr#   str)r   typeelements)gather_subsetT)argument_specsupports_check_moder   !r6   FzBad subset: %s)msgr   zansible_net_%s)ansible_factswarnings)rr   updater	   r   r
   r   paramssetVALID_SUBSETS
startswith	fail_jsonadddifference_updatesortedr   FACT_SUBSETSr   r   r   	exit_jsonr   )r   r   r   r   runable_subsetsexclude_subsetssubsetexcluder   	instancesrj   instr   rU   s                 r   r   r     s   G
M *,-DQFf
V
CMM/2MeOeO (U?""=1S!ABZF&&}5GG&!1F!:;'')(, }-%%o6	"E#O4E/I 9c*63789  !TZZ ! M& #
U$"c# =8Dr   __main__N)$
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   ansible.module_utils.sixr   +ansible.module_utils.common.text.convertersr   ?ansible_collections.community.routeros.plugins.module_utils.apir	   r
   r   librouteros.exceptionsr   rq   objectr   r.   rF   rW   r~   rr   r   	frozensetkeysr   r   r   r)   r,   r   r   <module>r      s    C B+Z$f
P 5 . A 	7 :Ci C2*y *6L L^6*i 6*r 	 ,++-.?ED zF Y	  		s   B" "B*)B*