* feat: add ses v2
* feat: move wrap v1 logic into v2 api
* feat: v2 api on v2 url
* chore: types
* chore: linting
* feat: raw emails
* chore: linting
* feat: add list_contacts
* fix: urls need to be explicit for this to work with moto server
* chore: linting
* chore: remodel
* chore: rework
* chore: cleanup
* chore: fix test
* chore: sort out mypy
* feat: add contact lists
* fix: new url for server mode
* feat: create and delete
* chore: linting
* chore: linting
* chore: refactor
* chore: match errors with real responses
* chore: linting
* chore: run implementation coverage script
* refactor: easier, faster look ups with dicts
* refactor: contact is now a child of contactlist
* tests: contactlists return 200 if empty, contacts do not
* chore: update botocore and run implementation coverage script
* refactor: add matching *_contact methods to backend model so coverage script can detect them
This change introduces a checklist similar to IMPLEMENTATION_COVERAGE.md
to document moto's adherence to the full CloudFormation specification.
The script (invoked via `make cloudformation_coverage`) finds any moto
models that implement `moto.core.common_models.CloudFormationModel` and
checks to see if all CRUD methods are implemented. For `has_cfn_attr`,
it also checks to see if all of the attributes exposed by `Fn::GetAtt` are
implemented. It does not check to see if `physical_resource_id` is
implemented because as far as I can tell, the published AWS spec doesn't
include that information:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
A more aggressive approach would be to remove default implementations
from all the abstract methods and allow Python to throw for any
unimplemented method. But that would obviously break a lot of things.
Instead, I think the checklist represents good documentation for users
about what they can and can't expect moto to handle when parsing their
CloudFormation templates. It also serves as a nice to-do list of small
improvements for contributors to add (and I'll likely add a few myself).
Many of these would be particularly good "first issues" for first time
contributors because in general, these methods just call existing
methods.