Elastic Beanstalk: Add the delete_application
method support (#6797)
This commit is contained in:
parent
6c04b7b1ce
commit
5e8b457bc9
@ -36,7 +36,7 @@ elasticbeanstalk
|
|||||||
- [X] create_environment
|
- [X] create_environment
|
||||||
- [ ] create_platform_version
|
- [ ] create_platform_version
|
||||||
- [ ] create_storage_location
|
- [ ] create_storage_location
|
||||||
- [ ] delete_application
|
- [x] delete_application
|
||||||
- [ ] delete_application_version
|
- [ ] delete_application_version
|
||||||
- [ ] delete_configuration_template
|
- [ ] delete_configuration_template
|
||||||
- [ ] delete_environment_configuration
|
- [ ] delete_environment_configuration
|
||||||
|
@ -1,5 +1,27 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
from moto.core.exceptions import RESTError
|
from moto.core.exceptions import RESTError
|
||||||
|
|
||||||
|
EXCEPTION_RESPONSE = """<?xml version="1.0"?>
|
||||||
|
<ErrorResponse xmlns="http://elasticache.amazonaws.com/doc/2015-02-02/">
|
||||||
|
<Error>
|
||||||
|
<Type>Sender</Type>
|
||||||
|
<Code>{{ error_type }}</Code>
|
||||||
|
<Message>{{ message }}</Message>
|
||||||
|
</Error>
|
||||||
|
<{{ request_id_tag }}>30c0dedb-92b1-4e2b-9be4-1188e3ed86ab</{{ request_id_tag }}>
|
||||||
|
</ErrorResponse>"""
|
||||||
|
|
||||||
|
|
||||||
|
class ElasticBeanstalkException(RESTError):
|
||||||
|
|
||||||
|
code = 400
|
||||||
|
|
||||||
|
def __init__(self, code: str, message: str, **kwargs: Any):
|
||||||
|
kwargs.setdefault("template", "ecerror")
|
||||||
|
self.templates["ecerror"] = EXCEPTION_RESPONSE
|
||||||
|
super().__init__(code, message)
|
||||||
|
|
||||||
|
|
||||||
class InvalidParameterValueError(RESTError):
|
class InvalidParameterValueError(RESTError):
|
||||||
def __init__(self, message: str):
|
def __init__(self, message: str):
|
||||||
@ -9,3 +31,14 @@ class InvalidParameterValueError(RESTError):
|
|||||||
class ResourceNotFoundException(RESTError):
|
class ResourceNotFoundException(RESTError):
|
||||||
def __init__(self, message: str):
|
def __init__(self, message: str):
|
||||||
super().__init__("ResourceNotFoundException", message)
|
super().__init__("ResourceNotFoundException", message)
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationNotFound(ElasticBeanstalkException):
|
||||||
|
|
||||||
|
code = 404
|
||||||
|
|
||||||
|
def __init__(self, application_name: str):
|
||||||
|
super().__init__(
|
||||||
|
"ApplicationNotFound",
|
||||||
|
message=f"Elastic Beanstalk application {application_name} not found.",
|
||||||
|
)
|
||||||
|
@ -2,7 +2,12 @@ import weakref
|
|||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from moto.core import BaseBackend, BackendDict, BaseModel
|
from moto.core import BaseBackend, BackendDict, BaseModel
|
||||||
from .exceptions import InvalidParameterValueError, ResourceNotFoundException
|
|
||||||
|
from .exceptions import (
|
||||||
|
InvalidParameterValueError,
|
||||||
|
ResourceNotFoundException,
|
||||||
|
ApplicationNotFound,
|
||||||
|
)
|
||||||
from .utils import make_arn
|
from .utils import make_arn
|
||||||
|
|
||||||
|
|
||||||
@ -42,7 +47,11 @@ class FakeEnvironment(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class FakeApplication(BaseModel):
|
class FakeApplication(BaseModel):
|
||||||
def __init__(self, backend: "EBBackend", application_name: str):
|
def __init__(
|
||||||
|
self,
|
||||||
|
backend: "EBBackend",
|
||||||
|
application_name: str,
|
||||||
|
):
|
||||||
self.backend = weakref.proxy(backend) # weakref to break cycles
|
self.backend = weakref.proxy(backend) # weakref to break cycles
|
||||||
self.application_name = application_name
|
self.application_name = application_name
|
||||||
self.environments: Dict[str, FakeEnvironment] = dict()
|
self.environments: Dict[str, FakeEnvironment] = dict()
|
||||||
@ -148,5 +157,15 @@ class EBBackend(BaseBackend):
|
|||||||
return env
|
return env
|
||||||
raise KeyError()
|
raise KeyError()
|
||||||
|
|
||||||
|
def delete_application(
|
||||||
|
self,
|
||||||
|
application_name: str,
|
||||||
|
) -> None:
|
||||||
|
if application_name:
|
||||||
|
if application_name in self.applications:
|
||||||
|
self.applications.pop(application_name)
|
||||||
|
else:
|
||||||
|
raise ApplicationNotFound(application_name)
|
||||||
|
|
||||||
|
|
||||||
eb_backends = BackendDict(EBBackend, "elasticbeanstalk")
|
eb_backends = BackendDict(EBBackend, "elasticbeanstalk")
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from moto.core.utils import tags_from_query_string
|
from moto.core.utils import tags_from_query_string
|
||||||
from .models import eb_backends, EBBackend
|
|
||||||
from .exceptions import InvalidParameterValueError
|
from .exceptions import InvalidParameterValueError
|
||||||
|
from .models import eb_backends, EBBackend
|
||||||
|
|
||||||
|
|
||||||
class EBResponse(BaseResponse):
|
class EBResponse(BaseResponse):
|
||||||
@ -9,35 +10,39 @@ class EBResponse(BaseResponse):
|
|||||||
super().__init__(service_name="elasticbeanstalk")
|
super().__init__(service_name="elasticbeanstalk")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def backend(self) -> EBBackend:
|
def elasticbeanstalk_backend(self) -> EBBackend:
|
||||||
"""
|
"""
|
||||||
:rtype: EBBackend
|
:rtype: EBBackend
|
||||||
"""
|
"""
|
||||||
return eb_backends[self.current_account][self.region]
|
return eb_backends[self.current_account][self.region]
|
||||||
|
|
||||||
def create_application(self) -> str:
|
def create_application(self) -> str:
|
||||||
app = self.backend.create_application(
|
app = self.elasticbeanstalk_backend.create_application(
|
||||||
application_name=self._get_param("ApplicationName")
|
application_name=self._get_param("ApplicationName")
|
||||||
)
|
)
|
||||||
|
|
||||||
template = self.response_template(EB_CREATE_APPLICATION)
|
template = self.response_template(EB_CREATE_APPLICATION)
|
||||||
return template.render(region_name=self.backend.region_name, application=app)
|
return template.render(
|
||||||
|
region_name=self.elasticbeanstalk_backend.region_name, application=app
|
||||||
|
)
|
||||||
|
|
||||||
def describe_applications(self) -> str:
|
def describe_applications(self) -> str:
|
||||||
template = self.response_template(EB_DESCRIBE_APPLICATIONS)
|
template = self.response_template(EB_DESCRIBE_APPLICATIONS)
|
||||||
return template.render(applications=self.backend.applications.values())
|
return template.render(
|
||||||
|
applications=self.elasticbeanstalk_backend.applications.values()
|
||||||
|
)
|
||||||
|
|
||||||
def create_environment(self) -> str:
|
def create_environment(self) -> str:
|
||||||
application_name = self._get_param("ApplicationName")
|
application_name = self._get_param("ApplicationName")
|
||||||
try:
|
try:
|
||||||
app = self.backend.applications[application_name]
|
app = self.elasticbeanstalk_backend.applications[application_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise InvalidParameterValueError(
|
raise InvalidParameterValueError(
|
||||||
f"No Application named '{application_name}' found."
|
f"No Application named '{application_name}' found."
|
||||||
)
|
)
|
||||||
|
|
||||||
tags = tags_from_query_string(self.querystring, prefix="Tags.member")
|
tags = tags_from_query_string(self.querystring, prefix="Tags.member")
|
||||||
env = self.backend.create_environment(
|
env = self.elasticbeanstalk_backend.create_environment(
|
||||||
app,
|
app,
|
||||||
environment_name=self._get_param("EnvironmentName"),
|
environment_name=self._get_param("EnvironmentName"),
|
||||||
stack_name=self._get_param("SolutionStackName"),
|
stack_name=self._get_param("SolutionStackName"),
|
||||||
@ -45,10 +50,12 @@ class EBResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
|
|
||||||
template = self.response_template(EB_CREATE_ENVIRONMENT)
|
template = self.response_template(EB_CREATE_ENVIRONMENT)
|
||||||
return template.render(environment=env, region=self.backend.region_name)
|
return template.render(
|
||||||
|
environment=env, region=self.elasticbeanstalk_backend.region_name
|
||||||
|
)
|
||||||
|
|
||||||
def describe_environments(self) -> str:
|
def describe_environments(self) -> str:
|
||||||
envs = self.backend.describe_environments()
|
envs = self.elasticbeanstalk_backend.describe_environments()
|
||||||
|
|
||||||
template = self.response_template(EB_DESCRIBE_ENVIRONMENTS)
|
template = self.response_template(EB_DESCRIBE_ENVIRONMENTS)
|
||||||
return template.render(environments=envs)
|
return template.render(environments=envs)
|
||||||
@ -62,17 +69,26 @@ class EBResponse(BaseResponse):
|
|||||||
self.querystring, prefix="TagsToAdd.member"
|
self.querystring, prefix="TagsToAdd.member"
|
||||||
)
|
)
|
||||||
tags_to_remove = self._get_multi_param("TagsToRemove.member")
|
tags_to_remove = self._get_multi_param("TagsToRemove.member")
|
||||||
self.backend.update_tags_for_resource(resource_arn, tags_to_add, tags_to_remove)
|
self.elasticbeanstalk_backend.update_tags_for_resource(
|
||||||
|
resource_arn, tags_to_add, tags_to_remove
|
||||||
|
)
|
||||||
|
|
||||||
return EB_UPDATE_TAGS_FOR_RESOURCE
|
return EB_UPDATE_TAGS_FOR_RESOURCE
|
||||||
|
|
||||||
def list_tags_for_resource(self) -> str:
|
def list_tags_for_resource(self) -> str:
|
||||||
resource_arn = self._get_param("ResourceArn")
|
resource_arn = self._get_param("ResourceArn")
|
||||||
tags = self.backend.list_tags_for_resource(resource_arn)
|
tags = self.elasticbeanstalk_backend.list_tags_for_resource(resource_arn)
|
||||||
|
|
||||||
template = self.response_template(EB_LIST_TAGS_FOR_RESOURCE)
|
template = self.response_template(EB_LIST_TAGS_FOR_RESOURCE)
|
||||||
return template.render(tags=tags, arn=resource_arn)
|
return template.render(tags=tags, arn=resource_arn)
|
||||||
|
|
||||||
|
def delete_application(self) -> str:
|
||||||
|
application_name = self._get_param("ApplicationName")
|
||||||
|
self.elasticbeanstalk_backend.delete_application(
|
||||||
|
application_name=application_name,
|
||||||
|
)
|
||||||
|
return DELETE_APPLICATION_TEMPLATE
|
||||||
|
|
||||||
|
|
||||||
EB_CREATE_APPLICATION = """
|
EB_CREATE_APPLICATION = """
|
||||||
<CreateApplicationResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<CreateApplicationResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
@ -105,7 +121,6 @@ EB_CREATE_APPLICATION = """
|
|||||||
</CreateApplicationResponse>
|
</CreateApplicationResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
EB_DESCRIBE_APPLICATIONS = """
|
EB_DESCRIBE_APPLICATIONS = """
|
||||||
<DescribeApplicationsResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<DescribeApplicationsResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
<DescribeApplicationsResult>
|
<DescribeApplicationsResult>
|
||||||
@ -141,6 +156,13 @@ EB_DESCRIBE_APPLICATIONS = """
|
|||||||
</DescribeApplicationsResponse>
|
</DescribeApplicationsResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
DELETE_APPLICATION_TEMPLATE = """
|
||||||
|
<DeleteApplicationResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>015a05eb-282e-4b76-bd18-663fdfaf42e4</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</DeleteApplicationResponse>
|
||||||
|
"""
|
||||||
|
|
||||||
EB_CREATE_ENVIRONMENT = """
|
EB_CREATE_ENVIRONMENT = """
|
||||||
<CreateEnvironmentResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<CreateEnvironmentResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
@ -167,7 +189,6 @@ EB_CREATE_ENVIRONMENT = """
|
|||||||
</CreateEnvironmentResponse>
|
</CreateEnvironmentResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
EB_DESCRIBE_ENVIRONMENTS = """
|
EB_DESCRIBE_ENVIRONMENTS = """
|
||||||
<DescribeEnvironmentsResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<DescribeEnvironmentsResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
<DescribeEnvironmentsResult>
|
<DescribeEnvironmentsResult>
|
||||||
@ -207,7 +228,6 @@ EB_DESCRIBE_ENVIRONMENTS = """
|
|||||||
</DescribeEnvironmentsResponse>
|
</DescribeEnvironmentsResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# Current list as of 2019-09-04
|
# Current list as of 2019-09-04
|
||||||
EB_LIST_AVAILABLE_SOLUTION_STACKS = """
|
EB_LIST_AVAILABLE_SOLUTION_STACKS = """
|
||||||
<ListAvailableSolutionStacksResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<ListAvailableSolutionStacksResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
@ -1359,7 +1379,6 @@ EB_LIST_AVAILABLE_SOLUTION_STACKS = """
|
|||||||
</ListAvailableSolutionStacksResponse>
|
</ListAvailableSolutionStacksResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
EB_UPDATE_TAGS_FOR_RESOURCE = """
|
EB_UPDATE_TAGS_FOR_RESOURCE = """
|
||||||
<UpdateTagsForResourceResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<UpdateTagsForResourceResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
<ResponseMetadata>
|
<ResponseMetadata>
|
||||||
@ -1368,7 +1387,6 @@ EB_UPDATE_TAGS_FOR_RESOURCE = """
|
|||||||
</UpdateTagsForResourceResponse>
|
</UpdateTagsForResourceResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
EB_LIST_TAGS_FOR_RESOURCE = """
|
EB_LIST_TAGS_FOR_RESOURCE = """
|
||||||
<ListTagsForResourceResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
<ListTagsForResourceResponse xmlns="http://elasticbeanstalk.amazonaws.com/docs/2010-12-01/">
|
||||||
<ListTagsForResourceResult>
|
<ListTagsForResourceResult>
|
||||||
|
0
tests/test_elasticbeanstalk/__init__.py
Normal file
0
tests/test_elasticbeanstalk/__init__.py
Normal file
@ -34,6 +34,37 @@ def test_describe_applications():
|
|||||||
assert "myapp" in apps["Applications"][0]["ApplicationArn"]
|
assert "myapp" in apps["Applications"][0]["ApplicationArn"]
|
||||||
|
|
||||||
|
|
||||||
|
@mock_elasticbeanstalk
|
||||||
|
def test_delete_application():
|
||||||
|
conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
|
||||||
|
|
||||||
|
application_name = "myapp"
|
||||||
|
|
||||||
|
conn.create_application(ApplicationName=application_name)
|
||||||
|
|
||||||
|
resp = conn.delete_application(ApplicationName=application_name)
|
||||||
|
|
||||||
|
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
|
||||||
|
|
||||||
|
|
||||||
|
@mock_elasticbeanstalk
|
||||||
|
def test_delete_unknown_application():
|
||||||
|
conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
|
||||||
|
|
||||||
|
application_name = "myapp"
|
||||||
|
unknown_application_name = "myapp1"
|
||||||
|
|
||||||
|
conn.create_application(ApplicationName=application_name)
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
conn.delete_application(ApplicationName=unknown_application_name)
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
assert err["Code"] == "ApplicationNotFound"
|
||||||
|
assert (
|
||||||
|
err["Message"]
|
||||||
|
== f"Elastic Beanstalk application {unknown_application_name} not found."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_elasticbeanstalk
|
@mock_elasticbeanstalk
|
||||||
def test_create_environment():
|
def test_create_environment():
|
||||||
# Create Elastic Beanstalk Environment
|
# Create Elastic Beanstalk Environment
|
15
tests/test_elasticbeanstalk/test_server.py
Normal file
15
tests/test_elasticbeanstalk/test_server.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
"""Test different server responses."""
|
||||||
|
|
||||||
|
import moto.server as server
|
||||||
|
|
||||||
|
|
||||||
|
def test_elasticbeanstalk_describe():
|
||||||
|
backend = server.create_backend_app("elasticbeanstalk")
|
||||||
|
test_client = backend.test_client()
|
||||||
|
|
||||||
|
data = "Action=DescribeApplications"
|
||||||
|
headers = {"Host": "elasticbeanstalk.us-east-1.amazonaws.com"}
|
||||||
|
resp = test_client.post("/", data=data, headers=headers)
|
||||||
|
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert "<Applications></Applications>" in str(resp.data)
|
Loading…
Reference in New Issue
Block a user