Skip to content

Commit

Permalink
Prep Release 4.1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
bblommers committed Apr 10, 2023
1 parent 54b2fc5 commit b553c49
Show file tree
Hide file tree
Showing 121 changed files with 361 additions and 16 deletions.
70 changes: 70 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,75 @@
Moto Changelog
==============

4.1.7
-----
Docker Digest for 4.1.7: <autopopulateddigest>

New Services:
* LakeFormation:
* batch_grant_permissions()
* batch_revoke_permissions()
* create_lf_tag()
* delete_lf_tag()
* deregister_resource()
* describe_resource()
* get_data_lake_settings()
* get_lf_tag()
* grant_permissions()
* list_data_cells_filter()
* list_lf_tags()
* list_permissions()
* list_resources()
* put_data_lake_settings()
* register_resource()
* revoke_permissions()
* RDS Data:
* execute_statement()
* Scheduler:
* create_schedule()
* create_schedule_group()
* delete_schedule()
* delete_schedule_group()
* get_schedule()
* get_schedule_group()
* list_schedule_groups()
* list_schedules()
* list_tags_for_resource()
* tag_resource()
* untag_resource()
* update_schedule()

New Methods:
* Config:
* delete_retention_configuration()
* describe_retention_configurations()
* put_retention_configuration()
* EC2:
* get_launch_template_data()
* RDS:
* create_db_cluster_parameter_group()
* create_global_cluster()
* delete_db_cluster_parameter_group()
* delete_global_cluster()
* describe_db_cluster_parameter_groups()
* describe_db_cluster_parameters()
* describe_db_subnet_groups()
* describe_global_clusters()
* promote_read_replica_db_cluster()
* remove_from_global_cluster()

Miscellaneous:
* APIGateway now allows semicolons in paths
* CloudFormation now supports Fn::ToJsonString
* DynamoDB: update_item() now supports number-sets in the AttributeUpdates-parameter
* DynamoDB: query() - The KeyConditionExpression now allows enclosing the sort key condition in brackets
* EC2: assign_private_ip_addresses() now supports the PrivateIpAddresses-argument
* ECR: put_image() now supports the imageManifestMediaType parameter
* ECS: run_task() now validates the provided launch-type
* Logs: put_subscription_filter() now supports KinesisStream destinations
* RDS: describe_db_clusters() now supports filtering by db-cluster-id and engine
* S3: head_object() now returns the AcceptRanges header
* SQS: Improvements in the deduplication-logic

4.1.6
-----
Expand Down Expand Up @@ -30,6 +99,7 @@ Docker Digest for 4.1.6: _sha256:36122dca33cb8f70d84734d1a0a6a5931f7a533fab3c58e
delete_rule(), describe_rule(), disable_rule(), enable_rule(), list_rule_names_by_target(), list_rules(), list_targets_by_rule()
* RDS: describe_db_clusters() now accepts an ARN as identifier
* RDS: describe_db_snapshots() now returns the TagList-attribute
* RDS: describe_db_clusters() now returns the parameters KmsKeyId, NetworkType, DBSubnetGroupName, ScalingConfiguration
* S3: get_object() now returns the AcceptRanges header
* S3: head_bucket() now returns the region-header
* SecretsManager now supports partial ARN's
Expand Down
5 changes: 5 additions & 0 deletions CLOUDFORMATION_COVERAGE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Supported CloudFormation resources

A list of all resources that can be created via CloudFormation.
Please let us know if you'd like support for a resource not yet listed here.

- AWS::ApiGateway::Deployment:
- [x] create implemented
- [ ] update implemented
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ implementation_coverage:
git commit IMPLEMENTATION_COVERAGE.md -m "Updating implementation coverage" || true

cloudformation_coverage:
./scripts/cloudformation_coverage.py > CLOUDFORMATION_COVERAGE.md
./scripts/cloudformation_coverage.py
git commit CLOUDFORMATION_COVERAGE.md -m "Updating CloudFormation coverage" || true

coverage: implementation_coverage cloudformation_coverage
Expand Down
193 changes: 193 additions & 0 deletions docs/docs/services/cf.rst

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/docs/services/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ Note that you can mock multiple services at the same time:
:maxdepth: 1
:glob:

*
implemented/*
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Additional Resources
:caption: Implemented Services

docs/services/index
docs/services/cf
docs/services/patching_other_services

.. toctree::
Expand Down
100 changes: 88 additions & 12 deletions scripts/cloudformation_coverage.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
#!/usr/bin/env python
import importlib
import json
import mock
from unittest.mock import patch
import requests
import os

import moto

# Populate CloudFormationModel.__subclasses__()
moto.mock_all()


script_dir = os.path.dirname(os.path.abspath(__file__))


def check(condition):
if bool(condition):
return "x"
else:
return " "


def utf_checkbox(condition):
return "☑" if bool(condition) else " "


def is_implemented(model, method_name):
# method_name in model.__dict__ will be True if the method
# exists on the model and False if it's only inherited from
Expand Down Expand Up @@ -73,7 +79,7 @@ def missing_attrs(self):
for attr in self.expected_attrs:
try:
# TODO: Change the actual abstract method to return False
with mock.patch(
with patch(
"moto.core.common_models.CloudFormationModel.has_cfn_attr",
return_value=False,
):
Expand All @@ -96,16 +102,86 @@ def deletable(self):
return is_implemented(self.moto_model, "delete_from_cloudformation_json")


def write_main_document(supported):
implementation_coverage_file = "{}/../CLOUDFORMATION_COVERAGE.md".format(script_dir)
try:
os.remove(implementation_coverage_file)
except OSError:
pass

print("Writing to {}".format(implementation_coverage_file))
with open(implementation_coverage_file, "w+") as file:
file.write("## Supported CloudFormation resources")
file.write("\n\n")
file.write("A list of all resources that can be created via CloudFormation. \n")
file.write("Please let us know if you'd like support for a resource not yet listed here.")
file.write("\n\n")

for checklist in supported:
file.write(str(checklist))
file.write("\n")


def write_documentation(supported):
docs_file = "{}/../docs/docs/services/cf.rst".format(script_dir)
try:
os.remove(docs_file)
except OSError:
pass

print("Writing to {}".format(docs_file))
with open(docs_file, "w+") as file:
file.write(f".. _cloudformation_resources:\n")
file.write("\n")
file.write("==================================\n")
file.write("Supported CloudFormation resources\n")
file.write("==================================\n")
file.write("\n\n")
file.write("A list of all resources that can be created via CloudFormation. \n")
file.write("Please let us know if you'd like support for a resource not yet listed here.")
file.write("\n\n")

max_resource_name_length = max([len(cf.resource_name) for cf in supported]) + 2
max_fn_att_length = 35

file.write(".. table:: \n\n")
file.write(f" +{('-'*max_resource_name_length)}+--------+--------+--------+{('-' * max_fn_att_length)}+\n")
file.write(f" |{(' '*max_resource_name_length)}| Create | Update | Delete | {('Fn::GetAtt'.ljust(max_fn_att_length-2))} |\n")
file.write(f" +{('='*max_resource_name_length)}+========+========+========+{('=' * max_fn_att_length)}+\n")

for checklist in supported:
attrs = [f" - [{check(att not in checklist.missing_attrs)}] {att}" for att in checklist.expected_attrs]
first_attr = attrs[0] if attrs else ""
file.write(" |")
file.write(checklist.resource_name.ljust(max_resource_name_length))
file.write("|")
file.write(f" {check(checklist.creatable)} ")
file.write("|")
file.write(f" {check(checklist.updatable)} ")
file.write("|")
file.write(f" {check(checklist.deletable)} ")
file.write(f"|{first_attr.ljust(max_fn_att_length)}|")
file.write("\n")
for index, attr in enumerate(attrs[1:]):
if index % 2 == 0:
file.write(
f" +{('-' * max_resource_name_length)}+--------+--------+--------+{attr.ljust(max_fn_att_length)}|\n")
else:
file.write(
f" |{(' ' * max_resource_name_length)}| | | |{attr.ljust(max_fn_att_length)}|\n")
if len(attrs) > 1 and len(attrs) % 2 == 0:
file.write(f" |{(' ' * max_resource_name_length)}| | | |{(' ' * max_fn_att_length)}|\n")
file.write(f" +{('-'*max_resource_name_length)}+--------+--------+--------+{('-' * max_fn_att_length)}+\n")


if __name__ == "__main__":
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
cfn_spec = requests.get(
"https://dnwj8swjjbsbt.cloudfront.net/latest/gzip/CloudFormationResourceSpecification.json"
).json()
for resource_name, schema in sorted(cfn_spec["ResourceTypes"].items()):
checklist = CloudFormationChecklist(resource_name, schema)
# Only print checklists for models that implement CloudFormationModel;
# otherwise the checklist is very long and mostly empty because there
# are so many niche AWS services and resources that moto doesn't
# implement yet.
if checklist.moto_model:
print(checklist)
# Only collect checklists for models that implement CloudFormationModel;
# otherwise the checklist is very long and mostly empty because there
# are so many niche AWS services and resources that moto doesn't implement yet.
supported = [CloudFormationChecklist(resource_name, schema) for resource_name, schema in sorted(cfn_spec["ResourceTypes"].items()) if CloudFormationChecklist(resource_name, schema).moto_model]
#write_main_document(supported)
write_documentation(supported)
4 changes: 2 additions & 2 deletions scripts/implementation_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def write_implementation_coverage_to_docs(coverage):
not_implemented = coverage.get(service_name)["not_implemented"]
operations = sorted(list(implemented.keys()) + not_implemented)

service_coverage_file = "{}/../docs/docs/services/{}.rst".format(script_dir, service_name)
service_coverage_file = "{}/../docs/docs/services/implemented/{}.rst".format(script_dir, service_name)
shorthand = service_name.replace(" ", "_")

with open(service_coverage_file, "w+") as file:
Expand Down Expand Up @@ -276,7 +276,7 @@ def test_{coverage[service_name]['name'][5:]}_behaviour:
file.write(" :maxdepth: 1\n")
file.write(" :glob:\n")
file.write("\n")
file.write(" *\n")
file.write(" implemented/*\n")


if __name__ == "__main__":
Expand Down

0 comments on commit b553c49

Please sign in to comment.