@ -90,6 +90,10 @@ class RpmKey(object):
state = module . params [ ' state ' ]
state = module . params [ ' state ' ]
key = module . params [ ' key ' ]
key = module . params [ ' key ' ]
self . gpg = self . module . get_bin_path ( ' gpg ' )
if not self . gpg :
self . gpg = self . module . get_bin_path ( ' gpg2 ' , required = True )
if ' :// ' in key :
if ' :// ' in key :
keyfile = self . fetch_key ( key )
keyfile = self . fetch_key ( key )
keyid = self . getkeyid ( keyfile )
keyid = self . getkeyid ( keyfile )
@ -109,13 +113,13 @@ class RpmKey(object):
else :
else :
if not keyfile :
if not keyfile :
self . module . fail_json ( msg = " When importing a key, a valid file must be given " )
self . module . fail_json ( msg = " When importing a key, a valid file must be given " )
self . import_key ( keyfile , dryrun = module . check_mode )
self . import_key ( keyfile )
if should_cleanup_keyfile :
if should_cleanup_keyfile :
self . module . cleanup ( keyfile )
self . module . cleanup ( keyfile )
module . exit_json ( changed = True )
module . exit_json ( changed = True )
else :
else :
if self . is_key_imported ( keyid ) :
if self . is_key_imported ( keyid ) :
self . drop_key ( keyid , dryrun = module . check_mode )
self . drop_key ( keyid )
module . exit_json ( changed = True )
module . exit_json ( changed = True )
else :
else :
module . exit_json ( changed = False )
module . exit_json ( changed = False )
@ -130,14 +134,15 @@ class RpmKey(object):
if not is_pubkey ( key ) :
if not is_pubkey ( key ) :
self . module . fail_json ( msg = " Not a public key: %s " % url )
self . module . fail_json ( msg = " Not a public key: %s " % url )
tmpfd , tmpname = tempfile . mkstemp ( )
tmpfd , tmpname = tempfile . mkstemp ( )
self . module . add_cleanup_file ( tmpname )
tmpfile = os . fdopen ( tmpfd , " w+b " )
tmpfile = os . fdopen ( tmpfd , " w+b " )
tmpfile . write ( key )
tmpfile . write ( key )
tmpfile . close ( )
tmpfile . close ( )
return tmpname
return tmpname
def normalize_keyid ( self , keyid ) :
def normalize_keyid ( self , keyid ) :
""" Ensure a keyid doesn ' t have a leading 0x, has leading or trailing whitespace, and make sure is low ercase"""
""" Ensure a keyid doesn ' t have a leading 0x, has leading or trailing whitespace, and make sure is upp ercase"""
ret = keyid . strip ( ) . low er( )
ret = keyid . strip ( ) . upp er( )
if ret . startswith ( ' 0x ' ) :
if ret . startswith ( ' 0x ' ) :
return ret [ 2 : ]
return ret [ 2 : ]
elif ret . startswith ( ' 0X ' ) :
elif ret . startswith ( ' 0X ' ) :
@ -146,21 +151,12 @@ class RpmKey(object):
return ret
return ret
def getkeyid ( self , keyfile ) :
def getkeyid ( self , keyfile ) :
stdout , stderr = self . execute_command ( [ self . gpg , ' --no-tty ' , ' --batch ' , ' --with-colons ' , ' --fixed-list-mode ' , keyfile ] )
gpg = self . module . get_bin_path ( ' gpg ' )
if not gpg :
gpg = self . module . get_bin_path ( ' gpg2 ' )
if not gpg :
self . module . fail_json ( msg = " rpm_key requires a command line gpg or gpg2, none found " )
stdout , stderr = self . execute_command ( [ gpg , ' --no-tty ' , ' --batch ' , ' --with-colons ' , ' --fixed-list-mode ' , ' --list-packets ' , keyfile ] )
for line in stdout . splitlines ( ) :
for line in stdout . splitlines ( ) :
line = line . strip ( )
line = line . strip ( )
if line . startswith ( ' :signature packet: ' ) :
if line . startswith ( ' pub: ' ) :
# We want just the last 8 characters of the keyid
return line . split ( ' : ' ) [ 4 ]
keyid = line . split ( ) [ - 1 ] . strip ( ) [ 8 : ]
return keyid
self . module . fail_json ( msg = " Unexpected gpg output " )
self . module . fail_json ( msg = " Unexpected gpg output " )
def is_keyid ( self , keystr ) :
def is_keyid ( self , keystr ) :
@ -168,32 +164,26 @@ class RpmKey(object):
return re . match ( ' (0x)?[0-9a-f] {8} ' , keystr , flags = re . IGNORECASE )
return re . match ( ' (0x)?[0-9a-f] {8} ' , keystr , flags = re . IGNORECASE )
def execute_command ( self , cmd ) :
def execute_command ( self , cmd ) :
rc , stdout , stderr = self . module . run_command ( cmd )
rc , stdout , stderr = self . module . run_command ( cmd , use_unsafe_shell = True )
if rc != 0 :
if rc != 0 :
self . module . fail_json ( msg = stderr )
self . module . fail_json ( msg = stderr )
return stdout , stderr
return stdout , stderr
def is_key_imported ( self , keyid ) :
def is_key_imported ( self , keyid ) :
stdout , stderr = self . execute_command ( [ self . rpm , ' -qa ' , ' gpg-pubkey ' ] )
cmd = self . rpm + ' -q gpg-pubkey --qf " % {description} " | ' + self . gpg + ' --no-tty --batch --with-colons --fixed-list-mode - '
stdout , stderr = self . execute_command ( cmd )
for line in stdout . splitlines ( ) :
for line in stdout . splitlines ( ) :
line = line . strip ( )
if keyid in line . split ( ' : ' ) [ 4 ] :
if not line :
continue
match = re . match ( ' gpg-pubkey-([0-9a-f]+)-([0-9a-f]+) ' , line )
if not match :
self . module . fail_json ( msg = " rpm returned unexpected output [ %s ] " % line )
else :
if keyid == match . group ( 1 ) :
return True
return True
return False
return False
def import_key ( self , keyfile , dryrun = False ):
def import_key ( self , keyfile ) :
if not dryrun :
if not self . module . check_mode :
self . execute_command ( [ self . rpm , ' --import ' , keyfile ] )
self . execute_command ( [ self . rpm , ' --import ' , keyfile ] )
def drop_key ( self , key , dryrun = False ) :
def drop_key ( self , key id ) :
if not dryrun :
if not self . module . check_mode :
self . execute_command ( [ self . rpm , ' --erase ' , ' --allmatches ' , " gpg-pubkey- %s " % key ] )
self . execute_command ( [ self . rpm , ' --erase ' , ' --allmatches ' , " gpg-pubkey- %s " % key id[ 8 : ] . lower ( ) ] )
def main ( ) :
def main ( ) :