Prep release 4.1.11 (#6367)

This commit is contained in:
Bert Blommers 2023-06-04 20:13:44 +00:00 committed by GitHub
parent 073b494113
commit 0df65a3e6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 174 additions and 70 deletions

View File

@ -2,6 +2,37 @@ Moto Changelog
==============
4.1.11
------
Docker Digest for 4.1.11: <autopopulateddigest>
New Methods:
* AppSync:
* get_introspection_schema()
* Comprehend:
* detect_key_phrases()
* detect_pii_entities()
* detect_sentiment()
Miscellaneous:
* EC2: describe_key_pairs() now returns the CreateTime-attribute
* EC2: describe_spot_fleet_requests() now returns the Tags-attribute
* ECR: put_image(): now behaves correctly on duplicate images with duplicate tags
* Organizations: create_policy() now supports the Tags-parameter
* RDS: creation times of all objects are now in UTC
* RDS: creation times of all objects are now in UTC
* S3: Bucket names are now global, meaning they have to be unique across accounts
* S3: select_object_content() now supports None-values
* S3: select_object_content() now supports nested FROM-clauses (from x.y as xy)
* SecretsManager - update_secret() now supports the Description-parameter
* SNS now returns the correct error message for non-existing topics
* SNS: Topics are no longer accessible across regions (only across accounts)
* SNS: delete_topic() is now idempotent and no longer throws an error for non-existent topics
* SQS: Requests and responses in JSON-format are now supported
* SSM: MaintenanceWindows now have tagging support
4.1.10
------
Docker Digest for 4.1.10: _sha256:095d1dfadc71b4c68f05240129a32acf6dd7ba722c78afd4f01d8c7c3af0ebb4_

View File

@ -301,9 +301,11 @@
## appsync
<details>
<summary>29% implemented</summary>
<summary>25% implemented</summary>
- [ ] associate_api
- [ ] associate_merged_graphql_api
- [ ] associate_source_graphql_api
- [ ] create_api_cache
- [X] create_api_key
- [ ] create_data_source
@ -321,6 +323,8 @@
- [ ] delete_resolver
- [ ] delete_type
- [ ] disassociate_api
- [ ] disassociate_merged_graphql_api
- [ ] disassociate_source_graphql_api
- [ ] evaluate_code
- [ ] evaluate_mapping_template
- [ ] flush_api_cache
@ -333,6 +337,7 @@
- [ ] get_introspection_schema
- [ ] get_resolver
- [X] get_schema_creation_status
- [ ] get_source_api_association
- [X] get_type
- [X] list_api_keys
- [ ] list_data_sources
@ -341,9 +346,12 @@
- [X] list_graphql_apis
- [ ] list_resolvers
- [ ] list_resolvers_by_function
- [ ] list_source_api_associations
- [X] list_tags_for_resource
- [ ] list_types
- [ ] list_types_by_association
- [X] start_schema_creation
- [ ] start_schema_merge
- [X] tag_resource
- [X] untag_resource
- [ ] update_api_cache
@ -353,6 +361,7 @@
- [ ] update_function
- [X] update_graphql_api
- [ ] update_resolver
- [ ] update_source_api_association
- [ ] update_type
</details>
@ -371,6 +380,7 @@
- [X] create_prepared_statement
- [ ] create_presigned_notebook_url
- [X] create_work_group
- [ ] delete_capacity_reservation
- [ ] delete_data_catalog
- [ ] delete_named_query
- [ ] delete_notebook
@ -788,7 +798,7 @@
## cloudtrail
<details>
<summary>36% implemented</summary>
<summary>34% implemented</summary>
- [X] add_tags
- [ ] cancel_query
@ -826,9 +836,11 @@
- [ ] register_organization_delegated_admin
- [X] remove_tags
- [ ] restore_event_data_store
- [ ] start_event_data_store_ingestion
- [ ] start_import
- [X] start_logging
- [ ] start_query
- [ ] stop_event_data_store_ingestion
- [ ] stop_import
- [X] stop_logging
- [ ] update_channel
@ -5030,7 +5042,7 @@
## quicksight
<details>
<summary>9% implemented</summary>
<summary>8% implemented</summary>
- [ ] cancel_ingestion
- [ ] create_account_customization
@ -5083,6 +5095,8 @@
- [ ] describe_analysis
- [ ] describe_analysis_definition
- [ ] describe_analysis_permissions
- [ ] describe_asset_bundle_export_job
- [ ] describe_asset_bundle_import_job
- [ ] describe_dashboard
- [ ] describe_dashboard_definition
- [ ] describe_dashboard_permissions
@ -5119,6 +5133,8 @@
- [ ] get_dashboard_embed_url
- [ ] get_session_embed_url
- [ ] list_analyses
- [ ] list_asset_bundle_export_jobs
- [ ] list_asset_bundle_import_jobs
- [ ] list_dashboard_versions
- [ ] list_dashboards
- [ ] list_data_sets
@ -5153,6 +5169,8 @@
- [ ] search_data_sources
- [ ] search_folders
- [ ] search_groups
- [ ] start_asset_bundle_export_job
- [ ] start_asset_bundle_import_job
- [ ] tag_resource
- [ ] untag_resource
- [ ] update_account_customization
@ -6575,11 +6593,11 @@
## sns
<details>
<summary>52% implemented</summary>
<summary>78% implemented</summary>
- [X] add_permission
- [ ] check_if_phone_number_is_opted_out
- [ ] confirm_subscription
- [X] check_if_phone_number_is_opted_out
- [X] confirm_subscription
- [X] create_platform_application
- [X] create_platform_endpoint
- [ ] create_sms_sandbox_phone_number
@ -6589,29 +6607,29 @@
- [ ] delete_sms_sandbox_phone_number
- [X] delete_topic
- [ ] get_data_protection_policy
- [ ] get_endpoint_attributes
- [ ] get_platform_application_attributes
- [ ] get_sms_attributes
- [X] get_endpoint_attributes
- [X] get_platform_application_attributes
- [X] get_sms_attributes
- [ ] get_sms_sandbox_account_status
- [X] get_subscription_attributes
- [ ] get_topic_attributes
- [X] get_topic_attributes
- [X] list_endpoints_by_platform_application
- [ ] list_origination_numbers
- [ ] list_phone_numbers_opted_out
- [X] list_phone_numbers_opted_out
- [X] list_platform_applications
- [ ] list_sms_sandbox_phone_numbers
- [X] list_subscriptions
- [ ] list_subscriptions_by_topic
- [X] list_subscriptions_by_topic
- [X] list_tags_for_resource
- [X] list_topics
- [ ] opt_in_phone_number
- [X] opt_in_phone_number
- [X] publish
- [X] publish_batch
- [ ] put_data_protection_policy
- [X] remove_permission
- [X] set_endpoint_attributes
- [ ] set_platform_application_attributes
- [ ] set_sms_attributes
- [X] set_platform_application_attributes
- [X] set_sms_attributes
- [X] set_subscription_attributes
- [ ] set_topic_attributes
- [X] subscribe
@ -7036,7 +7054,7 @@
## wafv2
<details>
<summary>23% implemented</summary>
<summary>22% implemented</summary>
- [X] associate_web_acl
- [ ] check_capacity
@ -7052,6 +7070,8 @@
- [ ] delete_regex_pattern_set
- [ ] delete_rule_group
- [X] delete_web_acl
- [ ] describe_all_managed_products
- [ ] describe_managed_products_by_vendor
- [ ] describe_managed_rule_group
- [X] disassociate_web_acl
- [ ] generate_mobile_sdk_release_url

View File

@ -28,6 +28,8 @@ appsync
|start-h3| Implemented features for this service |end-h3|
- [ ] associate_api
- [ ] associate_merged_graphql_api
- [ ] associate_source_graphql_api
- [ ] create_api_cache
- [X] create_api_key
- [ ] create_data_source
@ -45,6 +47,8 @@ appsync
- [ ] delete_resolver
- [ ] delete_type
- [ ] disassociate_api
- [ ] disassociate_merged_graphql_api
- [ ] disassociate_source_graphql_api
- [ ] evaluate_code
- [ ] evaluate_mapping_template
- [ ] flush_api_cache
@ -54,9 +58,10 @@ appsync
- [ ] get_domain_name
- [ ] get_function
- [X] get_graphql_api
- [X] get_introspection_schema
- [ ] get_introspection_schema
- [ ] get_resolver
- [X] get_schema_creation_status
- [ ] get_source_api_association
- [X] get_type
- [X] list_api_keys
@ -73,9 +78,12 @@ appsync
- [ ] list_resolvers
- [ ] list_resolvers_by_function
- [ ] list_source_api_associations
- [X] list_tags_for_resource
- [ ] list_types
- [ ] list_types_by_association
- [X] start_schema_creation
- [ ] start_schema_merge
- [X] tag_resource
- [X] untag_resource
- [ ] update_api_cache
@ -85,5 +93,6 @@ appsync
- [ ] update_function
- [X] update_graphql_api
- [ ] update_resolver
- [ ] update_source_api_association
- [ ] update_type

View File

@ -36,6 +36,7 @@ athena
- [X] create_prepared_statement
- [ ] create_presigned_notebook_url
- [X] create_work_group
- [ ] delete_capacity_reservation
- [ ] delete_data_catalog
- [ ] delete_named_query
- [ ] delete_notebook

View File

@ -67,9 +67,11 @@ cloudtrail
- [ ] register_organization_delegated_admin
- [X] remove_tags
- [ ] restore_event_data_store
- [ ] start_event_data_store_ingestion
- [ ] start_import
- [X] start_logging
- [ ] start_query
- [ ] stop_event_data_store_ingestion
- [ ] stop_import
- [X] stop_logging
- [ ] update_channel

View File

@ -78,6 +78,8 @@ quicksight
- [ ] describe_analysis
- [ ] describe_analysis_definition
- [ ] describe_analysis_permissions
- [ ] describe_asset_bundle_export_job
- [ ] describe_asset_bundle_import_job
- [ ] describe_dashboard
- [ ] describe_dashboard_definition
- [ ] describe_dashboard_permissions
@ -114,6 +116,8 @@ quicksight
- [ ] get_dashboard_embed_url
- [ ] get_session_embed_url
- [ ] list_analyses
- [ ] list_asset_bundle_export_jobs
- [ ] list_asset_bundle_import_jobs
- [ ] list_dashboard_versions
- [ ] list_dashboards
- [ ] list_data_sets
@ -165,6 +169,8 @@ quicksight
- [ ] search_data_sources
- [ ] search_folders
- [ ] search_groups
- [ ] start_asset_bundle_export_job
- [ ] start_asset_bundle_import_job
- [ ] tag_resource
- [ ] untag_resource
- [ ] update_account_customization

View File

@ -28,8 +28,12 @@ sns
|start-h3| Implemented features for this service |end-h3|
- [X] add_permission
- [x] check_if_phone_number_is_opted_out
- [x] confirm_subscription
- [X] check_if_phone_number_is_opted_out
Current implementation returns True for all numbers ending in '99'
- [X] confirm_subscription
- [X] create_platform_application
- [X] create_platform_endpoint
- [ ] create_sms_sandbox_phone_number
@ -39,22 +43,22 @@ sns
- [ ] delete_sms_sandbox_phone_number
- [X] delete_topic
- [ ] get_data_protection_policy
- [x] get_endpoint_attributes
- [x] get_platform_application_attributes
- [x] get_sms_attributes
- [X] get_endpoint_attributes
- [X] get_platform_application_attributes
- [X] get_sms_attributes
- [ ] get_sms_sandbox_account_status
- [X] get_subscription_attributes
- [x] get_topic_attributes
- [X] get_topic_attributes
- [X] list_endpoints_by_platform_application
- [ ] list_origination_numbers
- [x] list_phone_numbers_opted_out
- [X] list_phone_numbers_opted_out
- [X] list_platform_applications
- [ ] list_sms_sandbox_phone_numbers
- [X] list_subscriptions
- [x] list_subscriptions_by_topic
- [X] list_subscriptions_by_topic
- [X] list_tags_for_resource
- [X] list_topics
- [x] opt_in_phone_number
- [X] opt_in_phone_number
- [X] publish
- [X] publish_batch
@ -64,8 +68,8 @@ sns
- [ ] put_data_protection_policy
- [X] remove_permission
- [X] set_endpoint_attributes
- [x] set_platform_application_attributes
- [x] set_sms_attributes
- [X] set_platform_application_attributes
- [X] set_sms_attributes
- [X] set_subscription_attributes
- [ ] set_topic_attributes
- [X] subscribe

View File

@ -53,6 +53,8 @@ wafv2
The LockToken-parameter is not yet implemented
- [ ] describe_all_managed_products
- [ ] describe_managed_products_by_vendor
- [ ] describe_managed_rule_group
- [X] disassociate_web_acl
- [ ] generate_mobile_sdk_release_url

View File

@ -5,7 +5,7 @@ import requests
import re
from collections import OrderedDict
from typing import Any, Dict, List, Iterable, Optional, Tuple
from typing import Any, Dict, List, Iterable, Optional, Tuple, Set
from moto.core import BaseBackend, BackendDict, BaseModel, CloudFormationModel
from moto.core.utils import (
@ -76,7 +76,9 @@ class Topic(CloudFormationModel):
deduplication_id: Optional[str] = None,
) -> str:
message_id = str(mock_random.uuid4())
subscriptions, _ = self.sns_backend.list_subscriptions(self.arn)
subscriptions, _ = self.sns_backend.list_subscriptions_by_topic(
topic_arn=self.arn
)
for subscription in subscriptions:
subscription.publish(
message,
@ -418,7 +420,13 @@ class SNSBackend(BaseBackend):
service_region, zones, "sns"
)
def update_sms_attributes(self, attrs: Dict[str, str]) -> None:
def get_sms_attributes(self, filter_list: Set[str]) -> Dict[str, str]:
if len(filter_list) > 0:
return {k: v for k, v in self.sms_attributes.items() if k in filter_list}
else:
return self.sms_attributes
def set_sms_attributes(self, attrs: Dict[str, str]) -> None:
self.sms_attributes.update(attrs)
def create_topic(
@ -427,7 +435,6 @@ class SNSBackend(BaseBackend):
attributes: Optional[Dict[str, str]] = None,
tags: Optional[Dict[str, str]] = None,
) -> Topic:
if attributes is None:
attributes = {}
if attributes.get("FifoTopic") and attributes["FifoTopic"].lower() == "true":
@ -555,16 +562,18 @@ class SNSBackend(BaseBackend):
self.subscriptions.pop(subscription_arn, None)
def list_subscriptions(
self, topic_arn: Optional[str] = None, next_token: Optional[str] = None
self, next_token: Optional[str] = None
) -> Tuple[List[Subscription], Optional[int]]:
if topic_arn:
topic = self.get_topic(topic_arn)
filtered = OrderedDict(
[(sub.arn, sub) for sub in self._get_topic_subscriptions(topic)]
)
return self._get_values_nexttoken(filtered, next_token)
else:
return self._get_values_nexttoken(self.subscriptions, next_token)
return self._get_values_nexttoken(self.subscriptions, next_token)
def list_subscriptions_by_topic(
self, topic_arn: str, next_token: Optional[str] = None
) -> Tuple[List[Subscription], Optional[int]]:
topic = self.get_topic(topic_arn)
filtered = OrderedDict(
[(sub.arn, sub) for sub in self._get_topic_subscriptions(topic)]
)
return self._get_values_nexttoken(filtered, next_token)
def publish(
self,
@ -642,7 +651,7 @@ class SNSBackend(BaseBackend):
except KeyError:
raise SNSNotFoundError(f"Application with arn {arn} not found")
def set_application_attributes(
def set_platform_application_attributes(
self, arn: str, attributes: Dict[str, Any]
) -> PlatformApplication:
application = self.get_application(arn)
@ -1048,6 +1057,35 @@ class SNSBackend(BaseBackend):
)
return successful, failed
def check_if_phone_number_is_opted_out(self, number: str) -> bool:
"""
Current implementation returns True for all numbers ending in '99'
"""
return number.endswith("99")
def list_phone_numbers_opted_out(self) -> List[str]:
return self.opt_out_numbers
def opt_in_phone_number(self, number: str) -> None:
try:
self.opt_out_numbers.remove(number)
except ValueError:
pass
def confirm_subscription(self) -> None:
pass
def get_endpoint_attributes(self, arn: str) -> Dict[str, str]:
endpoint = self.get_endpoint(arn)
return endpoint.attributes
def get_platform_application_attributes(self, arn: str) -> Dict[str, str]:
application = self.get_application(arn)
return application.attributes
def get_topic_attributes(self) -> None:
pass
sns_backends = BackendDict(SNSBackend, "sns")

View File

@ -307,7 +307,7 @@ class SNSResponse(BaseResponse):
def list_subscriptions_by_topic(self) -> str:
topic_arn = self._get_param("TopicArn")
next_token = self._get_param("NextToken")
subscriptions, next_token = self.backend.list_subscriptions(
subscriptions, next_token = self.backend.list_subscriptions_by_topic(
topic_arn, next_token=next_token
)
@ -443,14 +443,14 @@ class SNSResponse(BaseResponse):
def get_platform_application_attributes(self) -> str:
arn = self._get_param("PlatformApplicationArn")
application = self.backend.get_application(arn)
attributes = self.backend.get_platform_application_attributes(arn)
if self.request_json:
return json.dumps(
{
"GetPlatformApplicationAttributesResponse": {
"GetPlatformApplicationAttributesResult": {
"Attributes": application.attributes
"Attributes": attributes
},
"ResponseMetadata": {
"RequestId": "384ac68d-3775-11df-8963-01868b7c937f"
@ -460,13 +460,13 @@ class SNSResponse(BaseResponse):
)
template = self.response_template(GET_PLATFORM_APPLICATION_ATTRIBUTES_TEMPLATE)
return template.render(application=application)
return template.render(attributes=attributes)
def set_platform_application_attributes(self) -> str:
arn = self._get_param("PlatformApplicationArn")
attributes = self._get_attributes()
self.backend.set_application_attributes(arn, attributes)
self.backend.set_platform_application_attributes(arn, attributes)
if self.request_json:
return json.dumps(
@ -589,15 +589,13 @@ class SNSResponse(BaseResponse):
def get_endpoint_attributes(self) -> Union[str, Tuple[str, Dict[str, int]]]:
arn = self._get_param("EndpointArn")
try:
endpoint = self.backend.get_endpoint(arn)
attributes = self.backend.get_endpoint_attributes(arn)
if self.request_json:
return json.dumps(
{
"GetEndpointAttributesResponse": {
"GetEndpointAttributesResult": {
"Attributes": endpoint.attributes
},
"GetEndpointAttributesResult": {"Attributes": attributes},
"ResponseMetadata": {
"RequestId": "384ac68d-3775-11df-8963-01868b7c937f"
},
@ -606,7 +604,7 @@ class SNSResponse(BaseResponse):
)
template = self.response_template(GET_ENDPOINT_ATTRIBUTES_TEMPLATE)
return template.render(endpoint=endpoint)
return template.render(attributes=attributes)
except SNSNotFoundError:
error_response = self._error("NotFound", "Endpoint does not exist")
return error_response, dict(status=404)
@ -683,7 +681,7 @@ class SNSResponse(BaseResponse):
if "key" in item and "value" in item:
result[item["key"]] = item["value"]
self.backend.update_sms_attributes(result)
self.backend.set_sms_attributes(result)
template = self.response_template(SET_SMS_ATTRIBUTES_TEMPLATE)
return template.render()
@ -694,12 +692,7 @@ class SNSResponse(BaseResponse):
if key.startswith("attributes.member.1"):
filter_list.add(value[0])
if len(filter_list) > 0:
result = {
k: v for k, v in self.backend.sms_attributes.items() if k in filter_list
}
else:
result = self.backend.sms_attributes
result = self.backend.get_sms_attributes(filter_list)
template = self.response_template(GET_SMS_ATTRIBUTES_TEMPLATE)
return template.render(attributes=result)
@ -715,21 +708,19 @@ class SNSResponse(BaseResponse):
)
return error_response, dict(status=400)
# There should be a nicer way to set if a nubmer has opted out
x = self.backend.check_if_phone_number_is_opted_out(number)
template = self.response_template(CHECK_IF_OPTED_OUT_TEMPLATE)
return template.render(opt_out=str(number.endswith("99")).lower())
return template.render(opt_out=str(x).lower())
def list_phone_numbers_opted_out(self) -> str:
numbers = self.backend.list_phone_numbers_opted_out()
template = self.response_template(LIST_OPTOUT_TEMPLATE)
return template.render(opt_outs=self.backend.opt_out_numbers)
return template.render(opt_outs=numbers)
def opt_in_phone_number(self) -> str:
number = self._get_param("phoneNumber")
try:
self.backend.opt_out_numbers.remove(number)
except ValueError:
pass
self.backend.opt_in_phone_number(number)
template = self.response_template(OPT_IN_NUMBER_TEMPLATE)
return template.render()
@ -955,10 +946,10 @@ DELETE_PLATFORM_APPLICATION_TEMPLATE = """<DeletePlatformApplicationResponse xml
GET_ENDPOINT_ATTRIBUTES_TEMPLATE = """<GetEndpointAttributesResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<GetEndpointAttributesResult>
<Attributes>
{% for attribute in endpoint.attributes %}
{% for attribute in attributes %}
<entry>
<key>{{ attribute }}</key>
<value>{{ endpoint.attributes[attribute] }}</value>
<value>{{ attributes[attribute] }}</value>
</entry>
{% endfor %}
</Attributes>
@ -994,10 +985,10 @@ LIST_ENDPOINTS_BY_PLATFORM_APPLICATION_TEMPLATE = """<ListEndpointsByPlatformApp
GET_PLATFORM_APPLICATION_ATTRIBUTES_TEMPLATE = """<GetPlatformApplicationAttributesResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<GetPlatformApplicationAttributesResult>
<Attributes>
{% for attribute in application.attributes %}
{% for attribute in attributes %}
<entry>
<key>{{ attribute }}</key>
<value>{{ application.attributes[attribute] }}</value>
<value>{{ attributes[attribute] }}</value>
</entry>
{% endfor %}
</Attributes>