@ -180,31 +180,24 @@ import json
from xml . etree import ElementTree
from xml . etree import ElementTree
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . junos import get_ config, get_ diff, load_ config
from ansible . module_utils . junos import get_ diff, load_ config, get_ configuration
from ansible . module_utils . junos import junos_argument_spec
from ansible . module_utils . junos import junos_argument_spec
from ansible . module_utils . junos import check_args as junos_check_args
from ansible . module_utils . junos import check_args as junos_check_args
from ansible . module_utils . netc fg import NetworkConfig
from ansible . module_utils . netc onf import send_request
from ansible . module_utils . six import string_types
from ansible . module_utils . six import string_types
USE_PERSISTENT_CONNECTION = True
USE_PERSISTENT_CONNECTION = True
DEFAULT_COMMENT = ' configured by junos_config '
DEFAULT_COMMENT = ' configured by junos_config '
def check_transport ( module ) :
transport = ( module . params [ ' provider ' ] or { } ) . get ( ' transport ' )
if transport == ' netconf ' :
module . fail_json ( msg = ' junos_config module is only supported over cli transport ' )
def check_args ( module , warnings ) :
def check_args ( module , warnings ) :
junos_check_args ( module , warnings )
junos_check_args ( module , warnings )
if module . params [ ' zeroize ' ] :
module . fail_json ( msg = ' argument zeroize is deprecated and no longer '
' supported, use junos_command instead ' )
if module . params [ ' replace ' ] is not None :
if module . params [ ' replace ' ] is not None :
module . fail_json ( msg = ' argument replace is deprecated, use update ' )
module . fail_json ( msg = ' argument replace is deprecated, use update ' )
zeroize = lambda x : send_request ( x , Element ( ' request-system-zeroize ' ) )
rollback = lambda x : get_diff ( x )
def guess_format ( config ) :
def guess_format ( config ) :
try :
try :
json . loads ( config )
json . loads ( config )
@ -223,27 +216,15 @@ def guess_format(config):
return ' text '
return ' text '
def config_to_commands ( config ) :
set_format = config . startswith ( ' set ' ) or config . startswith ( ' delete ' )
candidate = NetworkConfig ( indent = 4 , contents = config )
if not set_format :
candidate = [ c . line for c in candidate . items ]
commands = list ( )
# this filters out less specific lines
for item in candidate :
for index , entry in enumerate ( commands ) :
if item . startswith ( entry ) :
del commands [ index ]
break
commands . append ( item )
else :
commands = str ( candidate ) . split ( ' \n ' )
return commands
def filter_delete_statements ( module , candidate ) :
def filter_delete_statements ( module , candidate ) :
config = get_config ( module )
reply = get_configuration ( module , format = ' set ' )
match = reply . find ( ' .//configuration-set ' )
if match is None :
module . fail_json ( msg = ' unable to retrieve device configuration ' )
config = str ( match . text )
#if 'delete interfaces lo0' in candidate:
# raise ValueError(config)
modified_candidate = candidate [ : ]
modified_candidate = candidate [ : ]
for index , line in enumerate ( candidate ) :
for index , line in enumerate ( candidate ) :
@ -251,39 +232,43 @@ def filter_delete_statements(module, candidate):
newline = re . sub ( ' ^delete ' , ' set ' , line )
newline = re . sub ( ' ^delete ' , ' set ' , line )
if newline not in config :
if newline not in config :
del modified_candidate [ index ]
del modified_candidate [ index ]
return modified_candidate
return modified_candidate
def load ( module ) :
def configure_device ( module ) :
candidate = module . params [ ' lines ' ] or module . params [ ' src ' ]
candidate = module . params [ ' lines ' ] or module . params [ ' src ' ]
if isinstance ( candidate , string_types ) :
if isinstance ( candidate , string_types ) :
candidate = candidate . split ( ' \n ' )
candidate = candidate . split ( ' \n ' )
kwargs = {
kwargs = {
' confirm ' : module . params [ ' confirm ' ] is not None ,
' confirm_timeout ' : module . params [ ' confirm ' ] ,
' comment ' : module . params [ ' comment ' ] ,
' comment ' : module . params [ ' comment ' ] ,
' commit ' : not module . check_mode ,
' commit ' : not module . check_mode
}
}
if module . params [ ' confirm ' ] > 0 :
kwargs . update ( {
' confirm ' : True ,
' confirm_timeout ' : module . params [ ' confirm ' ]
} )
config_format = None
if module . params [ ' src ' ] :
if module . params [ ' src ' ] :
config_format = module . params [ ' src_format ' ] or guess_format ( str ( candidate ) )
config_format = module . params [ ' src_format ' ] or guess_format ( str ( candidate ) )
kwargs . update ( { ' format ' : config_format , ' action ' : module . params [ ' update ' ] } )
if config_format == ' set ' :
kwargs . update ( { ' format ' : ' text ' , ' action ' : ' set ' } )
else :
kwargs . update ( { ' format ' : config_format , ' action ' : module . params [ ' update ' ] } )
# this is done to filter out `delete ...` statements which map to
# this is done to filter out `delete ...` statements which map to
# nothing in the config as that will cause an exception to be raised
# nothing in the config as that will cause an exception to be raised
if module . params [ ' lines ' ] :
if any ( ( module . params [ ' lines ' ] , config_format == ' set ' ) ) :
candidate = filter_delete_statements ( module , candidate )
candidate = filter_delete_statements ( module , candidate )
kwargs [ ' format ' ] = ' text '
kwargs [ ' action ' ] = ' set '
return load_config ( module , candidate , * * kwargs )
return load_config ( module , candidate , * * kwargs )
def update_result ( module , result , diff = None ) :
if diff == ' ' :
diff = None
result [ ' changed ' ] = diff is not None
if module . _diff :
result [ ' diff ' ] = { ' prepared ' : diff }
def main ( ) :
def main ( ) :
""" main entry point for module execution
""" main entry point for module execution
"""
"""
@ -306,35 +291,47 @@ def main():
backup = dict ( type = ' bool ' , default = False ) ,
backup = dict ( type = ' bool ' , default = False ) ,
rollback = dict ( type = ' int ' ) ,
rollback = dict ( type = ' int ' ) ,
# deprecated zeroize in Ansible 2.3
zeroize = dict ( default = False , type = ' bool ' ) ,
zeroize = dict ( default = False , type = ' bool ' ) ,
)
)
argument_spec . update ( junos_argument_spec )
argument_spec . update ( junos_argument_spec )
mutually_exclusive = [ ( ' lines ' , ' src ' , ' rollback ' )]
mutually_exclusive = [ ( ' lines ' , ' src ' , ' rollback ' , ' zeroize ' )]
module = AnsibleModule ( argument_spec = argument_spec ,
module = AnsibleModule ( argument_spec = argument_spec ,
mutually_exclusive = mutually_exclusive ,
mutually_exclusive = mutually_exclusive ,
supports_check_mode = True )
supports_check_mode = True )
check_transport ( module )
warnings = list ( )
warnings = list ( )
check_args ( module , warnings )
check_args ( module , warnings )
result = { ' changed ' : False , ' warnings ' : warnings }
result = { ' changed ' : False , ' warnings ' : warnings }
if module . params [ ' backup ' ] :
if module . params [ ' backup ' ] :
result [ ' __backup__ ' ] = get_config ( module )
reply = get_configuration ( module , format = ' set ' )
match = reply . find ( ' .//configuration-set ' )
if match is None :
module . fail_json ( msg = ' unable to retrieve device configuration ' )
result [ ' __backup__ ' ] = str ( match . text ) . strip ( )
if module . params [ ' rollback ' ] :
if module . params [ ' rollback ' ] :
diff = get_diff ( module )
if not module . check_mode :
update_result ( module , result , diff )
diff = rollback ( module )
if module . _diff :
result [ ' diff ' ] = { ' prepared ' : diff }
result [ ' changed ' ] = True
elif module . params [ ' zeroize ' ] :
if not module . check_mode :
zeroize ( module )
result [ ' changed ' ] = True
else :
else :
diff = load ( module )
diff = configure_device ( module )
update_result ( module , result , diff )
if diff :
if module . _diff :
result [ ' diff ' ] = { ' prepared ' : diff }
result [ ' changed ' ] = True
module . exit_json ( * * result )
module . exit_json ( * * result )