Repository: getmoto/moto

Issue:
resourcegroupstaggingapi does not support glue
Please add glue as an option to resourcegroupstaggingapi, specifically glue schemas which already has enough support to tag.


Discussion:

Resolving patch:
diff --git a/moto/resourcegroupstaggingapi/models.py b/moto/resourcegroupstaggingapi/models.py
--- a/moto/resourcegroupstaggingapi/models.py
+++ b/moto/resourcegroupstaggingapi/models.py
@@ -7,6 +7,7 @@
 from moto.ec2 import ec2_backends
 from moto.elb.models import elb_backends, ELBBackend
 from moto.elbv2.models import elbv2_backends, ELBv2Backend
+from moto.glue.models import glue_backends, GlueBackend
 from moto.kinesis.models import kinesis_backends, KinesisBackend
 from moto.kms.models import kms_backends, KmsBackend
 from moto.rds.models import rds_backends, RDSBackend
@@ -47,6 +48,10 @@ def elb_backend(self) -> ELBBackend:
     def elbv2_backend(self) -> ELBv2Backend:
         return elbv2_backends[self.account_id][self.region_name]
 
+    @property
+    def glue_backend(self) -> GlueBackend:
+        return glue_backends[self.account_id][self.region_name]
+
     @property
     def kinesis_backend(self) -> KinesisBackend:
         return kinesis_backends[self.account_id][self.region_name]
@@ -328,6 +333,29 @@ def format_tag_keys(
 
         # Glacier Vault
 
+        # Glue
+        if not resource_type_filters or any(
+            ("glue" in _type) for _type in resource_type_filters
+        ):
+            if not resource_type_filters or "glue" in resource_type_filters:
+                arns_starting_with = [
+                    f"arn:aws:glue:{self.region_name}:{self.account_id}:"
+                ]
+            else:
+                arns_starting_with = []
+                for resource_type in resource_type_filters:
+                    if resource_type.startswith("glue:"):
+                        glue_type = resource_type.split(":")[-1]
+                        arns_starting_with.append(
+                            f"arn:aws:glue:{self.region_name}:{self.account_id}:{glue_type}"
+                        )
+            for glue_arn in self.glue_backend.tagger.tags.keys():
+                if any(glue_arn.startswith(arn) for arn in arns_starting_with):
+                    tags = self.glue_backend.tagger.list_tags_for_resource(glue_arn)[
+                        "Tags"
+                    ]
+                    yield {"ResourceARN": glue_arn, "Tags": tags}
+
         # Kinesis
 
         # KMS
@@ -506,6 +534,11 @@ def get_ec2_keys(res_id: str) -> List[Dict[str, str]]:
             for key in get_ec2_keys(volume.id):  # type: ignore[assignment]
                 yield key
 
+        # Glue
+        for tag_dict in self.glue_backend.tagger.tags.values():
+            for tag_key in tag_dict.keys():
+                yield tag_key
+
     def _get_tag_values_generator(self, tag_key: str) -> Iterator[str]:
         # Look at
         # https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
@@ -561,6 +594,12 @@ def get_ec2_values(res_id: str) -> List[Dict[str, str]]:
             for value in get_ec2_values(volume.id):  # type: ignore[assignment]
                 yield value
 
+        # Glue
+        for tag_dict in self.glue_backend.tagger.tags.values():
+            for key, tag_value in tag_dict.items():
+                if key == tag_key and tag_value is not None:
+                    yield tag_value
+
     def get_resources(
         self,
         pagination_token: Optional[str] = None,


Test patch:
diff --git a/scripts/dependency_test.sh b/scripts/dependency_test.sh
--- a/scripts/dependency_test.sh
+++ b/scripts/dependency_test.sh
@@ -33,7 +33,7 @@ valid_service() {
   # Verify whether this is a valid service
   # We'll ignore metadata folders, and folders that test generic Moto behaviour
   # We'll also ignore CloudFormation, as it will always depend on other services
-  local ignore_moto_folders="core instance_metadata __pycache__ templates cloudformation moto_api moto_server resourcegroupstaggingapi packages utilities s3bucket_path"
+  local ignore_moto_folders="core instance_metadata __pycache__ templates cloudformation moto_api moto_server packages utilities s3bucket_path"
   if echo $ignore_moto_folders | grep -q "$1"; then
     return 1
   else
diff --git a/tests/test_resourcegroupstaggingapi/test_resourcegroupstagging_glue.py b/tests/test_resourcegroupstaggingapi/test_resourcegroupstagging_glue.py
new file mode 100644
--- /dev/null
+++ b/tests/test_resourcegroupstaggingapi/test_resourcegroupstagging_glue.py
@@ -0,0 +1,55 @@
+import boto3
+
+from moto import mock_glue, mock_resourcegroupstaggingapi
+from moto.core import DEFAULT_ACCOUNT_ID
+from uuid import uuid4
+
+
+@mock_glue
+@mock_resourcegroupstaggingapi
+def test_glue_jobs():
+    glue = boto3.client("glue", region_name="us-west-1")
+    job_name = glue.create_job(
+        Name=str(uuid4()),
+        Role="test_role",
+        Command=dict(Name="test_command"),
+        Tags={"k1": "v1"},
+    )["Name"]
+    job_arn = f"arn:aws:glue:us-west-1:{DEFAULT_ACCOUNT_ID}:job/{job_name}"
+
+    rtapi = boto3.client("resourcegroupstaggingapi", region_name="us-west-1")
+    resources = rtapi.get_resources(ResourceTypeFilters=["glue"])[
+        "ResourceTagMappingList"
+    ]
+    assert resources == [
+        {"ResourceARN": job_arn, "Tags": [{"Key": "k1", "Value": "v1"}]}
+    ]
+
+    resources = rtapi.get_resources(ResourceTypeFilters=["glue:job"])[
+        "ResourceTagMappingList"
+    ]
+    assert resources == [
+        {"ResourceARN": job_arn, "Tags": [{"Key": "k1", "Value": "v1"}]}
+    ]
+
+    resources = rtapi.get_resources(TagFilters=[{"Key": "k1", "Values": ["v1"]}])[
+        "ResourceTagMappingList"
+    ]
+    assert resources == [
+        {"ResourceARN": job_arn, "Tags": [{"Key": "k1", "Value": "v1"}]}
+    ]
+
+    resources = rtapi.get_resources(ResourceTypeFilters=["glue:table"])[
+        "ResourceTagMappingList"
+    ]
+    assert resources == []
+
+    resources = rtapi.get_resources(ResourceTypeFilters=["ec2"])[
+        "ResourceTagMappingList"
+    ]
+    assert resources == []
+
+    assert rtapi.get_tag_keys()["TagKeys"] == ["k1"]
+
+    assert rtapi.get_tag_values(Key="k1")["TagValues"] == ["v1"]
+    assert rtapi.get_tag_values(Key="unknown")["TagValues"] == []