Repository: cloudtools/troposphere

Issue:
Lakeformation PrincipalPermissions and Permissions incorrectly have the same ResourceProperty
[AWS::LakeFormation::Permissions Resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-resource.html) and [AWS::LakeFormation::PrincipalPermissions Resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-resource.html) have different attributes, but are treated identically in Troposphere. 

I'm guessing that [`lakeformation.PrincipalPermissions`](https://github.com/cloudtools/troposphere/blob/759496c4d2ed3fec6fcb7315b98fa9bf7e2335b2/troposphere/lakeformation.py#L212) and [`lakeformation.Permissions`](https://github.com/cloudtools/troposphere/blob/759496c4d2ed3fec6fcb7315b98fa9bf7e2335b2/troposphere/lakeformation.py#L197) should probably reference different `ResourceProperty` classes.


Discussion:

Resolving patch:
diff --git a/scripts/patches/lakeformation.py b/scripts/patches/lakeformation.py
--- a/scripts/patches/lakeformation.py
+++ b/scripts/patches/lakeformation.py
@@ -29,6 +29,17 @@
         "op": "remove",
         "path": "/PropertyTypes/AWS::LakeFormation::PrincipalPermissions.Resource/Properties/Catalog/Type",
     },
+    # Rename AWS::LakeFormation::PrincipalPermissions.Resource to AWS::LakeFormation::PrincipalPermissions.PrincipalResource
+    {
+        "op": "move",
+        "from": "/PropertyTypes/AWS::LakeFormation::PrincipalPermissions.Resource",
+        "path": "/PropertyTypes/AWS::LakeFormation::PrincipalPermissions.PrincipalResource",
+    },
+    {
+        "op": "replace",
+        "path": "/ResourceTypes/AWS::LakeFormation::PrincipalPermissions/Properties/Resource/Type",
+        "value": "PrincipalResource",
+    },
     {
         "op": "add",
         "path": "/PropertyTypes/AWS::LakeFormation::TagAssociation.Resource/Properties/Catalog/PrimitiveType",
diff --git a/troposphere/lakeformation.py b/troposphere/lakeformation.py
--- a/troposphere/lakeformation.py
+++ b/troposphere/lakeformation.py
@@ -72,114 +72,153 @@ class DataLakeSettings(AWSObject):
     }
 
 
-class DataCellsFilterResource(AWSProperty):
+class DatabaseResource(AWSProperty):
     """
-    `DataCellsFilterResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-datacellsfilterresource.html>`__
+    `DatabaseResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-tagassociation-databaseresource.html>`__
     """
 
     props: PropsDictType = {
-        "DatabaseName": (str, True),
+        "CatalogId": (str, True),
         "Name": (str, True),
-        "TableCatalogId": (str, True),
-        "TableName": (str, True),
     }
 
 
-class DataLocationResource(AWSProperty):
+class PermissionsDataLocationResource(AWSProperty):
     """
-    `DataLocationResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-datalocationresource.html>`__
+    `PermissionsDataLocationResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-datalocationresource.html>`__
+    """
+
+    props: PropsDictType = {
+        "CatalogId": (str, False),
+        "S3Resource": (str, False),
+    }
+
+
+class TableWildcard(AWSProperty):
+    """
+    `TableWildcard <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewildcard.html>`__
+    """
+
+    props: PropsDictType = {}
+
+
+class TableResource(AWSProperty):
+    """
+    `TableResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-tagassociation-tableresource.html>`__
     """
 
     props: PropsDictType = {
         "CatalogId": (str, True),
-        "ResourceArn": (str, True),
+        "DatabaseName": (str, True),
+        "Name": (str, False),
+        "TableWildcard": (TableWildcard, False),
     }
 
 
-class DatabaseResource(AWSProperty):
+class TableWithColumnsResource(AWSProperty):
     """
-    `DatabaseResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-tagassociation-databaseresource.html>`__
+    `TableWithColumnsResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-tablewithcolumnsresource.html>`__
     """
 
     props: PropsDictType = {
         "CatalogId": (str, True),
+        "ColumnNames": ([str], False),
+        "ColumnWildcard": (ColumnWildcard, False),
+        "DatabaseName": (str, True),
         "Name": (str, True),
     }
 
 
-class LFTagKeyResource(AWSProperty):
+class ResourceProperty(AWSProperty):
     """
-    `LFTagKeyResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-lftagkeyresource.html>`__
+    `ResourceProperty <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-resource.html>`__
     """
 
     props: PropsDictType = {
-        "CatalogId": (str, True),
-        "TagKey": (str, True),
-        "TagValues": ([str], True),
+        "DataLocationResource": (PermissionsDataLocationResource, False),
+        "DatabaseResource": (DatabaseResource, False),
+        "TableResource": (TableResource, False),
+        "TableWithColumnsResource": (TableWithColumnsResource, False),
     }
 
 
-class LFTag(AWSProperty):
+class Permissions(AWSObject):
     """
-    `LFTag <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-lftag.html>`__
+    `Permissions <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lakeformation-permissions.html>`__
     """
 
+    resource_type = "AWS::LakeFormation::Permissions"
+
     props: PropsDictType = {
-        "TagKey": (str, False),
-        "TagValues": ([str], False),
+        "DataLakePrincipal": (DataLakePrincipal, True),
+        "Permissions": ([str], False),
+        "PermissionsWithGrantOption": ([str], False),
+        "Resource": (ResourceProperty, True),
     }
 
 
-class LFTagPolicyResource(AWSProperty):
+class DataCellsFilterResource(AWSProperty):
     """
-    `LFTagPolicyResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-lftagpolicyresource.html>`__
+    `DataCellsFilterResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-datacellsfilterresource.html>`__
     """
 
     props: PropsDictType = {
-        "CatalogId": (str, True),
-        "Expression": ([LFTag], True),
-        "ResourceType": (str, True),
+        "DatabaseName": (str, True),
+        "Name": (str, True),
+        "TableCatalogId": (str, True),
+        "TableName": (str, True),
     }
 
 
-class TableWildcard(AWSProperty):
+class DataLocationResource(AWSProperty):
     """
-    `TableWildcard <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewildcard.html>`__
+    `DataLocationResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-datalocationresource.html>`__
     """
 
-    props: PropsDictType = {}
+    props: PropsDictType = {
+        "CatalogId": (str, True),
+        "ResourceArn": (str, True),
+    }
 
 
-class TableResource(AWSProperty):
+class LFTagKeyResource(AWSProperty):
     """
-    `TableResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-tagassociation-tableresource.html>`__
+    `LFTagKeyResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-lftagkeyresource.html>`__
     """
 
     props: PropsDictType = {
         "CatalogId": (str, True),
-        "DatabaseName": (str, True),
-        "Name": (str, False),
-        "TableWildcard": (TableWildcard, False),
+        "TagKey": (str, True),
+        "TagValues": ([str], True),
     }
 
 
-class TableWithColumnsResource(AWSProperty):
+class LFTag(AWSProperty):
     """
-    `TableWithColumnsResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-tablewithcolumnsresource.html>`__
+    `LFTag <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-lftag.html>`__
+    """
+
+    props: PropsDictType = {
+        "TagKey": (str, False),
+        "TagValues": ([str], False),
+    }
+
+
+class LFTagPolicyResource(AWSProperty):
+    """
+    `LFTagPolicyResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-lftagpolicyresource.html>`__
     """
 
     props: PropsDictType = {
         "CatalogId": (str, True),
-        "ColumnNames": ([str], False),
-        "ColumnWildcard": (ColumnWildcard, False),
-        "DatabaseName": (str, True),
-        "Name": (str, True),
+        "Expression": ([LFTag], True),
+        "ResourceType": (str, True),
     }
 
 
-class ResourceProperty(AWSProperty):
+class PrincipalResource(AWSProperty):
     """
-    `ResourceProperty <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-resource.html>`__
+    `PrincipalResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-principalpermissions-resource.html>`__
     """
 
     props: PropsDictType = {
@@ -194,21 +233,6 @@ class ResourceProperty(AWSProperty):
     }
 
 
-class Permissions(AWSObject):
-    """
-    `Permissions <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lakeformation-permissions.html>`__
-    """
-
-    resource_type = "AWS::LakeFormation::Permissions"
-
-    props: PropsDictType = {
-        "DataLakePrincipal": (DataLakePrincipal, True),
-        "Permissions": ([str], False),
-        "PermissionsWithGrantOption": ([str], False),
-        "Resource": (ResourceProperty, True),
-    }
-
-
 class PrincipalPermissions(AWSObject):
     """
     `PrincipalPermissions <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lakeformation-principalpermissions.html>`__
@@ -221,7 +245,7 @@ class PrincipalPermissions(AWSObject):
         "Permissions": ([str], True),
         "PermissionsWithGrantOption": ([str], True),
         "Principal": (DataLakePrincipal, True),
-        "Resource": (ResourceProperty, True),
+        "Resource": (PrincipalResource, True),
     }
 
 
@@ -302,14 +326,3 @@ class TagAssociation(AWSObject):
         "LFTags": ([LFTagPair], True),
         "Resource": (TagAssociationResource, True),
     }
-
-
-class PermissionsDataLocationResource(AWSProperty):
-    """
-    `PermissionsDataLocationResource <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-datalocationresource.html>`__
-    """
-
-    props: PropsDictType = {
-        "CatalogId": (str, False),
-        "S3Resource": (str, False),
-    }


Test patch: