Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - Add compatibility with SAM models #118

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions pycfmodel/cloudformation_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2080,6 +2080,12 @@
"cloudformation:UpdateStackSet",
"cloudformation:UpdateTerminationProtection",
"cloudformation:ValidateTemplate",
"cloudfront-keyvaluestore:DeleteKey",
"cloudfront-keyvaluestore:DescribeKeyValueStore",
"cloudfront-keyvaluestore:GetKey",
"cloudfront-keyvaluestore:ListKeys",
"cloudfront-keyvaluestore:PutKey",
"cloudfront-keyvaluestore:UpdateKeys",
"cloudfront:AssociateAlias",
"cloudfront:CopyDistribution",
"cloudfront:CreateCachePolicy",
Expand Down Expand Up @@ -4536,6 +4542,7 @@
"ec2:AssociateEnclaveCertificateIamRole",
"ec2:AssociateIamInstanceProfile",
"ec2:AssociateInstanceEventWindow",
"ec2:AssociateIpamByoasn",
"ec2:AssociateIpamResourceDiscovery",
"ec2:AssociateNatGatewayAddress",
"ec2:AssociateRouteTable",
Expand Down Expand Up @@ -4732,6 +4739,7 @@
"ec2:DeleteVpnConnectionRoute",
"ec2:DeleteVpnGateway",
"ec2:DeprovisionByoipCidr",
"ec2:DeprovisionIpamByoasn",
"ec2:DeprovisionIpamPoolCidr",
"ec2:DeprovisionPublicIpv4PoolCidr",
"ec2:DeregisterImage",
Expand All @@ -4747,6 +4755,7 @@
"ec2:DescribeAwsNetworkPerformanceMetricSubscriptions",
"ec2:DescribeBundleTasks",
"ec2:DescribeByoipCidrs",
"ec2:DescribeCapacityBlockOfferings",
"ec2:DescribeCapacityReservationFleets",
"ec2:DescribeCapacityReservations",
"ec2:DescribeCarrierGateways",
Expand Down Expand Up @@ -4788,10 +4797,12 @@
"ec2:DescribeInstanceEventNotificationAttributes",
"ec2:DescribeInstanceEventWindows",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstanceTopology",
"ec2:DescribeInstanceTypeOfferings",
"ec2:DescribeInstanceTypes",
"ec2:DescribeInstances",
"ec2:DescribeInternetGateways",
"ec2:DescribeIpamByoasn",
"ec2:DescribeIpamPools",
"ec2:DescribeIpamResourceDiscoveries",
"ec2:DescribeIpamResourceDiscoveryAssociations",
Expand All @@ -4808,6 +4819,7 @@
"ec2:DescribeLocalGatewayVirtualInterfaceGroups",
"ec2:DescribeLocalGatewayVirtualInterfaces",
"ec2:DescribeLocalGateways",
"ec2:DescribeLockedSnapshots",
"ec2:DescribeManagedPrefixLists",
"ec2:DescribeMovingAddresses",
"ec2:DescribeNatGateways",
Expand Down Expand Up @@ -4901,6 +4913,7 @@
"ec2:DisableImageDeprecation",
"ec2:DisableIpamOrganizationAdminAccount",
"ec2:DisableSerialConsoleAccess",
"ec2:DisableSnapshotBlockPublicAccess",
"ec2:DisableTransitGatewayRouteTablePropagation",
"ec2:DisableVgwRoutePropagation",
"ec2:DisableVpcClassicLink",
Expand All @@ -4910,6 +4923,7 @@
"ec2:DisassociateEnclaveCertificateIamRole",
"ec2:DisassociateIamInstanceProfile",
"ec2:DisassociateInstanceEventWindow",
"ec2:DisassociateIpamByoasn",
"ec2:DisassociateIpamResourceDiscovery",
"ec2:DisassociateNatGatewayAddress",
"ec2:DisassociateRouteTable",
Expand All @@ -4931,6 +4945,7 @@
"ec2:EnableIpamOrganizationAdminAccount",
"ec2:EnableReachabilityAnalyzerOrganizationSharing",
"ec2:EnableSerialConsoleAccess",
"ec2:EnableSnapshotBlockPublicAccess",
"ec2:EnableTransitGatewayRouteTablePropagation",
"ec2:EnableVgwRoutePropagation",
"ec2:EnableVolumeIO",
Expand Down Expand Up @@ -4958,6 +4973,7 @@
"ec2:GetInstanceUefiData",
"ec2:GetIpamAddressHistory",
"ec2:GetIpamDiscoveredAccounts",
"ec2:GetIpamDiscoveredPublicAddresses",
"ec2:GetIpamDiscoveredResourceCidrs",
"ec2:GetIpamPoolAllocations",
"ec2:GetIpamPoolCidrs",
Expand All @@ -4972,6 +4988,7 @@
"ec2:GetResourcePolicy",
"ec2:GetSecurityGroupsForVpc",
"ec2:GetSerialConsoleAccessStatus",
"ec2:GetSnapshotBlockPublicAccessState",
"ec2:GetSpotPlacementScores",
"ec2:GetSubnetCidrReservations",
"ec2:GetTransitGatewayAttachmentPropagations",
Expand All @@ -4997,6 +5014,7 @@
"ec2:InjectApiError",
"ec2:ListImagesInRecycleBin",
"ec2:ListSnapshotsInRecycleBin",
"ec2:LockSnapshot",
"ec2:ModifyAddressAttribute",
"ec2:ModifyAvailabilityZoneGroup",
"ec2:ModifyCapacityReservation",
Expand Down Expand Up @@ -5066,8 +5084,10 @@
"ec2:MoveByoipCidrToIpam",
"ec2:PauseVolumeIO",
"ec2:ProvisionByoipCidr",
"ec2:ProvisionIpamByoasn",
"ec2:ProvisionIpamPoolCidr",
"ec2:ProvisionPublicIpv4PoolCidr",
"ec2:PurchaseCapacityBlock",
"ec2:PurchaseHostReservation",
"ec2:PurchaseReservedInstancesOffering",
"ec2:PurchaseScheduledInstances",
Expand Down Expand Up @@ -5127,6 +5147,7 @@
"ec2:UnassignIpv6Addresses",
"ec2:UnassignPrivateIpAddresses",
"ec2:UnassignPrivateNatGatewayAddress",
"ec2:UnlockSnapshot",
"ec2:UnmonitorInstances",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
Expand Down Expand Up @@ -7859,6 +7880,7 @@
"iotsitewise:CreateAccessPolicy",
"iotsitewise:CreateAsset",
"iotsitewise:CreateAssetModel",
"iotsitewise:CreateAssetModelCompositeModel",
"iotsitewise:CreateBulkImportJob",
"iotsitewise:CreateDashboard",
"iotsitewise:CreateGateway",
Expand All @@ -7867,14 +7889,18 @@
"iotsitewise:DeleteAccessPolicy",
"iotsitewise:DeleteAsset",
"iotsitewise:DeleteAssetModel",
"iotsitewise:DeleteAssetModelCompositeModel",
"iotsitewise:DeleteDashboard",
"iotsitewise:DeleteGateway",
"iotsitewise:DeletePortal",
"iotsitewise:DeleteProject",
"iotsitewise:DeleteTimeSeries",
"iotsitewise:DescribeAccessPolicy",
"iotsitewise:DescribeAction",
"iotsitewise:DescribeAsset",
"iotsitewise:DescribeAssetCompositeModel",
"iotsitewise:DescribeAssetModel",
"iotsitewise:DescribeAssetModelCompositeModel",
"iotsitewise:DescribeAssetProperty",
"iotsitewise:DescribeBulkImportJob",
"iotsitewise:DescribeDashboard",
Expand All @@ -7888,18 +7914,24 @@
"iotsitewise:DescribeTimeSeries",
"iotsitewise:DisassociateAssets",
"iotsitewise:DisassociateTimeSeriesFromAssetProperty",
"iotsitewise:EnableSiteWiseIntegration",
"iotsitewise:ExecuteAction",
"iotsitewise:ExecuteQuery",
"iotsitewise:GetAssetPropertyAggregates",
"iotsitewise:GetAssetPropertyValue",
"iotsitewise:GetAssetPropertyValueHistory",
"iotsitewise:GetInterpolatedAssetPropertyValues",
"iotsitewise:ListAccessPolicies",
"iotsitewise:ListActions",
"iotsitewise:ListAssetModelCompositeModels",
"iotsitewise:ListAssetModelProperties",
"iotsitewise:ListAssetModels",
"iotsitewise:ListAssetProperties",
"iotsitewise:ListAssetRelationships",
"iotsitewise:ListAssets",
"iotsitewise:ListAssociatedAssets",
"iotsitewise:ListBulkImportJobs",
"iotsitewise:ListCompositionRelationships",
"iotsitewise:ListDashboards",
"iotsitewise:ListGateways",
"iotsitewise:ListPortals",
Expand All @@ -7915,6 +7947,7 @@
"iotsitewise:UpdateAccessPolicy",
"iotsitewise:UpdateAsset",
"iotsitewise:UpdateAssetModel",
"iotsitewise:UpdateAssetModelCompositeModel",
"iotsitewise:UpdateAssetModelPropertyRouting",
"iotsitewise:UpdateAssetProperty",
"iotsitewise:UpdateDashboard",
Expand All @@ -7923,8 +7956,10 @@
"iotsitewise:UpdatePortal",
"iotsitewise:UpdateProject",
"iottwinmaker:BatchPutPropertyValues",
"iottwinmaker:CancelMetadataTransferJob",
"iottwinmaker:CreateComponentType",
"iottwinmaker:CreateEntity",
"iottwinmaker:CreateMetadataTransferJob",
"iottwinmaker:CreateScene",
"iottwinmaker:CreateSyncJob",
"iottwinmaker:CreateWorkspace",
Expand All @@ -7936,14 +7971,18 @@
"iottwinmaker:ExecuteQuery",
"iottwinmaker:GetComponentType",
"iottwinmaker:GetEntity",
"iottwinmaker:GetMetadataTransferJob",
"iottwinmaker:GetPricingPlan",
"iottwinmaker:GetPropertyValue",
"iottwinmaker:GetPropertyValueHistory",
"iottwinmaker:GetScene",
"iottwinmaker:GetSyncJob",
"iottwinmaker:GetWorkspace",
"iottwinmaker:ListComponentTypes",
"iottwinmaker:ListComponents",
"iottwinmaker:ListEntities",
"iottwinmaker:ListMetadataTransferJobs",
"iottwinmaker:ListProperties",
"iottwinmaker:ListScenes",
"iottwinmaker:ListSyncJobs",
"iottwinmaker:ListSyncResources",
Expand Down Expand Up @@ -8370,6 +8409,7 @@
"kinesis:AddTagsToStream",
"kinesis:CreateStream",
"kinesis:DecreaseStreamRetentionPeriod",
"kinesis:DeleteResourcePolicy",
"kinesis:DeleteStream",
"kinesis:DeregisterStreamConsumer",
"kinesis:DescribeLimits",
Expand All @@ -8379,6 +8419,7 @@
"kinesis:DisableEnhancedMonitoring",
"kinesis:EnableEnhancedMonitoring",
"kinesis:GetRecords",
"kinesis:GetResourcePolicy",
"kinesis:GetShardIterator",
"kinesis:IncreaseStreamRetentionPeriod",
"kinesis:ListShards",
Expand All @@ -8388,6 +8429,7 @@
"kinesis:MergeShards",
"kinesis:PutRecord",
"kinesis:PutRecords",
"kinesis:PutResourcePolicy",
"kinesis:RegisterStreamConsumer",
"kinesis:RemoveTagsFromStream",
"kinesis:SplitShard",
Expand Down Expand Up @@ -11574,6 +11616,7 @@
"redshift:CreateEventSubscription",
"redshift:CreateHsmClientCertificate",
"redshift:CreateHsmConfiguration",
"redshift:CreateRedshiftIdcApplication",
"redshift:CreateSavedQuery",
"redshift:CreateScheduledAction",
"redshift:CreateSnapshotCopyGrant",
Expand All @@ -11593,6 +11636,7 @@
"redshift:DeleteHsmClientCertificate",
"redshift:DeleteHsmConfiguration",
"redshift:DeletePartner",
"redshift:DeleteRedshiftIdcApplication",
"redshift:DeleteResourcePolicy",
"redshift:DeleteSavedQueries",
"redshift:DeleteScheduledAction",
Expand Down Expand Up @@ -11629,6 +11673,7 @@
"redshift:DescribeOrderableClusterOptions",
"redshift:DescribePartners",
"redshift:DescribeQuery",
"redshift:DescribeRedshiftIdcApplications",
"redshift:DescribeReservedNodeExchangeStatus",
"redshift:DescribeReservedNodeOfferings",
"redshift:DescribeReservedNodes",
Expand Down Expand Up @@ -11673,6 +11718,7 @@
"redshift:ModifyCustomDomainAssociation",
"redshift:ModifyEndpointAccess",
"redshift:ModifyEventSubscription",
"redshift:ModifyRedshiftIdcApplication",
"redshift:ModifySavedQuery",
"redshift:ModifyScheduledAction",
"redshift:ModifySnapshotCopyRetentionPeriod",
Expand Down
25 changes: 23 additions & 2 deletions pycfmodel/model/cf_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ class CFModel(CustomModel):

Properties:

- AWSTemplateFormatVersion
- AWSTemplateFormatVersion: The AWS CloudFormation template version that the template conforms to.
- Conditions: Conditions that control behaviour of the template.
- Description: Description for the template.
- Globals: TODO
- Mappings: A 3 level mapping of keys and associated values.
- Metadata: Additional information about the template.
- Outputs: Output values of the template.
Expand All @@ -30,11 +31,14 @@ class CFModel(CustomModel):
- Transform: For serverless applications, specifies the version of the AWS Serverless Application Model (AWS SAM) to use.

More info at [AWS Docs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html)

More info for Globals at [AWS Globals Docs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html)
"""

AWSTemplateFormatVersion: Optional[date]
Conditions: Optional[Dict] = {}
Description: Optional[str] = None
Globals: Optional[Dict] = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd create a subclass for SAM. Normal CF does not support Globals

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was one of the ideas I had in mind. I'd try to give this PR some development time this week and do a subclass instead for SAM 👍

Mappings: Optional[Dict[str, Dict[str, Dict[str, Any]]]] = {}
Metadata: Optional[Dict[str, Any]] = None
Outputs: Optional[Dict[str, Dict[str, Union[str, Dict]]]] = {}
Expand Down Expand Up @@ -84,14 +88,23 @@ def resolve(self, extra_params=None) -> "CFModel":
{key: _extended_bool(resolve(value, extended_parameters, self.Mappings, resolved_conditions))}
)

globals_cf = dict_value.pop("Globals", {})
resolved_globals = {
key: resolve(value, extended_parameters, self.Mappings, resolved_conditions)
for key, value in globals_cf.items()
}

resources = dict_value.pop("Resources")
resolved_resources = {
key: resolve(value, extended_parameters, self.Mappings, resolved_conditions)
for key, value in resources.items()
if value.get("Condition") is None
or (value.get("Condition") is not None and resolved_conditions.get(value["Condition"], True))
}
return CFModel(**dict_value, Conditions=resolved_conditions, Resources=resolved_resources)

return CFModel(
**dict_value, Conditions=resolved_conditions, Resources=resolved_resources, Globals=resolved_globals
)

def expand_actions(self) -> "CFModel":
"""
Expand Down Expand Up @@ -134,3 +147,11 @@ def resources_filtered_by_type(
if isinstance(resource, allowed_resource_classes) or resource.Type in allowed_types:
result[resource_name] = resource
return result

def is_sam_model(self) -> bool:
transform = self.Transform
if self.Transform is None:
return False
if isinstance(transform, str):
transform = [transform]
return any(macro.startswith("AWS::Serverless") for macro in transform)
Loading