Repository: getmoto/moto (python)

Issue:
Missing s3 storage class
Hello, please add missing s3 storage class GLACIER_IR in https://github.com/getmoto/moto/blob/3a7f10fece9df37a72adc4c642f26cf208256322/moto/s3/models.py#L62

Pull request:
S3 - Add Glacier IR
Fixes #5971 

Patch:
diff --git a/moto/kms/models.py b/moto/kms/models.py
index 917407699..0ce417126 100644
--- a/moto/kms/models.py
+++ b/moto/kms/models.py
@@ -374,7 +374,8 @@ class KmsBackend(BaseBackend):
         return False
 
     def add_alias(self, target_key_id, alias_name):
-        self.key_to_aliases[target_key_id].add(alias_name)
+        raw_key_id = self.get_key_id(target_key_id)
+        self.key_to_aliases[raw_key_id].add(alias_name)
 
     def delete_alias(self, alias_name):
         """Delete the alias."""
diff --git a/moto/kms/responses.py b/moto/kms/responses.py
index 8e3d595eb..b02c5cb27 100644
--- a/moto/kms/responses.py
+++ b/moto/kms/responses.py
@@ -239,7 +239,6 @@ class KmsResponse(BaseResponse):
             )
 
         self._validate_cmk_id(target_key_id)
-
         self.kms_backend.add_alias(target_key_id, alias_name)
 
         return json.dumps(None)
@@ -260,6 +259,11 @@ class KmsResponse(BaseResponse):
     def list_aliases(self):
         """https://docs.aws.amazon.com/kms/latest/APIReference/API_ListAliases.html"""
         region = self.region
+        key_id = self.parameters.get("KeyId")
+        if key_id is not None:
+            self._validate_key_id(key_id)
+            key_id = self.kms_backend.get_key_id(key_id)
+
         response_aliases = []
 
         backend_aliases = self.kms_backend.get_all_aliases()
@@ -287,6 +291,11 @@ class KmsResponse(BaseResponse):
                     }
                 )
 
+        if key_id is not None:
+            response_aliases = list(
+                filter(lambda alias: alias["TargetKeyId"] == key_id, response_aliases)
+            )
+
         return json.dumps({"Truncated": False, "Aliases": response_aliases})
 
     def create_grant(self):
diff --git a/moto/s3/models.py b/moto/s3/models.py
index 409b24174..9c6bd0b9f 100644
--- a/moto/s3/models.py
+++ b/moto/s3/models.py
@@ -53,21 +53,13 @@ from moto.s3.exceptions import (
 from .cloud_formation import cfn_to_api_encryption, is_replacement_update
 from . import notifications
 from .utils import clean_key_name, _VersionedKeyStore, undo_clean_key_name
+from .utils import ARCHIVE_STORAGE_CLASSES, STORAGE_CLASS
 from ..events.notifications import send_notification as events_send_notification
 from ..settings import get_s3_default_key_buffer_size, S3_UPLOAD_PART_MIN_SIZE
 
 MAX_BUCKET_NAME_LENGTH = 63
 MIN_BUCKET_NAME_LENGTH = 3
 UPLOAD_ID_BYTES = 43
-STORAGE_CLASS = [
-    "STANDARD",
-    "REDUCED_REDUNDANCY",
-    "STANDARD_IA",
-    "ONEZONE_IA",
-    "INTELLIGENT_TIERING",
-    "GLACIER",
-    "DEEP_ARCHIVE",
-]
 DEFAULT_TEXT_ENCODING = sys.getdefaultencoding()
 OWNER = "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"
 
@@ -2249,7 +2241,7 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider):
 
         if acl is not None:
             new_key.set_acl(acl)
-        if src_key.storage_class in "GLACIER":
+        if src_key.storage_class in ARCHIVE_STORAGE_CLASSES:
             # Object copied from Glacier object should not have expiry
             new_key.set_expiry(None)
 
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
index 205ba3c45..4cf8e7df7 100644
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -58,6 +58,7 @@ from .utils import (
     metadata_from_headers,
     parse_region_from_url,
     compute_checksum,
+    ARCHIVE_STORAGE_CLASSES,
 )
 from xml.dom import minidom
 
@@ -1311,8 +1312,8 @@ class S3Response(BaseResponse):
         if key.version_id:
             response_headers["x-amz-version-id"] = key.version_id
 
-        if key.storage_class == "GLACIER":
-            raise InvalidObjectState(storage_class="GLACIER")
+        if key.storage_class in ARCHIVE_STORAGE_CLASSES:
+            raise InvalidObjectState(storage_class=key.storage_class)
         if if_unmodified_since:
             if_unmodified_since = str_to_rfc_1123_datetime(if_unmodified_since)
             if key.last_modified.replace(microsecond=0) > if_unmodified_since:
@@ -1515,7 +1516,7 @@ class S3Response(BaseResponse):
             )
 
             if key is not None:
-                if key.storage_class in ["GLACIER", "DEEP_ARCHIVE"]:
+                if key.storage_class in ARCHIVE_STORAGE_CLASSES:
                     if key.response_dict.get(
                         "x-amz-restore"
                     ) is None or 'ongoing-request="true"' in key.response_dict.get(
@@ -2090,7 +2091,7 @@ class S3Response(BaseResponse):
             es = minidom.parseString(body).getElementsByTagName("Days")
             days = es[0].childNodes[0].wholeText
             key = self.backend.get_object(bucket_name, key_name)
-            if key.storage_class not in ["GLACIER", "DEEP_ARCHIVE"]:
+            if key.storage_class not in ARCHIVE_STORAGE_CLASSES:
                 raise InvalidObjectState(storage_class=key.storage_class)
             r = 202
             if key.expiry_date is not None:
diff --git a/moto/s3/utils.py b/moto/s3/utils.py
index d6bd84fb5..76a174978 100644
--- a/moto/s3/utils.py
+++ b/moto/s3/utils.py
@@ -24,6 +24,18 @@ user_settable_fields = {
     "content-disposition",
     "x-robots-tag",
 }
+ARCHIVE_STORAGE_CLASSES = [
+    "GLACIER",
+    "DEEP_ARCHIVE",
+    "GLACIER_IR",
+]
+STORAGE_CLASS = [
+    "STANDARD",
+    "REDUCED_REDUNDANCY",
+    "STANDARD_IA",
+    "ONEZONE_IA",
+    "INTELLIGENT_TIERING",
+] + ARCHIVE_STORAGE_CLASSES
 
 
 def bucket_name_from_url(url):


Test patch:
diff --git a/tests/test_kms/test_kms_boto3.py b/tests/test_kms/test_kms_boto3.py
index f82d56309..d04cdc919 100644
--- a/tests/test_kms/test_kms_boto3.py
+++ b/tests/test_kms/test_kms_boto3.py
@@ -281,6 +281,45 @@ def test_list_aliases():
         )
 
 
+@mock_kms
+def test_list_aliases_for_key_id():
+    region = "us-west-1"
+    client = boto3.client("kms", region_name=region)
+
+    my_alias = "alias/my-alias"
+    alias_arn = f"arn:aws:kms:{region}:{ACCOUNT_ID}:{my_alias}"
+    key_id = create_simple_key(client, description="my key")
+    client.create_alias(AliasName=my_alias, TargetKeyId=key_id)
+
+    aliases = client.list_aliases(KeyId=key_id)["Aliases"]
+    aliases.should.have.length_of(1)
+    aliases.should.contain(
+        {"AliasName": my_alias, "AliasArn": alias_arn, "TargetKeyId": key_id}
+    )
+
+
+@mock_kms
+def test_list_aliases_for_key_arn():
+    region = "us-west-1"
+    client = boto3.client("kms", region_name=region)
+    key = client.create_key()
+    key_id = key["KeyMetadata"]["KeyId"]
+    key_arn = key["KeyMetadata"]["Arn"]
+
+    id_alias = "alias/my-alias-1"
+    client.create_alias(AliasName=id_alias, TargetKeyId=key_id)
+    arn_alias = "alias/my-alias-2"
+    client.create_alias(AliasName=arn_alias, TargetKeyId=key_arn)
+
+    aliases = client.list_aliases(KeyId=key_arn)["Aliases"]
+    aliases.should.have.length_of(2)
+    for alias in [id_alias, arn_alias]:
+        alias_arn = f"arn:aws:kms:{region}:{ACCOUNT_ID}:{alias}"
+        aliases.should.contain(
+            {"AliasName": alias, "AliasArn": alias_arn, "TargetKeyId": key_id}
+        )
+
+
 @pytest.mark.parametrize(
     "key_id",
     [