Core: Add endpoint to configure Dockerless services in ServerMode (#7393)
This commit is contained in:
parent
dbfa456dda
commit
89a85cf454
@ -20,7 +20,8 @@ If you are using the decorators, some options are configurable within the decora
|
|||||||
"services": ["dynamodb"]
|
"services": ["dynamodb"]
|
||||||
},
|
},
|
||||||
"reset_boto3_session": True,
|
"reset_boto3_session": True,
|
||||||
}
|
},
|
||||||
|
"iam": {"load_aws_managed_policies": False},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +50,36 @@ That is why Moto resets the `boto3-Session`, to make sure that it is recreated w
|
|||||||
|
|
||||||
If all of your tests use Moto, and you never want to reach out to AWS, you can choose to _not_ reset the `boto3-session`. New boto3-clients that are created will reuse the `boto3-Session` (with fake credentials), making Moto much more performant.
|
If all of your tests use Moto, and you never want to reach out to AWS, you can choose to _not_ reset the `boto3-session`. New boto3-clients that are created will reuse the `boto3-Session` (with fake credentials), making Moto much more performant.
|
||||||
|
|
||||||
|
AWS Managed Policies
|
||||||
|
--------------------
|
||||||
|
Moto comes bundled with all Managed Policies that AWS exposes, which are updated regularly. However, they are not loaded unless specifically requested for performance reasons.
|
||||||
|
|
||||||
|
Set `"iam": {"load_aws_managed_policies": True}` to load these policies for a single test.
|
||||||
|
|
||||||
|
Configuring MotoServer
|
||||||
|
----------------------
|
||||||
|
The following options can also be configured when running the MotoServer:
|
||||||
|
|
||||||
|
.. sourcecode::
|
||||||
|
|
||||||
|
options = {
|
||||||
|
"batch": {"use_docker": True},
|
||||||
|
"lambda": {"use_docker": True}
|
||||||
|
}
|
||||||
|
requests.post(f"http://localhost:5000/moto-api/config", json=options)
|
||||||
|
|
||||||
|
Send a GET request to see the current status of this configuration:
|
||||||
|
|
||||||
|
.. sourcecode::
|
||||||
|
|
||||||
|
requests.get(f"http://localhost:5000/moto-api/config").json()
|
||||||
|
|
||||||
|
The IAM Managed Policies should be loaded with an environment variable:
|
||||||
|
|
||||||
|
.. sourcecode::
|
||||||
|
|
||||||
|
MOTO_IAM_LOAD_MANAGED_POLICIES=true
|
||||||
|
|
||||||
Other configuration options
|
Other configuration options
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ from typing import Any, Dict, List, Optional, Set, Tuple
|
|||||||
|
|
||||||
from moto.core import DEFAULT_ACCOUNT_ID
|
from moto.core import DEFAULT_ACCOUNT_ID
|
||||||
from moto.core.base_backend import BackendDict, BaseBackend
|
from moto.core.base_backend import BackendDict, BaseBackend
|
||||||
|
from moto.core.config import default_user_config
|
||||||
from moto.core.model_instances import reset_model_data
|
from moto.core.model_instances import reset_model_data
|
||||||
|
|
||||||
|
|
||||||
@ -116,5 +117,17 @@ class MotoAPIBackend(BaseBackend):
|
|||||||
self.proxy_urls_to_passthrough.clear()
|
self.proxy_urls_to_passthrough.clear()
|
||||||
self.proxy_hosts_to_passthrough.clear()
|
self.proxy_hosts_to_passthrough.clear()
|
||||||
|
|
||||||
|
def get_config(self) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"batch": default_user_config["batch"],
|
||||||
|
"lambda": default_user_config["lambda"],
|
||||||
|
}
|
||||||
|
|
||||||
|
def set_config(self, config: Dict[str, Any]) -> None:
|
||||||
|
if "batch" in config:
|
||||||
|
default_user_config["batch"] = config["batch"]
|
||||||
|
if "lambda" in config:
|
||||||
|
default_user_config["lambda"] = config["lambda"]
|
||||||
|
|
||||||
|
|
||||||
moto_api_backend = MotoAPIBackend(region_name="global", account_id=DEFAULT_ACCOUNT_ID)
|
moto_api_backend = MotoAPIBackend(region_name="global", account_id=DEFAULT_ACCOUNT_ID)
|
||||||
|
@ -277,6 +277,23 @@ class MotoAPIResponse(BaseResponse):
|
|||||||
resp = {"http_urls": list(urls), "https_hosts": list(hosts)}
|
resp = {"http_urls": list(urls), "https_hosts": list(hosts)}
|
||||||
return 201, res_headers, json.dumps(resp).encode("utf-8")
|
return 201, res_headers, json.dumps(resp).encode("utf-8")
|
||||||
|
|
||||||
|
def config(
|
||||||
|
self,
|
||||||
|
request: Any,
|
||||||
|
full_url: str, # pylint: disable=unused-argument
|
||||||
|
headers: Any,
|
||||||
|
) -> TYPE_RESPONSE:
|
||||||
|
from .models import moto_api_backend
|
||||||
|
|
||||||
|
res_headers = {"Content-Type": "application/json"}
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
config = self._get_body(headers, request)
|
||||||
|
moto_api_backend.set_config(config)
|
||||||
|
|
||||||
|
config = moto_api_backend.get_config()
|
||||||
|
return 201, res_headers, json.dumps(config).encode("utf-8")
|
||||||
|
|
||||||
def _get_body(self, headers: Any, request: Any) -> Any:
|
def _get_body(self, headers: Any, request: Any) -> Any:
|
||||||
if isinstance(request, AWSPreparedRequest):
|
if isinstance(request, AWSPreparedRequest):
|
||||||
return json.loads(request.body) # type: ignore[arg-type]
|
return json.loads(request.body) # type: ignore[arg-type]
|
||||||
|
@ -13,6 +13,7 @@ url_paths = {
|
|||||||
"{0}/moto-api/reset-auth": response_instance.reset_auth_response,
|
"{0}/moto-api/reset-auth": response_instance.reset_auth_response,
|
||||||
"{0}/moto-api/seed": response_instance.seed,
|
"{0}/moto-api/seed": response_instance.seed,
|
||||||
"{0}/moto-api/proxy/passthrough": response_instance.set_proxy_passthrough,
|
"{0}/moto-api/proxy/passthrough": response_instance.set_proxy_passthrough,
|
||||||
|
"{0}/moto-api/config": response_instance.config,
|
||||||
"{0}/moto-api/static/athena/query-results": response_instance.set_athena_result,
|
"{0}/moto-api/static/athena/query-results": response_instance.set_athena_result,
|
||||||
"{0}/moto-api/static/ce/cost-and-usage-results": response_instance.set_ce_cost_usage_result,
|
"{0}/moto-api/static/ce/cost-and-usage-results": response_instance.set_ce_cost_usage_result,
|
||||||
"{0}/moto-api/static/inspector2/findings-results": response_instance.set_inspector2_findings_result,
|
"{0}/moto-api/static/inspector2/findings-results": response_instance.set_inspector2_findings_result,
|
||||||
|
52
tests/test_core/test_config.py
Normal file
52
tests/test_core/test_config.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
from moto import mock_aws, settings
|
||||||
|
from moto.awslambda.models import LambdaBackend
|
||||||
|
from moto.awslambda.utils import get_backend
|
||||||
|
from moto.awslambda_simple.models import LambdaSimpleBackend
|
||||||
|
from moto.core import DEFAULT_ACCOUNT_ID
|
||||||
|
from moto.core.config import default_user_config
|
||||||
|
|
||||||
|
|
||||||
|
@mock_aws
|
||||||
|
def test_change_configuration_using_api() -> None:
|
||||||
|
assert default_user_config["batch"] == {"use_docker": True}
|
||||||
|
assert default_user_config["lambda"] == {"use_docker": True}
|
||||||
|
|
||||||
|
base_url = (
|
||||||
|
"localhost:5000" if settings.TEST_SERVER_MODE else "motoapi.amazonaws.com"
|
||||||
|
)
|
||||||
|
resp = requests.get(f"http://{base_url}/moto-api/config")
|
||||||
|
assert resp.json()["batch"] == {"use_docker": True}
|
||||||
|
assert resp.json()["lambda"] == {"use_docker": True}
|
||||||
|
|
||||||
|
# Update a single configuration item
|
||||||
|
requests.post(
|
||||||
|
f"http://{base_url}/moto-api/config", json={"batch": {"use_docker": False}}
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = requests.get(f"http://{base_url}/moto-api/config")
|
||||||
|
assert resp.json()["batch"] == {"use_docker": False}
|
||||||
|
assert resp.json()["lambda"] == {"use_docker": True}
|
||||||
|
|
||||||
|
if settings.TEST_DECORATOR_MODE:
|
||||||
|
isinstance(get_backend(DEFAULT_ACCOUNT_ID, "us-east-1"), LambdaBackend)
|
||||||
|
|
||||||
|
# Update multiple configuration items
|
||||||
|
requests.post(
|
||||||
|
f"http://{base_url}/moto-api/config",
|
||||||
|
json={"batch": {"use_docker": True}, "lambda": {"use_docker": False}},
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = requests.get(f"http://{base_url}/moto-api/config")
|
||||||
|
assert resp.json()["batch"] == {"use_docker": True}
|
||||||
|
assert resp.json()["lambda"] == {"use_docker": False}
|
||||||
|
|
||||||
|
if settings.TEST_DECORATOR_MODE:
|
||||||
|
isinstance(get_backend(DEFAULT_ACCOUNT_ID, "us-east-1"), LambdaSimpleBackend)
|
||||||
|
|
||||||
|
# reset
|
||||||
|
requests.post(
|
||||||
|
f"http://{base_url}/moto-api/config",
|
||||||
|
json={"batch": {"use_docker": True}, "lambda": {"use_docker": True}},
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user