@ -71,6 +71,11 @@ options:
- This option has no effect for states other than " absent " .
- This option has no effect for states other than " absent " .
default : false
default : false
version_added : " 2.5 "
version_added : " 2.5 "
random_password :
description : Generate a random password to be used in bulk enrollment
default : False
type : bool
version_added : ' 2.5 '
extends_documentation_fragment : ipa . documentation
extends_documentation_fragment : ipa . documentation
version_added : " 2.3 "
version_added : " 2.3 "
'''
'''
@ -92,6 +97,18 @@ EXAMPLES = '''
ipa_user : admin
ipa_user : admin
ipa_pass : topsecret
ipa_pass : topsecret
# Generate a random password for bulk enrolment
- ipa_host :
name : host01 . example . com
description : Example host
ip_address : 192.168 .0 .123
state : present
ipa_host : ipa . example . com
ipa_user : admin
ipa_pass : topsecret
validate_certs : False
random_password : True
# Ensure host is disabled
# Ensure host is disabled
- ipa_host :
- ipa_host :
name : host01 . example . com
name : host01 . example . com
@ -148,6 +165,9 @@ class HostIPAClient(IPAClient):
def __init__ ( self , module , host , port , protocol ) :
def __init__ ( self , module , host , port , protocol ) :
super ( HostIPAClient , self ) . __init__ ( module , host , port , protocol )
super ( HostIPAClient , self ) . __init__ ( module , host , port , protocol )
def host_show ( self , name ) :
return self . _post_json ( method = ' host_show ' , name = name )
def host_find ( self , name ) :
def host_find ( self , name ) :
return self . _post_json ( method = ' host_find ' , name = None , item = { ' all ' : True , ' fqdn ' : name } )
return self . _post_json ( method = ' host_find ' , name = None , item = { ' all ' : True , ' fqdn ' : name } )
@ -165,7 +185,7 @@ class HostIPAClient(IPAClient):
def get_host_dict ( description = None , force = None , ip_address = None , ns_host_location = None , ns_hardware_platform = None ,
def get_host_dict ( description = None , force = None , ip_address = None , ns_host_location = None , ns_hardware_platform = None ,
ns_os_version = None , user_certificate = None , mac_address = None ):
ns_os_version = None , user_certificate = None , mac_address = None , random_password = None ):
data = { }
data = { }
if description is not None :
if description is not None :
data [ ' description ' ] = description
data [ ' description ' ] = description
@ -183,11 +203,15 @@ def get_host_dict(description=None, force=None, ip_address=None, ns_host_locatio
data [ ' usercertificate ' ] = [ { " __base64__ " : item } for item in user_certificate ]
data [ ' usercertificate ' ] = [ { " __base64__ " : item } for item in user_certificate ]
if mac_address is not None :
if mac_address is not None :
data [ ' macaddress ' ] = mac_address
data [ ' macaddress ' ] = mac_address
if random_password is not None :
data [ ' random ' ] = random_password
return data
return data
def get_host_diff ( client , ipa_host , module_host ) :
def get_host_diff ( client , ipa_host , module_host ) :
non_updateable_keys = [ ' force ' , ' ip_address ' ]
non_updateable_keys = [ ' force ' , ' ip_address ' ]
if not module_host . get ( ' random ' ) :
non_updateable_keys . append ( ' random ' )
for key in non_updateable_keys :
for key in non_updateable_keys :
if key in module_host :
if key in module_host :
del module_host [ key ]
del module_host [ key ]
@ -206,13 +230,17 @@ def ensure(module, client):
ns_hardware_platform = module . params [ ' ns_hardware_platform ' ] ,
ns_hardware_platform = module . params [ ' ns_hardware_platform ' ] ,
ns_os_version = module . params [ ' ns_os_version ' ] ,
ns_os_version = module . params [ ' ns_os_version ' ] ,
user_certificate = module . params [ ' user_certificate ' ] ,
user_certificate = module . params [ ' user_certificate ' ] ,
mac_address = module . params [ ' mac_address ' ] )
mac_address = module . params [ ' mac_address ' ] ,
random_password = module . params . get ( ' random_password ' ) ,
)
changed = False
changed = False
if state in [ ' present ' , ' enabled ' , ' disabled ' ] :
if state in [ ' present ' , ' enabled ' , ' disabled ' ] :
if not ipa_host :
if not ipa_host :
changed = True
changed = True
if not module . check_mode :
if not module . check_mode :
client . host_add ( name = name , host = module_host )
# OTP password generated by FreeIPA is visible only for host_add command
# so, return directly from here.
return changed , client . host_add ( name = name , host = module_host )
else :
else :
diff = get_host_diff ( client , ipa_host , module_host )
diff = get_host_diff ( client , ipa_host , module_host )
if len ( diff ) > 0 :
if len ( diff ) > 0 :
@ -221,7 +249,10 @@ def ensure(module, client):
data = { }
data = { }
for key in diff :
for key in diff :
data [ key ] = module_host . get ( key )
data [ key ] = module_host . get ( key )
client . host_mod ( name = name , host = data )
ipa_host_show = client . host_show ( name = name )
if ipa_host_show . get ( ' has_keytab ' , False ) and module . params . get ( ' random_password ' ) :
client . host_disable ( name = name )
return changed , client . host_mod ( name = name , host = data )
else :
else :
if ipa_host :
if ipa_host :
@ -245,7 +276,8 @@ def main():
user_certificate = dict ( type = ' list ' , aliases = [ ' usercertificate ' ] ) ,
user_certificate = dict ( type = ' list ' , aliases = [ ' usercertificate ' ] ) ,
mac_address = dict ( type = ' list ' , aliases = [ ' macaddress ' ] ) ,
mac_address = dict ( type = ' list ' , aliases = [ ' macaddress ' ] ) ,
update_dns = dict ( type = ' bool ' ) ,
update_dns = dict ( type = ' bool ' ) ,
state = dict ( type = ' str ' , default = ' present ' , choices = [ ' present ' , ' absent ' , ' enabled ' , ' disabled ' ] ) )
state = dict ( type = ' str ' , default = ' present ' , choices = [ ' present ' , ' absent ' , ' enabled ' , ' disabled ' ] ) ,
random_password = dict ( type = ' bool ' ) , )
module = AnsibleModule ( argument_spec = argument_spec ,
module = AnsibleModule ( argument_spec = argument_spec ,
supports_check_mode = True )
supports_check_mode = True )
@ -263,5 +295,6 @@ def main():
except Exception as e :
except Exception as e :
module . fail_json ( msg = to_native ( e ) , exception = traceback . format_exc ( ) )
module . fail_json ( msg = to_native ( e ) , exception = traceback . format_exc ( ) )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :
main ( )
main ( )