@ -99,14 +99,14 @@ user:
'''
'''
from ansible . module_utils . _text import to_native
from ansible . module_utils . _text import to_native
from ansible . module_utils . basic import Ansible Module
from ansible . module_utils . aws. core import AnsibleAWS Module
from ansible . module_utils . ec2 import camel_dict_to_snake_dict , ec2_argument_spec , get_aws_connection_info , boto3_conn
from ansible . module_utils . ec2 import camel_dict_to_snake_dict , ec2_argument_spec , get_aws_connection_info , boto3_conn
from ansible . module_utils . ec2 import HAS_BOTO3
from ansible . module_utils . ec2 import HAS_BOTO3
import traceback
import traceback
try :
try :
from botocore . exceptions import ClientError , ParamValidationError
from botocore . exceptions import ClientError , ParamValidationError , BotoCoreError
except ImportError :
except ImportError :
pass # caught by imported HAS_BOTO3
pass # caught by imported HAS_BOTO3
@ -227,38 +227,72 @@ def create_or_update_user(connection, module):
def destroy_user ( connection , module ) :
def destroy_user ( connection , module ) :
params = dict ( )
user_name = module . params . get ( ' name ' )
params [ ' UserName ' ] = module . params . get ( ' name ' )
if get_user ( connection , module , params [ ' UserName ' ] ) :
user = get_user ( connection , module , user_name )
# Check mode means we would remove this user
# User is not present
if module . check_mode :
if not user :
module . exit_json ( changed = Tru e)
module . exit_json ( changed = Fals e)
# Remove any attached policies otherwise deletion fails
# Check mode means we would remove this user
try :
if module . check_mode :
for policy in get_attached_policy_list ( connection , module , params [ ' UserName ' ] ) :
module . exit_json ( changed = True )
connection . detach_user_policy ( UserName = params [ ' UserName ' ] , PolicyArn = policy [ ' PolicyArn ' ] )
except ClientError as e :
module . fail_json ( msg = " Unable to detach policy {0} from user {1} : {2} " . format (
policy [ ' PolicyArn ' ] , params [ ' UserName ' ] , to_native ( e ) ) ,
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
except ParamValidationError as e :
module . fail_json ( msg = " Unable to detach policy {0} from user {1} : {2} " . format (
policy [ ' PolicyArn ' ] , params [ ' UserName ' ] , to_native ( e ) ) ,
exception = traceback . format_exc ( ) )
try :
# Remove any attached policies otherwise deletion fails
connection . delete_user ( * * params )
try :
except ClientError as e :
for policy in get_attached_policy_list ( connection , module , user_name ) :
module . fail_json ( msg = " Unable to delete user {0} : {1} " . format ( params [ ' UserName ' ] , to_native ( e ) ) ,
connection . detach_user_policy ( UserName = user_name , PolicyArn = policy [ ' PolicyArn ' ] )
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
except ( ClientError , BotoCoreError ) as e :
except ParamValidationError as e :
module . fail_json_aws ( e , msg = " Unable to delete user {0} " . format ( user_name ) )
module . fail_json ( msg = " Unable to delete user {0} : {1} " . format ( params [ ' UserName ' ] , to_native ( e ) ) ,
exception = traceback . format_exc ( ) )
else :
try :
module . exit_json ( changed = False )
# Remove user's access keys
access_keys = connection . list_access_keys ( UserName = user_name ) [ " AccessKeyMetadata " ]
for access_key in access_keys :
connection . delete_access_key ( UserName = user_name , AccessKeyId = access_key [ " AccessKeyId " ] )
# Remove user's login profile (console password)
delete_user_login_profile ( connection , module , user_name )
# Remove user's ssh public keys
ssh_public_keys = connection . list_ssh_public_keys ( UserName = user_name ) [ " SSHPublicKeys " ]
for ssh_public_key in ssh_public_keys :
connection . delete_ssh_public_key ( UserName = user_name , SSHPublicKeyId = ssh_public_key [ " SSHPublicKeyId " ] )
# Remove user's service specific credentials
service_credentials = connection . list_service_specific_credentials ( UserName = user_name ) [ " ServiceSpecificCredentials " ]
for service_specific_credential in service_credentials :
connection . delete_service_specific_credential (
UserName = user_name ,
ServiceSpecificCredentialId = service_specific_credential [ " ServiceSpecificCredentialId " ]
)
# Remove user's signing certificates
signing_certificates = connection . list_signing_certificates ( UserName = user_name ) [ " Certificates " ]
for signing_certificate in signing_certificates :
connection . delete_signing_certificate (
UserName = user_name ,
CertificateId = signing_certificate [ " CertificateId " ]
)
# Remove user's MFA devices
mfa_devices = connection . list_mfa_devices ( UserName = user_name ) [ " MFADevices " ]
for mfa_device in mfa_devices :
connection . deactivate_mfa_device ( UserName = user_name , SerialNumber = mfa_device [ " SerialNumber " ] )
# Remove user's inline policies
inline_policies = connection . list_user_policies ( UserName = user_name ) [ " PolicyNames " ]
for policy_name in inline_policies :
connection . delete_user_policy ( UserName = user_name , PolicyName = policy_name )
# Remove user's group membership
user_groups = connection . list_groups_for_user ( UserName = user_name ) [ " Groups " ]
for group in user_groups :
connection . remove_user_from_group ( UserName = user_name , GroupName = group [ " GroupName " ] )
connection . delete_user ( UserName = user_name )
except ( ClientError , BotoCoreError ) as e :
module . fail_json_aws ( e , msg = " Unable to delete user {0} " . format ( user_name ) )
module . exit_json ( changed = True )
module . exit_json ( changed = True )
@ -286,8 +320,18 @@ def get_attached_policy_list(connection, module, name):
if e . response [ ' Error ' ] [ ' Code ' ] == ' NoSuchEntity ' :
if e . response [ ' Error ' ] [ ' Code ' ] == ' NoSuchEntity ' :
return None
return None
else :
else :
module . fail_json ( msg = " Unable to get policies for user {0} : {1} " . format ( name , to_native ( e ) ) ,
module . fail_json_aws ( e , msg = " Unable to get policies for user {0} " . format ( name ) )
* * camel_dict_to_snake_dict ( e . response ) )
def delete_user_login_profile ( connection , module , user_name ) :
try :
return connection . delete_login_profile ( UserName = user_name )
except ClientError as e :
if e . response [ " Error " ] [ " Code " ] == " NoSuchEntity " :
return None
else :
module . fail_json_aws ( e , msg = " Unable to delete login profile for user {0} " . format ( user_name ) )
def main ( ) :
def main ( ) :
@ -302,7 +346,7 @@ def main():
)
)
)
)
module = Ansible Module(
module = Ansible AWS Module(
argument_spec = argument_spec ,
argument_spec = argument_spec ,
supports_check_mode = True
supports_check_mode = True
)
)