Repository: cloud-custodian/cloud-custodian

Issue:
aws | rds-cluster-snapshot tagging feature request
Request to add support for aws.rds-cluster-snapshot tag , untag and mark-for-op


Discussion:

Resolving patch:
diff --git a/c7n/resources/rdscluster.py b/c7n/resources/rdscluster.py
--- a/c7n/resources/rdscluster.py
+++ b/c7n/resources/rdscluster.py
@@ -41,124 +41,19 @@ class RDSCluster(QueryResourceManager):
     class resource_type(TypeInfo):
 
         service = 'rds'
-        arn_type = 'cluster'
-        arn_separator = ":"
+        arn = 'DBClusterArn'
         enum_spec = ('describe_db_clusters', 'DBClusters', None)
         name = id = 'DBClusterIdentifier'
         dimension = 'DBClusterIdentifier'
+        universal_taggable = True
 
-    def augment(self, dbs):
-        return list(filter(None, _rds_cluster_tags(
-            self.get_model(),
-            dbs, self.session_factory,
-            self.generate_arn, self.retry)))
+    augment = tags.universal_augment
 
 
-RDSCluster.filter_registry.register('tag-count', tags.TagCountFilter)
-RDSCluster.filter_registry.register('marked-for-op', tags.TagActionFilter)
 RDSCluster.filter_registry.register('offhour', OffHour)
 RDSCluster.filter_registry.register('onhour', OnHour)
 
 
-def _rds_cluster_tags(model, dbs, session_factory, generator, retry):
-    """Augment rds clusters with their respective tags."""
-    client = local_session(session_factory).client('rds')
-
-    def process_tags(db):
-        try:
-            db['Tags'] = retry(
-                client.list_tags_for_resource,
-                ResourceName=generator(db[model.id]))['TagList']
-            return db
-        except client.exceptions.DBClusterNotFoundFault:
-            return None
-
-    # Rds maintains a low api call limit, so this can take some time :-(
-    return list(filter(None, map(process_tags, dbs)))
-
-
-@RDSCluster.action_registry.register('mark-for-op')
-class TagDelayedAction(tags.TagDelayedAction):
-    """Mark a RDS cluster for specific custodian action
-
-    :example:
-
-    .. code-block:: yaml
-
-            policies:
-              - name: mark-for-delete
-                resource: rds-cluster
-                filters:
-                  - type: value
-                    key: default-vpc
-                    value: True
-                actions:
-                  - type: mark-for-op
-                    op: delete
-                    days: 7
-    """
-
-
-@RDSCluster.action_registry.register('tag')
-@RDSCluster.action_registry.register('mark')
-class Tag(tags.Tag):
-    """Mark/tag a RDS cluster with a key/value
-
-    :example:
-
-    .. code-block:: yaml
-
-            policies:
-              - name: rds-cluster-owner-tag
-                resource: rds-cluster
-                filters:
-                  - "tag:OwnerName": absent
-                actions:
-                  - type: tag
-                    key: OwnerName
-                    value: OwnerName
-    """
-
-    concurrency = 2
-    batch_size = 5
-    permissions = ('rds:AddTagsToResource',)
-
-    def process_resource_set(self, client, dbs, ts):
-        for db in dbs:
-            arn = self.manager.generate_arn(db['DBClusterIdentifier'])
-            client.add_tags_to_resource(ResourceName=arn, Tags=ts)
-
-
-@RDSCluster.action_registry.register('remove-tag')
-@RDSCluster.action_registry.register('unmark')
-class RemoveTag(tags.RemoveTag):
-    """Removes a tag or set of tags from RDS clusters
-
-    :example:
-
-    .. code-block:: yaml
-
-            policies:
-              - name: rds-unmark-cluster
-                resource: rds-cluster
-                filters:
-                  - "tag:ExpiredTag": present
-                actions:
-                  - type: unmark
-                    tags: ["ExpiredTag"]
-    """
-
-    concurrency = 2
-    batch_size = 5
-    permissions = ('rds:RemoveTagsFromResource',)
-
-    def process_resource_set(self, client, dbs, tag_keys):
-        for db in dbs:
-            client.remove_tags_from_resource(
-                ResourceName=self.manager.generate_arn(db['DBClusterIdentifier']),
-                TagKeys=tag_keys)
-
-
 @RDSCluster.filter_registry.register('security-group')
 class SecurityGroupFilter(net_filters.SecurityGroupFilter):
 
@@ -449,11 +344,14 @@ class RDSClusterSnapshot(QueryResourceManager):
     class resource_type(TypeInfo):
 
         service = 'rds'
-        arn_type = 'cluster-snapshot'
+        arn = 'DBClusterSnapshotArn'
         enum_spec = (
             'describe_db_cluster_snapshots', 'DBClusterSnapshots', None)
         name = id = 'DBClusterSnapshotIdentifier'
         date = 'SnapshotCreateTime'
+        universal_tagging = object()
+
+    augment = tags.universal_augment
 
 
 @RDSClusterSnapshot.filter_registry.register('age')


Test patch:
diff --git a/tests/data/placebo/test_lambda_tag_and_remove/tagging.GetResources_1.json b/tests/data/placebo/test_lambda_tag_and_remove/tagging.GetResources_1.json
--- a/tests/data/placebo/test_lambda_tag_and_remove/tagging.GetResources_1.json
+++ b/tests/data/placebo/test_lambda_tag_and_remove/tagging.GetResources_1.json
@@ -25,4 +25,4 @@
             "RetryAttempts": 0
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/data/placebo/test_modify_rds_cluster/rds.ListTagsForResource_1.json b/tests/data/placebo/test_modify_rds_cluster/rds.ListTagsForResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_modify_rds_cluster/rds.ListTagsForResource_1.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "status_code": 200,
-    "data": {
-        "TagList": [
-            {
-                "Key": "Owner",
-                "Value": "kapil"
-            }
-        ],
-        "ResponseMetadata": {
-            "RequestId": "0d409697-0534-4758-8cdc-c48aed51e17b",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "0d409697-0534-4758-8cdc-c48aed51e17b",
-                "content-type": "text/xml",
-                "content-length": "386",
-                "date": "Fri, 22 Mar 2019 06:23:20 GMT"
-            },
-            "RetryAttempts": 0
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_modify_rds_cluster/tagging.GetResources_1.json b/tests/data/placebo/test_modify_rds_cluster/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_modify_rds_cluster/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.AddTagsToResource_1.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.AddTagsToResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.AddTagsToResource_1.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "66823bbd-6bd0-11e7-b392-6379faaa3b00", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "66823bbd-6bd0-11e7-b392-6379faaa3b00", 
-                "date": "Tue, 18 Jul 2017 15:47:27 GMT", 
-                "content-length": "213", 
-                "content-type": "text/xml"
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_1.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_1.json
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_1.json
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_1.json
@@ -4,9 +4,9 @@
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "665b79d8-6bd0-11e7-b392-6379faaa3b00", 
+            "RequestId": "66cbc7cf-6bd0-11e7-8110-65c21ac11bf6", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "665b79d8-6bd0-11e7-b392-6379faaa3b00", 
+                "x-amzn-requestid": "66cbc7cf-6bd0-11e7-8110-65c21ac11bf6", 
                 "date": "Tue, 18 Jul 2017 15:47:27 GMT", 
                 "content-length": "438", 
                 "content-type": "text/xml"
@@ -19,4 +19,4 @@
             }
         ]
     }
-}
\ No newline at end of file
+}
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_2.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_2.json
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_2.json
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_2.json
@@ -4,19 +4,14 @@
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "66cbc7cf-6bd0-11e7-8110-65c21ac11bf6", 
+            "RequestId": "678ea2af-6bd0-11e7-8110-65c21ac11bf6", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "66cbc7cf-6bd0-11e7-8110-65c21ac11bf6", 
-                "date": "Tue, 18 Jul 2017 15:47:27 GMT", 
-                "content-length": "438", 
+                "x-amzn-requestid": "678ea2af-6bd0-11e7-8110-65c21ac11bf6", 
+                "date": "Tue, 18 Jul 2017 15:47:29 GMT", 
+                "content-length": "293", 
                 "content-type": "text/xml"
             }
         }, 
-        "TagList": [
-            {
-                "Value": "Resource does not meet policy: delete@2017/07/19", 
-                "Key": "custodian_next"
-            }
-        ]
+        "TagList": []
     }
 }
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_3.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_3.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_3.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "67126e28-6bd0-11e7-8bc1-657a32d20107", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "67126e28-6bd0-11e7-8bc1-657a32d20107", 
-                "date": "Tue, 18 Jul 2017 15:47:27 GMT", 
-                "content-length": "438", 
-                "content-type": "text/xml"
-            }
-        }, 
-        "TagList": [
-            {
-                "Value": "Resource does not meet policy: delete@2017/07/19", 
-                "Key": "custodian_next"
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_4.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_4.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_4.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "675e924e-6bd0-11e7-a4f7-696ce6484d55", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "675e924e-6bd0-11e7-a4f7-696ce6484d55", 
-                "date": "Tue, 18 Jul 2017 15:47:28 GMT", 
-                "content-length": "438", 
-                "content-type": "text/xml"
-            }
-        }, 
-        "TagList": [
-            {
-                "Value": "Resource does not meet policy: delete@2017/07/19", 
-                "Key": "custodian_next"
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_5.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_5.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.ListTagsForResource_5.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "678ea2af-6bd0-11e7-8110-65c21ac11bf6", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "678ea2af-6bd0-11e7-8110-65c21ac11bf6", 
-                "date": "Tue, 18 Jul 2017 15:47:29 GMT", 
-                "content-length": "293", 
-                "content-type": "text/xml"
-            }
-        }, 
-        "TagList": []
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/rds.RemoveTagsFromResource_1.json b/tests/data/placebo/test_rdscluster_mark_and_match/rds.RemoveTagsFromResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_mark_and_match/rds.RemoveTagsFromResource_1.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "678071da-6bd0-11e7-8110-65c21ac11bf6", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "678071da-6bd0-11e7-8110-65c21ac11bf6", 
-                "date": "Tue, 18 Jul 2017 15:47:29 GMT", 
-                "content-length": "223", 
-                "content-type": "text/xml"
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_2.json b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_2.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_2.json
@@ -0,0 +1,16 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResourceTagMappingList": [
+            {
+                "ResourceARN": "arn:aws:rds:us-east-2:123456789012:cluster:c7ntest",
+                "Tags": [
+		    {
+			"Value": "Resource does not meet policy: delete@2017/07/19", 
+			"Key": "custodian_next"
+		    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_3.json b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_3.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.GetResources_3.json
@@ -0,0 +1,16 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResourceTagMappingList": [
+            {
+                "ResourceARN": "arn:aws:rds:us-east-2:123456789012:cluster:c7ntest",
+                "Tags": [
+		    {
+			"Value": "Resource does not meet policy: delete@2017/07/19", 
+			"Key": "custodian_next"
+		    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/tagging.TagResources_1.json b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.TagResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.TagResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200,
+    "data": {"FailedResourcesMap": {}}
+}
diff --git a/tests/data/placebo/test_rdscluster_mark_and_match/tagging.UntagResources_1.json b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.UntagResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_mark_and_match/tagging.UntagResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200,
+    "data": {"FailedResourcesMap": {}}
+}
diff --git a/tests/data/placebo/test_rdscluster_snapshot_delete/rds.DescribeDBClusterSnapshots_1.json b/tests/data/placebo/test_rdscluster_snapshot_delete/rds.DescribeDBClusterSnapshots_1.json
--- a/tests/data/placebo/test_rdscluster_snapshot_delete/rds.DescribeDBClusterSnapshots_1.json
+++ b/tests/data/placebo/test_rdscluster_snapshot_delete/rds.DescribeDBClusterSnapshots_1.json
@@ -21,6 +21,7 @@
                 "Status": "available",
                 "PercentProgress": 100,
                 "DBClusterSnapshotIdentifier": "aaa-final-snapshot",
+		"DBClusterSnapshotArn": "arn:aws:rds:us-east-1:644160558196:cluster-snapshot:aaa-final-snapshot",
                 "KmsKeyId": "arn:aws:kms:us-east-1:123:key/k1",
                 "ClusterCreateTime": {
                     "hour": 10,
@@ -60,6 +61,7 @@
                 "LicenseModel": "aurora",
                 "Status": "available",
                 "PercentProgress": 100,
+		"DBClusterSnapshotArn": "arn:aws:rds:us-east-1:644160558196:cluster-snapshot:bbb-final-snapshot",
                 "DBClusterSnapshotIdentifier": "bbb-final-snapshot",
                 "ClusterCreateTime": {
                     "hour": 19,
diff --git a/tests/data/placebo/test_rdscluster_snapshot_delete/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_snapshot_delete/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_snapshot_delete/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_snapshot_simple/rds.DescribeDBClusterSnapshots_1.json b/tests/data/placebo/test_rdscluster_snapshot_simple/rds.DescribeDBClusterSnapshots_1.json
--- a/tests/data/placebo/test_rdscluster_snapshot_simple/rds.DescribeDBClusterSnapshots_1.json
+++ b/tests/data/placebo/test_rdscluster_snapshot_simple/rds.DescribeDBClusterSnapshots_1.json
@@ -22,6 +22,7 @@
                 "PercentProgress": 100,
                 "DBClusterSnapshotIdentifier": "aaa-final-snapshot",
                 "KmsKeyId": "arn:aws:kms:us-east-1:123:key/k1",
+		"DBClusterSnapshotArn": "arn:aws:rds:us-east-1:644160558196:cluster-snapshot:aaa-final-snapshot",
                 "ClusterCreateTime": {
                     "hour": 10,
                     "__class__": "datetime",
@@ -61,6 +62,7 @@
                 "Status": "available",
                 "PercentProgress": 100,
                 "DBClusterSnapshotIdentifier": "bbb-final-snapshot",
+		"DBClusterSnapshotArn": "arn:aws:rds:us-east-1:644160558196:cluster-snapshot:bbb-final-snapshot",
                 "ClusterCreateTime": {
                     "hour": 19,
                     "__class__": "datetime",
diff --git a/tests/data/placebo/test_rdscluster_snapshot_simple/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_snapshot_simple/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_snapshot_simple/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_start/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_start/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_start/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_stop/rds.ListTagsForResource_1.json b/tests/data/placebo/test_rdscluster_stop/rds.ListTagsForResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_stop/rds.ListTagsForResource_1.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "status_code": 200,
-    "data": {
-        "TagList": [],
-        "ResponseMetadata": {
-            "RequestId": "56fa1f76-d7f3-432a-a7c4-72dfb4f416db",
-            "HTTPStatusCode": 200,
-            "HTTPHeaders": {
-                "x-amzn-requestid": "56fa1f76-d7f3-432a-a7c4-72dfb4f416db",
-                "content-type": "text/xml",
-                "content-length": "293",
-                "date": "Thu, 21 Feb 2019 12:16:34 GMT"
-            },
-            "RetryAttempts": 0
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_stop/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_stop/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_stop/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.AddTagsToResource_1.json b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.AddTagsToResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.AddTagsToResource_1.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "c483b414-6bce-11e7-a67b-b3f0325f1236", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "c483b414-6bce-11e7-a67b-b3f0325f1236", 
-                "date": "Tue, 18 Jul 2017 15:35:45 GMT", 
-                "content-length": "213", 
-                "content-type": "text/xml"
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_1.json b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_1.json
--- a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_1.json
+++ b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_1.json
@@ -4,14 +4,19 @@
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "c45f14de-6bce-11e7-8110-65c21ac11bf6", 
+            "RequestId": "c4abfc7b-6bce-11e7-b392-6379faaa3b00", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "c45f14de-6bce-11e7-8110-65c21ac11bf6", 
+                "x-amzn-requestid": "c4abfc7b-6bce-11e7-b392-6379faaa3b00", 
                 "date": "Tue, 18 Jul 2017 15:35:45 GMT", 
-                "content-length": "293", 
+                "content-length": "390", 
                 "content-type": "text/xml"
             }
         }, 
-        "TagList": []
+        "TagList": [
+            {
+                "Value": "hello world", 
+                "Key": "xyz"
+            }
+        ]
     }
 }
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_2.json b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_2.json
--- a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_2.json
+++ b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_2.json
@@ -4,19 +4,14 @@
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "c4abfc7b-6bce-11e7-b392-6379faaa3b00", 
+            "RequestId": "c5254b38-6bce-11e7-b392-6379faaa3b00", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "c4abfc7b-6bce-11e7-b392-6379faaa3b00", 
-                "date": "Tue, 18 Jul 2017 15:35:45 GMT", 
-                "content-length": "390", 
+                "x-amzn-requestid": "c5254b38-6bce-11e7-b392-6379faaa3b00", 
+                "date": "Tue, 18 Jul 2017 15:35:46 GMT", 
+                "content-length": "293", 
                 "content-type": "text/xml"
             }
         }, 
-        "TagList": [
-            {
-                "Value": "hello world", 
-                "Key": "xyz"
-            }
-        ]
+        "TagList": []
     }
 }
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_3.json b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_3.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_3.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "c4f42912-6bce-11e7-b392-6379faaa3b00", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "c4f42912-6bce-11e7-b392-6379faaa3b00", 
-                "date": "Tue, 18 Jul 2017 15:35:46 GMT", 
-                "content-length": "390", 
-                "content-type": "text/xml"
-            }
-        }, 
-        "TagList": [
-            {
-                "Value": "hello world", 
-                "Key": "xyz"
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_4.json b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_4.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.ListTagsForResource_4.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "c5254b38-6bce-11e7-b392-6379faaa3b00", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "c5254b38-6bce-11e7-b392-6379faaa3b00", 
-                "date": "Tue, 18 Jul 2017 15:35:46 GMT", 
-                "content-length": "293", 
-                "content-type": "text/xml"
-            }
-        }, 
-        "TagList": []
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.RemoveTagsFromResource_1.json b/tests/data/placebo/test_rdscluster_tag_and_remove/rds.RemoveTagsFromResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_tag_and_remove/rds.RemoveTagsFromResource_1.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "c51a9ca9-6bce-11e7-a4f7-696ce6484d55", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "c51a9ca9-6bce-11e7-a4f7-696ce6484d55", 
-                "date": "Tue, 18 Jul 2017 15:35:47 GMT", 
-                "content-length": "223", 
-                "content-type": "text/xml"
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.GetResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200, 
+    "data": {"ResourceTagMappingList": []}
+}
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.GetResources_2.json b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.GetResources_2.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.GetResources_2.json
@@ -0,0 +1,16 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResourceTagMappingList": [
+            {
+                "ResourceARN": "arn:aws:rds:us-east-2:123456789012:cluster:c7ntest",
+                "Tags": [
+		    {
+			"Value": "hello world",
+			"Key": "xyz"
+		    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.TagResources_1.json b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.TagResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.TagResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200,
+    "data": {"FailedResourcesMap": {}}
+}
diff --git a/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.UntagResources_1.json b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.UntagResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_tag_and_remove/tagging.UntagResources_1.json
@@ -0,0 +1,4 @@
+{
+    "status_code": 200,
+    "data": {"FailedResourcesMap": {}}
+}
diff --git a/tests/data/placebo/test_rdscluster_tag_augment/rds.ListTagsForResource_1.json b/tests/data/placebo/test_rdscluster_tag_augment/rds.ListTagsForResource_1.json
deleted file mode 100644
--- a/tests/data/placebo/test_rdscluster_tag_augment/rds.ListTagsForResource_1.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "status_code": 200, 
-    "data": {
-        "ResponseMetadata": {
-            "RetryAttempts": 0, 
-            "HTTPStatusCode": 200, 
-            "RequestId": "fb11fe91-5c32-11e7-887a-3bb31b4e417f", 
-            "HTTPHeaders": {
-                "x-amzn-requestid": "fb11fe91-5c32-11e7-887a-3bb31b4e417f", 
-                "date": "Wed, 28 Jun 2017 18:52:48 GMT", 
-                "content-length": "384", 
-                "content-type": "text/xml"
-            }
-        }, 
-        "TagList": [
-            {
-                "Value": "cbar", 
-                "Key": "cfoo"
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/tests/data/placebo/test_rdscluster_tag_augment/tagging.GetResources_1.json b/tests/data/placebo/test_rdscluster_tag_augment/tagging.GetResources_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rdscluster_tag_augment/tagging.GetResources_1.json
@@ -0,0 +1,28 @@
+{
+    "status_code": 200, 
+    "data": {
+        "PaginationToken": "", 
+        "ResourceTagMappingList": [
+            {
+                "ResourceARN": "arn:aws:rds:us-east-1:644160558196:cluster:scot-test-cluster",
+                "Tags": [
+                    {
+                        "Value": "cbar", 
+                        "Key": "cfoo"
+                    }
+                ]
+            }
+        ], 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "bed27a38-9742-11e7-8210-dd0e2d1c96ab", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "bed27a38-9742-11e7-8210-dd0e2d1c96ab", 
+                "date": "Mon, 11 Sep 2017 22:44:18 GMT", 
+                "content-length": "205", 
+                "content-type": "application/x-amz-json-1.1"
+            }
+        }
+    }
+}