@ -36,7 +36,9 @@ options:
in the device running - config . Be sure to note the configuration
command syntax as some commands are automatically modified by the
device config parser .
required : true
required : false
default : null
aliases : [ ' commands ' ]
parents :
description :
- The ordered set of parents that uniquely identify the section
@ -45,6 +47,40 @@ options:
level or global commands .
required : false
default : null
src :
description :
- Specifies the source path to the file that contains the configuration
or configuration template to load . The path to the source file can
either be the full path on the Ansible control host or a relative
path from the playbook or role root dir . This argument is mutually
exclusive with O ( lines ) .
required : false
default : null
version_added : " 2.2 "
dest :
description :
- Configures a destination file write the source template or config
updates to . The path to the destination file can either be a full
path on the Ansible control host or a relative path from the
playbook or role root dir . This will , by default , overwrite any
previously created file . See O ( append ) to change the behavior .
- When the O ( dest ) argument is used , the output from processing the
configuration lines is written to a file and not to the actual
device . If the O ( dest ) argument is omitted , then the configuration
is written to the device .
required : false
default : null
version_added : " 2.2 "
append :
description :
- Changes the default behavior when writing the configuration out
to a remote file on disk . By defaul if O ( dest ) is specified , the
file is overridden . By setting this argument to true , the remote
file ( if it exists ) is appended to .
required : false
default : false
choices : [ ' yes ' , ' no ' ]
version_added : " 2.2 "
before :
description :
- The ordered set of commands to push on to the command stack if
@ -68,11 +104,13 @@ options:
the set of commands against the current device config . If
match is set to I ( line ) , commands are matched line by line . If
match is set to I ( strict ) , command lines are matched with respect
to position . Finally if match is set to I ( exact ) , command lines
must be an equal match .
to position . If match is set to I ( exact ) , command lines
must be an equal match . Finally , if match is set to I ( none ) , the
module will not attempt to compare the source configuration with
the running configuration on the remote device .
required : false
default : line
choices : [ ' line ' , ' strict ' , ' exact ' ]
choices : [ ' line ' , ' strict ' , ' exact ' , ' none ' ]
replace :
description :
- Instructs the module on the way to perform the configuration
@ -84,26 +122,16 @@ options:
required : false
default : line
choices : [ ' line ' , ' block ' ]
force :
backup_config :
description :
- The force argument instructs the module to not consider the
current devices running - config . When set to true , this will
cause the module to push the contents of I ( src ) into the device
without first checking if already configured .
- This argument will cause the module to create a full backup of
the current C ( running - config ) from the remote device before any
changes are made . The backup file is written to the C ( backup )
folder in the playbook root directory . If the directory does not
exist , it is created .
required : false
default : false
choices : [ ' yes ' , ' no ' ]
config :
description :
- The module , by default , will connect to the remote device and
retrieve the current running - config to use as a base for comparing
against the contents of source . There are times when it is not
desirable to have the task get the current running - config for
every task in a playbook . The I ( config ) argument allows the
implementer to pass in the configuruation to use as the base
config for comparision .
required : false
default : null
version_added : " 2.2 "
"""
EXAMPLES = """
@ -153,72 +181,107 @@ responses:
type : list
sample : [ ' ... ' , ' ... ' ]
"""
from ansible . module_utils . netcfg import NetworkConfig , dumps
from ansible . module_utils . ios import NetworkModule
from ansible . module_utils . ios import load_config , get_config , ios_argument_spec
def get_config ( module ) :
config = module . params [ ' config ' ] or dict ( )
if not config and not module . params [ ' force ' ] :
config = module . config
return config
def invoke ( name , * args , * * kwargs ) :
func = globals ( ) . get ( name )
if func :
return func ( * args , * * kwargs )
def check_args ( module , warnings ) :
if module . params [ ' parents ' ] :
if not module . params [ ' lines ' ] or module . params [ ' src ' ] :
warnings . append ( ' ignoring unneeded argument parents ' )
if module . params [ ' match ' ] == ' none ' and module . params [ ' replace ' ] :
warnings . append ( ' ignorning unneeded argument replace ' )
if module . params [ ' dest ' ] and module . params [ ' save_config ' ] is True :
warnings . append ( ' config will not be saved with dest argument used ' )
def get_candidate ( module ) :
candidate = NetworkConfig ( indent = 1 )
if module . params [ ' src ' ] :
candidate = module . params [ ' src ' ]
elif module . params [ ' lines ' ] :
parents = module . params [ ' parents ' ] or list ( )
candidate . add ( module . params [ ' lines ' ] , parents = parents )
return candidate
def main ( ) :
argument_spec = dict (
lines = dict ( aliases = [ ' commands ' ] , required = True , type = ' list ' ) ,
lines = dict ( aliases = [ ' commands ' ] , type = ' list ' ) ,
parents = dict ( type = ' list ' ) ,
src = dict ( type = ' path ' ) ,
dest = dict ( type = ' path ' ) ,
append = dict ( type = ' bool ' , default = False ) ,
before = dict ( type = ' list ' ) ,
after = dict ( type = ' list ' ) ,
match = dict ( default = ' line ' , choices = [ ' line ' , ' strict ' , ' exact ' ] ) ,
match = dict ( default = ' line ' , choices = [ ' line ' , ' strict ' , ' exact ' , ' none ' ] ) ,
replace = dict ( default = ' line ' , choices = [ ' line ' , ' block ' ] ) ,
force = dict ( default = False , type = ' bool ' ) ,
config = dict ( )
backup_ config= dict ( type = ' bool ' , default = False )
)
argument_spec . update ( ios_argument_spec )
module = get_module ( argument_spec = argument_spec ,
supports_check_mode = True )
mutually_exclusive = [ ( ' lines ' , ' src ' ) ]
lines = module . params [ ' lines ' ]
parents = module . params [ ' parents ' ] or list ( )
module = NetworkModule ( argument_spec = argument_spec ,
connect_on_load = False ,
mutually_exclusive = mutually_exclusive ,
supports_check_mode = True )
before = module . params [ ' before ' ]
after = module . params [ ' after ' ]
parents = module . params [ ' parents ' ] or list ( )
match = module . params [ ' match ' ]
replace = module . params [ ' replace ' ]
if not module . params [ ' force ' ] :
contents = get_config ( module )
config = NetworkConfig ( contents = contents , indent = 1 )
warnings = list ( )
invoke ( ' check_args ' , module , warnings )
result = dict ( changed = False , saved = False )
candidate = NetworkConfig ( indent = 1 )
candidate . add ( lines , parents = parents )
candidate = get_candidate ( module )
commands = candidate . difference ( config , path = parents , match = match , replace = replace )
if module . params [ ' match ' ] != ' none ' :
config = get_config ( module )
configobjs = candidate . difference ( config , match = match , replace = replace )
else :
commands = parents
commands . extend ( lines )
configobjs = candidate . items
result = dict ( changed = False )
if module . params [ ' backup_config ' ] :
result [ ' __backup__ ' ] = module . cli ( ' show running-config ' ) [ 0 ]
if commands :
if before :
commands = list ( )
if configobjs :
commands = dumps ( configobjs , ' commands ' )
if module . params [ ' before ' ] :
commands [ : 0 ] = before
if after :
commands . extend ( after )
if module . params [ ' after ' ] :
commands . extend ( module . params [ ' after ' ] )
if not module . params [ ' dest ' ] :
response = load_config ( module , commands , nodiff = True )
result . update ( * * response )
else :
result [ ' __config__ ' ] = dumps ( configobjs , ' block ' )
if not module . check_mode :
commands = [ str ( c ) . strip ( ) for c in commands ]
response = module . configure ( commands )
result [ ' responses ' ] = response
result [ ' changed ' ] = True
if commands :
commands = commands . split ( ' \n ' )
result [ ' updates ' ] = commands
result [ ' connected ' ] = module . connected
module . exit_json ( * * result )
from ansible . module_utils . basic import *
from ansible . module_utils . shell import *
from ansible . module_utils . netcfg import *
from ansible . module_utils . ios import *
if __name__ == ' __main__ ' :
main ( )