diff --git a/CHANGELOG.md b/CHANGELOG.md index e9b5e1ebc..cd252b650 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,76 @@ Moto Changelog ============== +5.0.4 +----- +Docker Digest for 5.0.4: + + General: + * Lambda: The results of a Dockerless invocation can now be configured. + See http://docs.getmoto.org/en/latest/docs/services/lambda.html + + * StepFunctions can now execute the provided StepFunctionMachine (opt-in), instead of returning static data (still the default). + See http://docs.getmoto.org/en/latest/docs/services/stepfunctions.html + + New Service: + * ElastiCache: + * list_tags_for_resource() + + * ResilienceHub: + * create_app() + * create_app_version_app_component() + * create_app_version_resource() + * create_resiliency_policy() + * describe_app() + * describe_resiliency_policy() + * import_resources_to_draft_app_version() + * list_app_assessments() + * list_app_version_app_components() + * list_app_version_resources() + * list_app_versions() + * list_apps() + * list_resiliency_policies() + * list_tags_for_resource() + * publish_app_version() + * tag_resource() + * untag_resource() + + * Workspaces: + * create_tags() + * create_workspace_image() + * create_workspaces() + * deregister_workspace_directory() + * describe_client_properties() + * describe_tags() + * describe_workspace_directories() + * describe_workspace_image_permissions() + * describe_workspace_images() + * describe_workspaces() + * modify_client_properties() + * modify_selfservice_permissions() + * modify_workspace_creation_properties() + * register_workspace_directory() + * update_workspace_image_permission() + + Miscellaneous: + * APIGateway: update_usage_plan() now supports some remove-operations + * Autoscaling: describe_auto_scaling_groups() now returns a dynamic CreatedTime + * CloudFormation: Outputs now support Conditions + * CloudFormation: Outputs now return Descriptions + * CognitoIDP: admin_update_user_attributes() and admin_delete_user_attributes now correctly update the UserLastModifiedDate + * DynamoDB: query() no longer requires the LastEvaluatedKey to exist + * EC2: describe_vpc_endpoint_services() now supports all services + * Kinesis: list_streams() now returns StreamSummaries + * Lambda: get_policy() now throws an error when no statements exist + * ResourceGroupsTaggingAPI now supports DynamoDB tables + * ResourceGroupsTaggingAPI now supports SSM documents + * S3: EventBridge notifications are now supported for ObjectRestore:Post + * S3: restore_object() now contains limited validation when supplying both Days- and Type-argument + * S3: select_object_content() now supports Compressed requests and CSV responses + * SecretsManager: list_secrets() now handles negative matches correctly + * SNS: delete_endpoint() is now an idempotent operation, just like AWS + + 5.0.3 ----- Docker Digest for 5.0.3: _sha256:032d8ead42f289d9700e9bc844c6d264575ad11b3f6c22cc76d65ff638c8c7bd_ diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index a00754251..b9ffea9a2 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -2870,7 +2870,7 @@ ## elasticache
-8% implemented +9% implemented - [ ] add_tags_to_resource - [ ] authorize_cache_security_group_ingress @@ -2928,7 +2928,7 @@ - [ ] increase_node_groups_in_global_replication_group - [ ] increase_replica_count - [ ] list_allowed_node_type_modifications -- [ ] list_tags_for_resource +- [X] list_tags_for_resource - [ ] modify_cache_cluster - [ ] modify_cache_parameter_group - [ ] modify_cache_subnet_group @@ -8015,6 +8015,85 @@ - [X] update_web_acl
+## workspaces +
+20% implemented + +- [ ] associate_connection_alias +- [ ] associate_ip_groups +- [ ] associate_workspace_application +- [ ] authorize_ip_rules +- [ ] copy_workspace_image +- [ ] create_connect_client_add_in +- [ ] create_connection_alias +- [ ] create_ip_group +- [ ] create_standby_workspaces +- [X] create_tags +- [ ] create_updated_workspace_image +- [ ] create_workspace_bundle +- [X] create_workspace_image +- [X] create_workspaces +- [ ] delete_client_branding +- [ ] delete_connect_client_add_in +- [ ] delete_connection_alias +- [ ] delete_ip_group +- [ ] delete_tags +- [ ] delete_workspace_bundle +- [ ] delete_workspace_image +- [ ] deploy_workspace_applications +- [X] deregister_workspace_directory +- [ ] describe_account +- [ ] describe_account_modifications +- [ ] describe_application_associations +- [ ] describe_applications +- [ ] describe_bundle_associations +- [ ] describe_client_branding +- [X] describe_client_properties +- [ ] describe_connect_client_add_ins +- [ ] describe_connection_alias_permissions +- [ ] describe_connection_aliases +- [ ] describe_image_associations +- [ ] describe_ip_groups +- [X] describe_tags +- [ ] describe_workspace_associations +- [ ] describe_workspace_bundles +- [X] describe_workspace_directories +- [X] describe_workspace_image_permissions +- [X] describe_workspace_images +- [ ] describe_workspace_snapshots +- [X] describe_workspaces +- [ ] describe_workspaces_connection_status +- [ ] disassociate_connection_alias +- [ ] disassociate_ip_groups +- [ ] disassociate_workspace_application +- [ ] import_client_branding +- [ ] import_workspace_image +- [ ] list_available_management_cidr_ranges +- [ ] migrate_workspace +- [ ] modify_account +- [ ] modify_certificate_based_auth_properties +- [X] modify_client_properties +- [ ] modify_saml_properties +- [X] modify_selfservice_permissions +- [ ] modify_workspace_access_properties +- [X] modify_workspace_creation_properties +- [ ] modify_workspace_properties +- [ ] modify_workspace_state +- [ ] reboot_workspaces +- [ ] rebuild_workspaces +- [X] register_workspace_directory +- [ ] restore_workspace +- [ ] revoke_ip_rules +- [ ] start_workspaces +- [ ] stop_workspaces +- [ ] terminate_workspaces +- [ ] update_connect_client_add_in +- [ ] update_connection_alias_permission +- [ ] update_rules_of_ip_group +- [ ] update_workspace_bundle +- [X] update_workspace_image_permission +
+ ## Unimplemented:
@@ -8269,7 +8348,6 @@ - worklink - workmail - workmailmessageflow -- workspaces - workspaces-thin-client - workspaces-web - xray diff --git a/docs/docs/configuration/index.rst b/docs/docs/configuration/index.rst index 4718b94dc..106986b90 100644 --- a/docs/docs/configuration/index.rst +++ b/docs/docs/configuration/index.rst @@ -65,7 +65,8 @@ The following options can also be configured when running the MotoServer: options = { "batch": {"use_docker": True}, - "lambda": {"use_docker": True} + "lambda": {"use_docker": True}, + "stepfunctions": {"execute_state_machine": True} } requests.post(f"http://localhost:5000/moto-api/config", json=options) diff --git a/docs/docs/services/apigateway.rst b/docs/docs/services/apigateway.rst index 4d3797589..4a7a15239 100644 --- a/docs/docs/services/apigateway.rst +++ b/docs/docs/services/apigateway.rst @@ -155,7 +155,7 @@ apigateway The following PatchOperations are currently supported: add : Everything except /apiStages/{apidId:stageName}/throttle/ and children replace: Everything except /apiStages/{apidId:stageName}/throttle/ and children - remove : Nothing yet + remove : Everything except /apiStages/{apidId:stageName}/throttle/ and children copy : Nothing yet diff --git a/docs/docs/services/athena.rst b/docs/docs/services/athena.rst index 67f14ea67..12145c85a 100644 --- a/docs/docs/services/athena.rst +++ b/docs/docs/services/athena.rst @@ -78,7 +78,7 @@ athena ], } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/athena/query-results", + "http://motoapi.amazonaws.com/moto-api/static/athena/query-results", json=expected_results, ) assert resp.status_code == 201 diff --git a/docs/docs/services/ce.rst b/docs/docs/services/ce.rst index ace021264..ee3b41d83 100644 --- a/docs/docs/services/ce.rst +++ b/docs/docs/services/ce.rst @@ -74,7 +74,7 @@ ce ] } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/ce/cost-and-usage-results", + "http://motoapi.amazonaws.com/moto-api/static/ce/cost-and-usage-results", json=expected_results, ) assert resp.status_code == 201 diff --git a/docs/docs/services/elasticache.rst b/docs/docs/services/elasticache.rst index f11f21dfd..b250acc49 100644 --- a/docs/docs/services/elasticache.rst +++ b/docs/docs/services/elasticache.rst @@ -77,7 +77,7 @@ elasticache - [ ] increase_node_groups_in_global_replication_group - [ ] increase_replica_count - [ ] list_allowed_node_type_modifications -- [ ] list_tags_for_resource +- [X] list_tags_for_resource - [ ] modify_cache_cluster - [ ] modify_cache_parameter_group - [ ] modify_cache_subnet_group diff --git a/docs/docs/services/inspector2.rst b/docs/docs/services/inspector2.rst index ccde2b5d3..56c38f19e 100644 --- a/docs/docs/services/inspector2.rst +++ b/docs/docs/services/inspector2.rst @@ -82,7 +82,7 @@ inspector2 "region": "us-east-1", # This is the default - can be omitted } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/inspector2/findings-results", + "http://motoapi.amazonaws.com/moto-api/static/inspector2/findings-results", json=findings, ) diff --git a/docs/docs/services/lambda.rst b/docs/docs/services/lambda.rst index a4e91e2ac..40045f6e4 100644 --- a/docs/docs/services/lambda.rst +++ b/docs/docs/services/lambda.rst @@ -81,15 +81,15 @@ lambda expected_results = {"results": ["test", "test 2"], "region": "us-east-1"} resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/lambda-simple/response", - json=expected_results, - ) - + "http://motoapi.amazonaws.com/moto-api/static/lambda-simple/response", + json=expected_results + ) assert resp.status_code == 201 client = boto3.client("lambda", region_name="us-east-1") resp = client.invoke(...) # resp["Payload"].read().decode() == "test" resp = client.invoke(...) # resp["Payload"].read().decode() == "test2" + - [ ] invoke_async - [ ] invoke_with_response_stream diff --git a/docs/docs/services/rds-data.rst b/docs/docs/services/rds-data.rst index 07ec2a91f..77b72519b 100644 --- a/docs/docs/services/rds-data.rst +++ b/docs/docs/services/rds-data.rst @@ -47,7 +47,7 @@ rds-data ], } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/rds-data/statement-results", + "http://motoapi.amazonaws.com/moto-api/static/rds-data/statement-results", json=expected_results, ) assert resp.status_code == 201 diff --git a/docs/docs/services/resourcegroupstaggingapi.rst b/docs/docs/services/resourcegroupstaggingapi.rst index 8a675e343..90c46ab77 100644 --- a/docs/docs/services/resourcegroupstaggingapi.rst +++ b/docs/docs/services/resourcegroupstaggingapi.rst @@ -22,7 +22,7 @@ resourcegroupstaggingapi - [ ] start_report_creation - [X] tag_resources - Only Logs and RDS resources are currently supported + Only DynamoDB, Logs and RDS resources are currently supported - [ ] untag_resources diff --git a/docs/docs/services/s3.rst b/docs/docs/services/s3.rst index d7973040d..155e1ff07 100644 --- a/docs/docs/services/s3.rst +++ b/docs/docs/services/s3.rst @@ -114,6 +114,7 @@ s3 - 's3:ObjectCreated:Post' - 's3:ObjectCreated:Put' - 's3:ObjectDeleted' + - 's3:ObjectRestore:Post' - [X] put_bucket_ownership_controls diff --git a/docs/docs/services/sagemaker-runtime.rst b/docs/docs/services/sagemaker-runtime.rst index 68c711f83..073331ff8 100644 --- a/docs/docs/services/sagemaker-runtime.rst +++ b/docs/docs/services/sagemaker-runtime.rst @@ -42,7 +42,7 @@ sagemaker-runtime ], } requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/sagemaker/endpoint-results", + "http://motoapi.amazonaws.com/moto-api/static/sagemaker/endpoint-results", json=expected_results, ) diff --git a/docs/docs/services/workspaces.rst b/docs/docs/services/workspaces.rst new file mode 100644 index 000000000..0b57da593 --- /dev/null +++ b/docs/docs/services/workspaces.rst @@ -0,0 +1,96 @@ +.. _implementedservice_workspaces: + +.. |start-h3| raw:: html + +

+ +.. |end-h3| raw:: html + +

+ +========== +workspaces +========== + +.. autoclass:: moto.workspaces.models.WorkSpacesBackend + +|start-h3| Implemented features for this service |end-h3| + +- [ ] associate_connection_alias +- [ ] associate_ip_groups +- [ ] associate_workspace_application +- [ ] authorize_ip_rules +- [ ] copy_workspace_image +- [ ] create_connect_client_add_in +- [ ] create_connection_alias +- [ ] create_ip_group +- [ ] create_standby_workspaces +- [X] create_tags +- [ ] create_updated_workspace_image +- [ ] create_workspace_bundle +- [X] create_workspace_image +- [X] create_workspaces +- [ ] delete_client_branding +- [ ] delete_connect_client_add_in +- [ ] delete_connection_alias +- [ ] delete_ip_group +- [ ] delete_tags +- [ ] delete_workspace_bundle +- [ ] delete_workspace_image +- [ ] deploy_workspace_applications +- [X] deregister_workspace_directory + Deregister Workspace Directory with the matching ID. + +- [ ] describe_account +- [ ] describe_account_modifications +- [ ] describe_application_associations +- [ ] describe_applications +- [ ] describe_bundle_associations +- [ ] describe_client_branding +- [X] describe_client_properties +- [ ] describe_connect_client_add_ins +- [ ] describe_connection_alias_permissions +- [ ] describe_connection_aliases +- [ ] describe_image_associations +- [ ] describe_ip_groups +- [X] describe_tags +- [ ] describe_workspace_associations +- [ ] describe_workspace_bundles +- [X] describe_workspace_directories + Return info on all directories or directories with matching IDs. + +- [X] describe_workspace_image_permissions +- [X] describe_workspace_images +- [ ] describe_workspace_snapshots +- [X] describe_workspaces +- [ ] describe_workspaces_connection_status +- [ ] disassociate_connection_alias +- [ ] disassociate_ip_groups +- [ ] disassociate_workspace_application +- [ ] import_client_branding +- [ ] import_workspace_image +- [ ] list_available_management_cidr_ranges +- [ ] migrate_workspace +- [ ] modify_account +- [ ] modify_certificate_based_auth_properties +- [X] modify_client_properties +- [ ] modify_saml_properties +- [X] modify_selfservice_permissions +- [ ] modify_workspace_access_properties +- [X] modify_workspace_creation_properties +- [ ] modify_workspace_properties +- [ ] modify_workspace_state +- [ ] reboot_workspaces +- [ ] rebuild_workspaces +- [X] register_workspace_directory +- [ ] restore_workspace +- [ ] revoke_ip_rules +- [ ] start_workspaces +- [ ] stop_workspaces +- [ ] terminate_workspaces +- [ ] update_connect_client_add_in +- [ ] update_connection_alias_permission +- [ ] update_rules_of_ip_group +- [ ] update_workspace_bundle +- [X] update_workspace_image_permission + diff --git a/moto/athena/models.py b/moto/athena/models.py index 327405c4f..b78a0bf06 100644 --- a/moto/athena/models.py +++ b/moto/athena/models.py @@ -259,7 +259,7 @@ class AthenaBackend(BaseBackend): ], } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/athena/query-results", + "http://motoapi.amazonaws.com/moto-api/static/athena/query-results", json=expected_results, ) assert resp.status_code == 201 diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py index 37e9c4c1f..aeefc988b 100644 --- a/moto/awslambda/models.py +++ b/moto/awslambda/models.py @@ -2375,6 +2375,26 @@ class LambdaBackend(BaseBackend): ) -> Optional[Union[str, bytes]]: """ Invoking a Function with PackageType=Image is not yet supported. + + Invoking a Funcation against Lambda without docker now supports customised responses, the default being `Simple Lambda happy path OK`. + You can use a dedicated API to override this, by configuring a queue of expected results. + + A request to `invoke` will take the first result from that queue. + + Configure this queue by making an HTTP request to `/moto-api/static/lambda-simple/response`. An example invocation looks like this: + + .. sourcecode:: python + + expected_results = {"results": ["test", "test 2"], "region": "us-east-1"} + resp = requests.post( + "http://motoapi.amazonaws.com/moto-api/static/lambda-simple/response", + json=expected_results + ) + assert resp.status_code == 201 + + client = boto3.client("lambda", region_name="us-east-1") + resp = client.invoke(...) # resp["Payload"].read().decode() == "test" + resp = client.invoke(...) # resp["Payload"].read().decode() == "test2" """ fn = self.get_function(function_name, qualifier) payload = fn.invoke(body, headers, response_headers) diff --git a/moto/awslambda_simple/models.py b/moto/awslambda_simple/models.py index 12381a98c..536082b7e 100644 --- a/moto/awslambda_simple/models.py +++ b/moto/awslambda_simple/models.py @@ -23,7 +23,7 @@ class LambdaSimpleBackend(LambdaBackend): headers: Any, response_headers: Any, ) -> Optional[Union[str, bytes]]: - default_result = "Simple Lambda happy path OK" + default_result = body or "Simple Lambda happy path OK" if self.lambda_simple_results_queue: default_result = self.lambda_simple_results_queue.pop(0) return str.encode(default_result) diff --git a/moto/ce/models.py b/moto/ce/models.py index add58e3c0..6bba495c1 100644 --- a/moto/ce/models.py +++ b/moto/ce/models.py @@ -191,7 +191,7 @@ class CostExplorerBackend(BaseBackend): ] } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/ce/cost-and-usage-results", + "http://motoapi.amazonaws.com/moto-api/static/ce/cost-and-usage-results", json=expected_results, ) assert resp.status_code == 201 diff --git a/moto/inspector2/models.py b/moto/inspector2/models.py index 53de199c8..f2e797e11 100644 --- a/moto/inspector2/models.py +++ b/moto/inspector2/models.py @@ -196,7 +196,7 @@ class Inspector2Backend(BaseBackend): "region": "us-east-1", # This is the default - can be omitted } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/inspector2/findings-results", + "http://motoapi.amazonaws.com/moto-api/static/inspector2/findings-results", json=findings, ) diff --git a/moto/rdsdata/models.py b/moto/rdsdata/models.py index 17ad7453f..ae0c32c22 100644 --- a/moto/rdsdata/models.py +++ b/moto/rdsdata/models.py @@ -63,7 +63,7 @@ class RDSDataServiceBackend(BaseBackend): ], } resp = requests.post( - "http://motoapi.amazonaws.com:5000/moto-api/static/rds-data/statement-results", + "http://motoapi.amazonaws.com/moto-api/static/rds-data/statement-results", json=expected_results, ) assert resp.status_code == 201 diff --git a/moto/s3/models.py b/moto/s3/models.py index af925ebf3..b4ef6cc2a 100644 --- a/moto/s3/models.py +++ b/moto/s3/models.py @@ -2379,6 +2379,7 @@ class S3Backend(BaseBackend, CloudWatchMetricProvider): - 's3:ObjectCreated:Post' - 's3:ObjectCreated:Put' - 's3:ObjectDeleted' + - 's3:ObjectRestore:Post' """ bucket = self.get_bucket(bucket_name) bucket.set_notification_configuration(notification_config) diff --git a/tests/test_awslambda_simple/test_lambda_simple.py b/tests/test_awslambda_simple/test_lambda_simple.py index be4454c28..5232dfa60 100644 --- a/tests/test_awslambda_simple/test_lambda_simple.py +++ b/tests/test_awslambda_simple/test_lambda_simple.py @@ -41,6 +41,13 @@ def test_run_function_no_log(): # Execute result = client.invoke(FunctionName=FUNCTION_NAME, Payload=json.dumps(payload)) + # Verify + assert result["StatusCode"] == 200 + assert json.loads(result["Payload"].read().decode("utf-8")) == payload + + # Execute + result = client.invoke(FunctionName=FUNCTION_NAME) + # Verify assert result["StatusCode"] == 200 assert result["Payload"].read().decode("utf-8") == "Simple Lambda happy path OK"