Skip to content

Commit

Permalink
Merge branch 'master' into develop/cloudhsm-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Singha22 authored Feb 7, 2025
2 parents e08a869 + f35194d commit cbe5fad
Show file tree
Hide file tree
Showing 204 changed files with 75,020 additions and 30,082 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,8 @@ jobs:
needs: [lint]
if: "!contains(github.event.pull_request.labels.*.name, 'java')"
uses: ./.github/workflows/tests_proxymode.yml

testcdk:
needs: [lint]
if: "!contains(github.event.pull_request.labels.*.name, 'java')"
uses: ./.github/workflows/tests_cdk.yml
45 changes: 45 additions & 0 deletions .github/workflows/tests_cdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Unit tests in Server Mode
on: [workflow_call]

jobs:
cdk_start:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Start MotoServer
run: |
pip install build
python -m build
docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e MOTO_EC2_LOAD_DEFAULT_AMIS=false -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:${{ matrix.python-version }}-slim /moto/scripts/ci_moto_server.sh &
python scripts/ci_wait_for_server.py
- name: Install CDK
id: install-cdk
run: |
sudo npm install -g aws-cdk
- name: Init CDK APP
run: |
mkdir ~/.aws && touch ~/.aws/credentials && echo -e "[default]\naws_access_key_id = test\naws_secret_access_key = test" > ~/.aws/credentials
mkdir cdk_example_app
cd cdk_example_app
cdk init app --language python
source .venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Bootstrap CDK
env:
AWS_ENDPOINT_URL: "http://localhost:5000"
run: |
pwd
ls -la
cd cdk_example_app
source .venv/bin/activate
cdk bootstrap -v
2 changes: 1 addition & 1 deletion .github/workflows/tests_sdk_ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3
uses: ruby/setup-ruby@2654679fe7f7c29875c669398a8ec0791b8a64a1
with:
ruby-version: ${{ matrix.ruby-version }}
- name: Set up Python 3.8
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
Moto Changelog
==============

5.0.28
-----
Docker Digest for 5.0.28: _sha256:d3532929e4c498334949a014e9f0af6617ec1e89d92be690cd192fa3354ad7e6_

* General:
* Bootstrapping a CDK project is now supported

* New Services:
* S3 Tables:
* create_namespace()
* create_table()
* create_table_bucket()
* delete_namespace()
* delete_table()
* delete_table_bucket()
* get_metadata_location()
* get_table()
* get_table_bucket()
* list_namespaces()
* list_table_buckets()
* list_tables()
* rename_table()
* update_metadata_location()

* Miscellaneous:
* DynamoDB: delete_item() now returns ConsumedCapacity
* DynamoDB: transact_write_items() now returns a ReturnValuesOnConditionCheckFailure for all operations
* ECR: Lifecycle Policies() now support the tagPatternList-parameter
* S3: get_object() now returns the ETag when returning a 304 (Not Modified)
* SecretsManager: get_secret_value() no longer throws an error after calling rotate_secret(RotateImmediately=False)
* SecretsManager: list_secrets() now filters values with special chars correctly
* Organizations: list_roots() now returns the roots of the parent organization, if called from within a child organization


5.0.27
-----
Docker Digest for 5.0.27: _sha256:ac5312f68c6b748b667526025f9e7a8c2e4112837c258eee68f96fa36d9dbbef_
Expand Down
2 changes: 1 addition & 1 deletion moto/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from moto.core.decorator import mock_aws as mock_aws

__title__ = "moto"
__version__ = "5.0.28.dev"
__version__ = "5.0.29.dev"
17 changes: 9 additions & 8 deletions moto/apigatewayv2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import hashlib
import string
from datetime import datetime
from typing import Any, Dict, List, Optional, Union

import yaml

from moto.core.base_backend import BackendDict, BaseBackend
from moto.core.common_models import BaseModel
from moto.core.utils import unix_time
from moto.core.utils import iso_8601_datetime_without_milliseconds
from moto.moto_api._internal import mock_random as random
from moto.utilities.tagging_service import TaggingService
from moto.utilities.utils import get_partition
Expand Down Expand Up @@ -54,14 +55,14 @@ def __init__(self, api: "Api", config: Dict[str, Any]):
self.route_settings = config.get("routeSettings", {})
self.stage_variables = config.get("stageVariables", {})
self.tags = config.get("tags", {})
self.created = self.updated = unix_time()
self.created = self.updated = datetime.now()

def to_json(self) -> Dict[str, Any]:
dct = {
"stageName": self.name,
"defaultRouteSettings": self.default_route_settings,
"createdDate": self.created,
"lastUpdatedDate": self.updated,
"createdDate": iso_8601_datetime_without_milliseconds(self.created),
"lastUpdatedDate": iso_8601_datetime_without_milliseconds(self.updated),
"routeSettings": self.route_settings,
"stageVariables": self.stage_variables,
"tags": self.tags,
Expand Down Expand Up @@ -578,7 +579,7 @@ def __init__(
self.api_key_selection_expression = (
api_key_selection_expression or "$request.header.x-api-key"
)
self.created_date = unix_time()
self.created_date = datetime.now()
self.cors_configuration = cors_configuration
self.description = description
self.disable_execute_api_endpoint = disable_execute_api_endpoint or False
Expand Down Expand Up @@ -1036,7 +1037,7 @@ def to_json(self) -> Dict[str, Any]:
"apiId": self.api_id,
"apiEndpoint": self.api_endpoint,
"apiKeySelectionExpression": self.api_key_selection_expression,
"createdDate": self.created_date,
"createdDate": iso_8601_datetime_without_milliseconds(self.created_date),
"corsConfiguration": self.cors_configuration,
"description": self.description,
"disableExecuteApiEndpoint": self.disable_execute_api_endpoint,
Expand All @@ -1058,7 +1059,7 @@ def __init__(
tags: Dict[str, str],
backend: "ApiGatewayV2Backend",
):
self.created = unix_time()
self.created = datetime.now()
self.id = "".join(random.choice(string.ascii_lowercase) for _ in range(8))
self.name = name
self.sg_ids = sg_ids
Expand All @@ -1073,7 +1074,7 @@ def update(self, name: str) -> None:

def to_json(self) -> Dict[str, Any]:
return {
"createdDate": self.created,
"createdDate": iso_8601_datetime_without_milliseconds(self.created),
"name": self.name,
"securityGroupIds": self.sg_ids,
"subnetIds": self.subnet_ids,
Expand Down
42 changes: 16 additions & 26 deletions moto/appmesh/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""AppMeshBackend class with methods for supported APIs."""

from typing import Any, Dict, List, Literal, Optional, Union
from typing import Dict, List, Literal, Optional, Union

from moto.appmesh.dataclasses.mesh import (
Mesh,
Expand Down Expand Up @@ -35,7 +35,7 @@
PAGINATION_MODEL = {
"list_meshes": {
"input_token": "next_token",
"limit_key": "max_results",
"limit_key": "limit",
"limit_default": 100,
"unique_attribute": "meshName",
},
Expand All @@ -55,13 +55,13 @@
"input_token": "next_token",
"limit_key": "limit",
"limit_default": 100,
"unique_attribute": ["routeName"],
"unique_attribute": "route_name",
},
"list_virtual_nodes": {
"input_token": "next_token",
"limit_key": "limit",
"limit_default": 100,
"unique_attribute": ["virtualNodeName"],
"unique_attribute": "virtual_node_name",
},
}

Expand Down Expand Up @@ -249,8 +249,8 @@ def delete_mesh(self, mesh_name: str) -> Mesh:
del self.meshes[mesh_name]
return mesh

@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
def list_meshes(self, limit: Optional[int], next_token: Optional[str]):
@paginate(pagination_model=PAGINATION_MODEL)
def list_meshes(self) -> List[Dict[str, Union[str, int]]]:
return [
{
"arn": mesh.metadata.arn,
Expand Down Expand Up @@ -284,7 +284,7 @@ def _get_resource_with_arn(
raise ResourceNotFoundError(resource_arn)

@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
def list_tags_for_resource(self, limit: int, next_token: str, resource_arn: str):
def list_tags_for_resource(self, resource_arn: str) -> List[Dict[str, str]]:
return self._get_resource_with_arn(resource_arn=resource_arn).tags

def tag_resource(self, resource_arn: str, tags: List[Dict[str, str]]) -> None:
Expand Down Expand Up @@ -375,10 +375,10 @@ def delete_virtual_router(
del mesh.virtual_routers[virtual_router_name]
return virtual_router

@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
@paginate(pagination_model=PAGINATION_MODEL)
def list_virtual_routers(
self, limit: int, mesh_name: str, mesh_owner: Optional[str], next_token: str
):
self, mesh_name: str, mesh_owner: Optional[str]
) -> List[Dict[str, Union[str, int]]]:
self._validate_mesh(mesh_name=mesh_name, mesh_owner=mesh_owner)
return [
{
Expand Down Expand Up @@ -507,25 +507,20 @@ def delete_route(
)
return route

@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
@paginate(pagination_model=PAGINATION_MODEL)
def list_routes(
self,
limit: Optional[int],
mesh_name: str,
mesh_owner: Optional[str],
next_token: Optional[str],
virtual_router_name: str,
) -> List[Dict[str, Any]]:
) -> List[RouteMetadata]:
self._check_router_validity(
mesh_name=mesh_name,
mesh_owner=mesh_owner,
virtual_router_name=virtual_router_name,
)
virtual_router = self.meshes[mesh_name].virtual_routers[virtual_router_name]
return [
route.metadata.formatted_for_list_api()
for route in virtual_router.routes.values()
]
return [route.metadata for route in virtual_router.routes.values()]

def describe_virtual_node(
self, mesh_name: str, mesh_owner: Optional[str], virtual_node_name: str
Expand Down Expand Up @@ -602,20 +597,15 @@ def delete_virtual_node(
del self.meshes[mesh_name].virtual_nodes[virtual_node_name]
return virtual_node

@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
@paginate(pagination_model=PAGINATION_MODEL)
def list_virtual_nodes(
self,
limit: Optional[int],
mesh_name: str,
mesh_owner: Optional[str],
next_token: Optional[str],
) -> List[Dict[str, Any]]:
) -> List[VirtualNodeMetadata]:
self._validate_mesh(mesh_name=mesh_name, mesh_owner=mesh_owner)
virtual_nodes = self.meshes[mesh_name].virtual_nodes
return [
virtual_node.metadata.formatted_for_list_api()
for virtual_node in virtual_nodes.values()
]
return [virtual_node.metadata for virtual_node in virtual_nodes.values()]


appmesh_backends = BackendDict(AppMeshBackend, "appmesh")
24 changes: 17 additions & 7 deletions moto/appmesh/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def delete_mesh(self) -> str:

def list_meshes(self) -> str:
params = self._get_params()
limit = params.get("limit")
limit = self._get_int_param("limit")
next_token = params.get("nextToken")
meshes, next_token = self.appmesh_backend.list_meshes(
limit=limit,
Expand All @@ -81,7 +81,7 @@ def list_meshes(self) -> str:

def list_tags_for_resource(self) -> str:
params = self._get_params()
limit = params.get("limit")
limit = self._get_int_param("limit")
next_token = params.get("nextToken")
resource_arn = params.get("resourceArn")
tags, next_token = self.appmesh_backend.list_tags_for_resource(
Expand Down Expand Up @@ -158,7 +158,7 @@ def delete_virtual_router(self) -> str:
return json.dumps(virtual_router.to_dict())

def list_virtual_routers(self) -> str:
limit = self._get_param("limit")
limit = self._get_int_param("limit")
mesh_name = self._get_param("meshName")
mesh_owner = self._get_param("meshOwner")
next_token = self._get_param("nextToken")
Expand Down Expand Up @@ -235,7 +235,7 @@ def delete_route(self) -> str:
return json.dumps(route.to_dict())

def list_routes(self) -> str:
limit = self._get_param("limit")
limit = self._get_int_param("limit")
mesh_name = self._get_param("meshName")
mesh_owner = self._get_param("meshOwner")
next_token = self._get_param("nextToken")
Expand All @@ -247,7 +247,12 @@ def list_routes(self) -> str:
next_token=next_token,
virtual_router_name=virtual_router_name,
)
return json.dumps(dict(nextToken=next_token, routes=routes))
return json.dumps(
dict(
nextToken=next_token,
routes=[r.formatted_for_list_api() for r in routes],
)
)

def describe_virtual_node(self) -> str:
mesh_name = self._get_param("meshName")
Expand Down Expand Up @@ -306,7 +311,7 @@ def delete_virtual_node(self) -> str:
return json.dumps(virtual_node.to_dict())

def list_virtual_nodes(self) -> str:
limit = self._get_param("limit")
limit = self._get_int_param("limit")
mesh_name = self._get_param("meshName")
mesh_owner = self._get_param("meshOwner")
next_token = self._get_param("nextToken")
Expand All @@ -316,4 +321,9 @@ def list_virtual_nodes(self) -> str:
mesh_owner=mesh_owner,
next_token=next_token,
)
return json.dumps(dict(nextToken=next_token, virtualNodes=virtual_nodes))
return json.dumps(
dict(
nextToken=next_token,
virtualNodes=[n.formatted_for_list_api() for n in virtual_nodes],
)
)
4 changes: 2 additions & 2 deletions moto/athena/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __init__(
self.configuration["EnforceWorkGroupConfiguration"] = True
if "EngineVersion" not in self.configuration:
self.configuration["EngineVersion"] = {
"EffectiveEngineVersion": "Athena engine " "version 3",
"EffectiveEngineVersion": "Athena engine version 3",
"SelectedEngineVersion": "AUTO",
}
if "PublishCloudWatchMetricsEnabled" not in self.configuration:
Expand Down Expand Up @@ -346,7 +346,7 @@ def _store_query_result_in_s3(self, exec_id: str) -> None:
for row in self.query_results[exec_id].rows:
query_result += ",".join(
[
f"\"{r['VarCharValue']}\"" if "VarCharValue" in r else ""
f'"{r["VarCharValue"]}"' if "VarCharValue" in r else ""
for r in row["Data"]
]
)
Expand Down
Loading

0 comments on commit cbe5fad

Please sign in to comment.