@ -42,19 +42,31 @@ options:
"""
"""
EXAMPLES = """
EXAMPLES = """
# Note: examples below use the following provider dict to handle
# transport and authentication to the node.
vars :
cli :
host : " {{ inventory_hostname }} "
username : cisco
password : cisco
transport : cli
# Collect all facts from the device
# Collect all facts from the device
- ios_facts :
- ios_facts :
gather_subset : all
gather_subset : all
provider : " {{ cli }} "
# Collect only the config and default facts
# Collect only the config and default facts
- ios_facts :
- ios_facts :
gather_subset :
gather_subset :
- config
- config
provider : " {{ cli }} "
# Do not collect hardware facts
# Do not collect hardware facts
- ios_facts :
- ios_facts :
gather_subset :
gather_subset :
- " !hardware "
- " !hardware "
provider : " {{ cli }} "
"""
"""
RETURN = """
RETURN = """
@ -127,44 +139,35 @@ import re
import itertools
import itertools
import ansible . module_utils . ios
import ansible . module_utils . ios
from ansible . module_utils . netcli import CommandRunner , AddCommandError
from ansible . module_utils . network import NetworkModule
from ansible . module_utils . network import NetworkModule
from ansible . module_utils . six import iteritems
from ansible . module_utils . six import iteritems
from ansible . module_utils . six . moves import zip
from ansible . module_utils . six . moves import zip
def add_command ( runner , command ) :
try :
runner . add_command ( command )
except AddCommandError :
# AddCommandError is raised for any issue adding a command to
# the runner. Silently ignore the exception in this case
pass
class FactsBase ( object ) :
class FactsBase ( object ) :
def __init__ ( self , runner ) :
def __init__ ( self , module ) :
self . runner = runner
self . module = module
self . facts = dict ( )
self . facts = dict ( )
self . failed_commands = list ( )
self . commands ( )
def run ( self , cmd ) :
try :
return self . module . cli ( cmd ) [ 0 ]
except :
self . failed_commands . append ( cmd )
def commands ( self ) :
raise NotImplementedError
class Default ( FactsBase ) :
class Default ( FactsBase ) :
def commands ( self ) :
add_command ( self . runner , ' show version ' )
def populate ( self ) :
def populate ( self ) :
data = self . run ner. get_command ( ' show version ' )
data = self . run ( ' show version ' )
if data :
self . facts [ ' version ' ] = self . parse_version ( data )
self . facts [ ' version ' ] = self . parse_version ( data )
self . facts [ ' serialnum ' ] = self . parse_serialnum ( data )
self . facts [ ' serialnum ' ] = self . parse_serialnum ( data )
self . facts [ ' model ' ] = self . parse_model ( data )
self . facts [ ' model ' ] = self . parse_model ( data )
self . facts [ ' image ' ] = self . parse_image ( data )
self . facts [ ' image ' ] = self . parse_image ( data )
self . facts [ ' hostname ' ] = self . parse_hostname ( data )
self . facts [ ' hostname ' ] = self . parse_hostname ( data )
def parse_version ( self , data ) :
def parse_version ( self , data ) :
match = re . search ( r ' Version ( \ S+), ' , data )
match = re . search ( r ' Version ( \ S+), ' , data )
@ -194,20 +197,17 @@ class Default(FactsBase):
class Hardware ( FactsBase ) :
class Hardware ( FactsBase ) :
def commands ( self ) :
add_command ( self . runner , ' dir | include Directory ' )
add_command ( self . runner , ' show version ' )
add_command ( self . runner , ' show memory statistics | include Processor ' )
def populate ( self ) :
def populate ( self ) :
data = self . runner . get_command ( ' dir | include Directory ' )
data = self . run ( ' dir | include Directory ' )
self . facts [ ' filesystems ' ] = self . parse_filesystems ( data )
if data :
self . facts [ ' filesystems ' ] = self . parse_filesystems ( data )
data = self . runner . get_command ( ' show memory statistics | include Processor ' )
data = self . run ( ' show memory statistics | include Processor ' )
match = re . findall ( r ' \ s( \ d+) \ s ' , data )
if data :
if match :
match = re . findall ( r ' \ s( \ d+) \ s ' , data )
self . facts [ ' memtotal_mb ' ] = int ( match [ 0 ] ) / 1024
if match :
self . facts [ ' memfree_mb ' ] = int ( match [ 1 ] ) / 1024
self . facts [ ' memtotal_mb ' ] = int ( match [ 0 ] ) / 1024
self . facts [ ' memfree_mb ' ] = int ( match [ 1 ] ) / 1024
def parse_filesystems ( self , data ) :
def parse_filesystems ( self , data ) :
return re . findall ( r ' ^Directory of ( \ S+)/ ' , data , re . M )
return re . findall ( r ' ^Directory of ( \ S+)/ ' , data , re . M )
@ -215,37 +215,33 @@ class Hardware(FactsBase):
class Config ( FactsBase ) :
class Config ( FactsBase ) :
def commands ( self ) :
add_command ( self . runner , ' show running-config ' )
def populate ( self ) :
def populate ( self ) :
self . facts [ ' config ' ] = self . runner . get_command ( ' show running-config ' )
data = self . run ( ' show running-config ' )
if data :
self . facts [ ' config ' ] = data
class Interfaces ( FactsBase ) :
class Interfaces ( FactsBase ) :
def commands ( self ) :
add_command ( self . runner , ' show interfaces ' )
add_command ( self . runner , ' show ipv6 interface ' )
add_command ( self . runner , ' show lldp ' )
add_command ( self . runner , ' show lldp neighbors detail ' )
def populate ( self ) :
def populate ( self ) :
self . facts [ ' all_ipv4_addresses ' ] = list ( )
self . facts [ ' all_ipv4_addresses ' ] = list ( )
self . facts [ ' all_ipv6_addresses ' ] = list ( )
self . facts [ ' all_ipv6_addresses ' ] = list ( )
data = self . runner . get_command ( ' show interfaces ' )
data = self . run ( ' show interfaces ' )
interfaces = self . parse_interfaces ( data )
if data :
self . facts [ ' interfaces ' ] = self . populate_interfaces ( interfaces )
interfaces = self . parse_interfaces ( data )
self . facts [ ' interfaces ' ] = self . populate_interfaces ( interfaces )
data = self . run ner. get_command ( ' show ipv6 interface ' )
data = self . run ( ' show ipv6 interface ' )
if len ( data ) > 0 :
if data :
data = self . parse_interfaces ( data )
data = self . parse_interfaces ( data )
self . populate_ipv6_interfaces ( data )
self . populate_ipv6_interfaces ( data )
if ' LLDP is not enabled ' not in self . runner . get_command ( ' show lldp ' ) :
data = self . run ( ' show lldp ' )
neighbors = self . runner . get_command ( ' show lldp neighbors detail ' )
if ' LLDP is not enabled ' not in data :
self . facts [ ' neighbors ' ] = self . parse_neighbors ( neighbors )
neighbors = self . run ( ' show lldp neighbors detail ' )
if neighbors :
self . facts [ ' neighbors ' ] = self . parse_neighbors ( neighbors )
def populate_interfaces ( self , interfaces ) :
def populate_interfaces ( self , interfaces ) :
facts = dict ( )
facts = dict ( )
@ -434,27 +430,27 @@ def main():
facts = dict ( )
facts = dict ( )
facts [ ' gather_subset ' ] = list ( runable_subsets )
facts [ ' gather_subset ' ] = list ( runable_subsets )
runner = CommandRunner ( module )
instances = list ( )
instances = list ( )
for key in runable_subsets :
for key in runable_subsets :
instances . append ( FACT_SUBSETS [ key ] ( runner ) )
instances . append ( FACT_SUBSETS [ key ] ( module ) )
runner. run ( )
failed_commands = list ( )
try :
try :
for inst in instances :
for inst in instances :
inst . populate ( )
inst . populate ( )
failed_commands . extend ( inst . failed_commands )
facts . update ( inst . facts )
facts . update ( inst . facts )
except Exception :
except Exception :
module . exit_json ( out = module . from_json ( runner . items ) )
exc = get_exception ( )
module . fail_json ( msg = str ( exc ) )
ansible_facts = dict ( )
ansible_facts = dict ( )
for key , value in iteritems ( facts ) :
for key , value in iteritems ( facts ) :
key = ' ansible_net_ %s ' % key
key = ' ansible_net_ %s ' % key
ansible_facts [ key ] = value
ansible_facts [ key ] = value
module . exit_json ( ansible_facts = ansible_facts )
module . exit_json ( ansible_facts = ansible_facts , failed_commands = failed_commands )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :