106106 ScheduleKeyDeletionResponse ,
107107 SignRequest ,
108108 SignResponse ,
109+ Tag ,
110+ TagKeyList ,
111+ TagList ,
109112 TagResourceRequest ,
110113 UnsupportedOperationException ,
111114 UntagResourceRequest ,
@@ -389,6 +392,20 @@ def _parse_key_id(key_id_or_arn: str, context: RequestContext) -> tuple[str, str
389392 def _is_rsa_spec (key_spec : str ) -> bool :
390393 return key_spec in [KeySpec .RSA_2048 , KeySpec .RSA_3072 , KeySpec .RSA_4096 ]
391394
395+ # These tagging methods are overwritten in the Pro implementation.
396+ def _get_key_tags (self , key : KmsKey , account_id : str , region : str ) -> TagList :
397+ return [Tag (TagKey = key , TagValue = value ) for key , value in key .tags .items ()]
398+
399+ def _set_key_tags (self , key : KmsKey , account_id : str , region : str , tags : TagList ) -> None :
400+ return
401+
402+ def _remove_key_tags (
403+ self , key : KmsKey , account_id : str , region : str , tag_keys : TagKeyList
404+ ) -> None :
405+ # AWS doesn't seem to mind removal of a non-existent tag, so we do not raise any exception.
406+ for tag_key in tag_keys :
407+ key .tags .pop (tag_key , None )
408+
392409 #
393410 # Operation Handlers
394411 #
@@ -400,6 +417,7 @@ def create_key(
400417 request : CreateKeyRequest = None ,
401418 ) -> CreateKeyResponse :
402419 key = self ._create_kms_key (context .account_id , context .region , request )
420+ self ._set_key_tags (key , context .account_id , context .region , request .get ("Tags" , []))
403421 return CreateKeyResponse (KeyMetadata = key .metadata )
404422
405423 @handler ("ScheduleKeyDeletion" , expand = False )
@@ -1466,15 +1484,15 @@ def list_resource_tags(
14661484 key = self ._get_kms_key (
14671485 context .account_id , context .region , request .get ("KeyId" ), any_key_state_allowed = True
14681486 )
1469- keys_list = PaginatedList (
1470- [{"TagKey" : tag_key , "TagValue" : tag_value } for tag_key , tag_value in key .tags .items ()]
1471- )
1487+ keys_list = PaginatedList (self ._get_key_tags (key , context .account_id , context .region ))
14721488 page , next_token = keys_list .get_page (
14731489 lambda tag : tag .get ("TagKey" ),
14741490 next_token = request .get ("Marker" ),
14751491 page_size = request .get ("Limit" , 50 ),
14761492 )
1477- kwargs = {"NextMarker" : next_token , "Truncated" : True } if next_token else {}
1493+ kwargs = (
1494+ {"NextMarker" : next_token , "Truncated" : True } if next_token else {"Truncated" : False }
1495+ )
14781496 return ListResourceTagsResponse (Tags = page , ** kwargs )
14791497
14801498 @handler ("RotateKeyOnDemand" , expand = False )
@@ -1498,29 +1516,30 @@ def rotate_key_on_demand(
14981516
14991517 @handler ("TagResource" , expand = False )
15001518 def tag_resource (self , context : RequestContext , request : TagResourceRequest ) -> None :
1519+ tags = request ["Tags" ]
15011520 key = self ._get_kms_key (
15021521 context .account_id ,
15031522 context .region ,
15041523 request .get ("KeyId" ),
15051524 enabled_key_allowed = True ,
15061525 disabled_key_allowed = True ,
15071526 )
1508- key .add_tags (request .get ("Tags" ))
1527+ key .add_tags (tags )
1528+ self ._set_key_tags (key , context .account_id , context .region , tags )
15091529
15101530 @handler ("UntagResource" , expand = False )
15111531 def untag_resource (self , context : RequestContext , request : UntagResourceRequest ) -> None :
1532+ if not (tag_keys := request .get ("TagKeys" , [])):
1533+ return
1534+
15121535 key = self ._get_kms_key (
15131536 context .account_id ,
15141537 context .region ,
15151538 request .get ("KeyId" ),
15161539 enabled_key_allowed = True ,
15171540 disabled_key_allowed = True ,
15181541 )
1519- if not request .get ("TagKeys" ):
1520- return
1521- for tag_key in request .get ("TagKeys" ):
1522- # AWS doesn't seem to mind removal of a non-existent tag, so we do not raise any exception.
1523- key .tags .pop (tag_key , None )
1542+ self ._remove_key_tags (key , context .account_id , context .region , tag_keys )
15241543
15251544 def derive_shared_secret (
15261545 self ,
0 commit comments