diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md
index f039425f6..f99d86df3 100644
--- a/IMPLEMENTATION_COVERAGE.md
+++ b/IMPLEMENTATION_COVERAGE.md
@@ -2878,15 +2878,15 @@
- [ ] test_failover
## elasticbeanstalk
-0% implemented
+13% implemented
- [ ] abort_environment_update
- [ ] apply_environment_managed_action
- [ ] check_dns_availability
- [ ] compose_environments
-- [ ] create_application
+- [X] create_application
- [ ] create_application_version
- [ ] create_configuration_template
-- [ ] create_environment
+- [X] create_environment
- [ ] create_platform_version
- [ ] create_storage_location
- [ ] delete_application
@@ -2903,13 +2903,13 @@
- [ ] describe_environment_managed_action_history
- [ ] describe_environment_managed_actions
- [ ] describe_environment_resources
-- [ ] describe_environments
+- [X] describe_environments
- [ ] describe_events
- [ ] describe_instances_health
- [ ] describe_platform_version
-- [ ] list_available_solution_stacks
+- [X] list_available_solution_stacks
- [ ] list_platform_versions
-- [ ] list_tags_for_resource
+- [X] list_tags_for_resource
- [ ] rebuild_environment
- [ ] request_environment_info
- [ ] restart_app_server
@@ -2921,7 +2921,7 @@
- [ ] update_application_version
- [ ] update_configuration_template
- [ ] update_environment
-- [ ] update_tags_for_resource
+- [X] update_tags_for_resource
- [ ] validate_configuration_settings
## elastictranscoder
diff --git a/moto/__init__.py b/moto/__init__.py
index 44b25f41e..4c9d4753c 100644
--- a/moto/__init__.py
+++ b/moto/__init__.py
@@ -21,6 +21,7 @@ from .datasync import mock_datasync # noqa
from .dynamodb import mock_dynamodb, mock_dynamodb_deprecated # noqa
from .dynamodb2 import mock_dynamodb2, mock_dynamodb2_deprecated # noqa
from .dynamodbstreams import mock_dynamodbstreams # noqa
+from .elasticbeanstalk import mock_elasticbeanstalk # noqa
from .ec2 import mock_ec2, mock_ec2_deprecated # noqa
from .ec2_instance_connect import mock_ec2_instance_connect # noqa
from .ecr import mock_ecr, mock_ecr_deprecated # noqa
diff --git a/moto/backends.py b/moto/backends.py
index a358b8fd2..a48df74a4 100644
--- a/moto/backends.py
+++ b/moto/backends.py
@@ -23,6 +23,7 @@ from moto.ec2 import ec2_backends
from moto.ec2_instance_connect import ec2_instance_connect_backends
from moto.ecr import ecr_backends
from moto.ecs import ecs_backends
+from moto.elasticbeanstalk import eb_backends
from moto.elb import elb_backends
from moto.elbv2 import elbv2_backends
from moto.emr import emr_backends
@@ -77,6 +78,7 @@ BACKENDS = {
"ec2_instance_connect": ec2_instance_connect_backends,
"ecr": ecr_backends,
"ecs": ecs_backends,
+ "elasticbeanstalk": eb_backends,
"elb": elb_backends,
"elbv2": elbv2_backends,
"events": events_backends,
diff --git a/moto/core/utils.py b/moto/core/utils.py
index f61b040e0..dce9f675c 100644
--- a/moto/core/utils.py
+++ b/moto/core/utils.py
@@ -328,3 +328,25 @@ def py2_strip_unicode_keys(blob):
blob = new_set
return blob
+
+
+def tags_from_query_string(
+ querystring_dict, prefix="Tag", key_suffix="Key", value_suffix="Value"
+):
+ response_values = {}
+ for key, value in querystring_dict.items():
+ if key.startswith(prefix) and key.endswith(key_suffix):
+ tag_index = key.replace(prefix + ".", "").replace("." + key_suffix, "")
+ tag_key = querystring_dict.get(
+ "{prefix}.{index}.{key_suffix}".format(
+ prefix=prefix, index=tag_index, key_suffix=key_suffix,
+ )
+ )[0]
+ tag_value_key = "{prefix}.{index}.{value_suffix}".format(
+ prefix=prefix, index=tag_index, value_suffix=value_suffix,
+ )
+ if tag_value_key in querystring_dict:
+ response_values[tag_key] = querystring_dict.get(tag_value_key)[0]
+ else:
+ response_values[tag_key] = None
+ return response_values
diff --git a/moto/ec2/responses/tags.py b/moto/ec2/responses/tags.py
index 5290b7409..0c7d89a41 100644
--- a/moto/ec2/responses/tags.py
+++ b/moto/ec2/responses/tags.py
@@ -2,7 +2,8 @@ from __future__ import unicode_literals
from moto.core.responses import BaseResponse
from moto.ec2.models import validate_resource_ids
-from moto.ec2.utils import tags_from_query_string, filters_from_querystring
+from moto.ec2.utils import filters_from_querystring
+from moto.core.utils import tags_from_query_string
class TagResponse(BaseResponse):
diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py
index 74fe3d27b..61d22d8b2 100644
--- a/moto/ec2/utils.py
+++ b/moto/ec2/utils.py
@@ -196,22 +196,6 @@ def split_route_id(route_id):
return values[0], values[1]
-def tags_from_query_string(querystring_dict):
- prefix = "Tag"
- suffix = "Key"
- response_values = {}
- for key, value in querystring_dict.items():
- if key.startswith(prefix) and key.endswith(suffix):
- tag_index = key.replace(prefix + ".", "").replace("." + suffix, "")
- tag_key = querystring_dict.get("Tag.{0}.Key".format(tag_index))[0]
- tag_value_key = "Tag.{0}.Value".format(tag_index)
- if tag_value_key in querystring_dict:
- response_values[tag_key] = querystring_dict.get(tag_value_key)[0]
- else:
- response_values[tag_key] = None
- return response_values
-
-
def dhcp_configuration_from_querystring(querystring, option="DhcpConfiguration"):
"""
turn:
diff --git a/moto/elasticbeanstalk/__init__.py b/moto/elasticbeanstalk/__init__.py
new file mode 100644
index 000000000..851fa445b
--- /dev/null
+++ b/moto/elasticbeanstalk/__init__.py
@@ -0,0 +1,4 @@
+from .models import eb_backends
+from moto.core.models import base_decorator
+
+mock_elasticbeanstalk = base_decorator(eb_backends)
diff --git a/moto/elasticbeanstalk/exceptions.py b/moto/elasticbeanstalk/exceptions.py
new file mode 100644
index 000000000..f1e27c564
--- /dev/null
+++ b/moto/elasticbeanstalk/exceptions.py
@@ -0,0 +1,15 @@
+from moto.core.exceptions import RESTError
+
+
+class InvalidParameterValueError(RESTError):
+ def __init__(self, message):
+ super(InvalidParameterValueError, self).__init__(
+ "InvalidParameterValue", message
+ )
+
+
+class ResourceNotFoundException(RESTError):
+ def __init__(self, message):
+ super(ResourceNotFoundException, self).__init__(
+ "ResourceNotFoundException", message
+ )
diff --git a/moto/elasticbeanstalk/models.py b/moto/elasticbeanstalk/models.py
new file mode 100644
index 000000000..3767846c1
--- /dev/null
+++ b/moto/elasticbeanstalk/models.py
@@ -0,0 +1,152 @@
+import weakref
+
+from boto3 import Session
+
+from moto.core import BaseBackend, BaseModel
+from .exceptions import InvalidParameterValueError, ResourceNotFoundException
+
+
+class FakeEnvironment(BaseModel):
+ def __init__(
+ self, application, environment_name, solution_stack_name, tags,
+ ):
+ self.application = weakref.proxy(
+ application
+ ) # weakref to break circular dependencies
+ self.environment_name = environment_name
+ self.solution_stack_name = solution_stack_name
+ self.tags = tags
+
+ @property
+ def application_name(self):
+ return self.application.application_name
+
+ @property
+ def environment_arn(self):
+ return (
+ "arn:aws:elasticbeanstalk:{region}:{account_id}:"
+ "environment/{application_name}/{environment_name}".format(
+ region=self.region,
+ account_id="123456789012",
+ application_name=self.application_name,
+ environment_name=self.environment_name,
+ )
+ )
+
+ @property
+ def platform_arn(self):
+ return "TODO" # TODO
+
+ @property
+ def region(self):
+ return self.application.region
+
+
+class FakeApplication(BaseModel):
+ def __init__(self, backend, application_name):
+ self.backend = weakref.proxy(backend) # weakref to break cycles
+ self.application_name = application_name
+ self.environments = dict()
+
+ def create_environment(
+ self, environment_name, solution_stack_name, tags,
+ ):
+ if environment_name in self.environments:
+ raise InvalidParameterValueError
+
+ env = FakeEnvironment(
+ application=self,
+ environment_name=environment_name,
+ solution_stack_name=solution_stack_name,
+ tags=tags,
+ )
+ self.environments[environment_name] = env
+
+ return env
+
+ @property
+ def region(self):
+ return self.backend.region
+
+
+class EBBackend(BaseBackend):
+ def __init__(self, region):
+ self.region = region
+ self.applications = dict()
+
+ def reset(self):
+ # preserve region
+ region = self.region
+ self._reset_model_refs()
+ self.__dict__ = {}
+ self.__init__(region)
+
+ def create_application(self, application_name):
+ if application_name in self.applications:
+ raise InvalidParameterValueError(
+ "Application {} already exists.".format(application_name)
+ )
+ new_app = FakeApplication(backend=self, application_name=application_name,)
+ self.applications[application_name] = new_app
+ return new_app
+
+ def create_environment(self, app, environment_name, stack_name, tags):
+ return app.create_environment(
+ environment_name=environment_name,
+ solution_stack_name=stack_name,
+ tags=tags,
+ )
+
+ def describe_environments(self):
+ envs = []
+ for app in self.applications.values():
+ for env in app.environments.values():
+ envs.append(env)
+ return envs
+
+ def list_available_solution_stacks(self):
+ # Implemented in response.py
+ pass
+
+ def update_tags_for_resource(self, resource_arn, tags_to_add, tags_to_remove):
+ try:
+ res = self._find_environment_by_arn(resource_arn)
+ except KeyError:
+ raise ResourceNotFoundException(
+ "Resource not found for ARN '{}'.".format(resource_arn)
+ )
+
+ for key, value in tags_to_add.items():
+ res.tags[key] = value
+
+ for key in tags_to_remove:
+ del res.tags[key]
+
+ def list_tags_for_resource(self, resource_arn):
+ try:
+ res = self._find_environment_by_arn(resource_arn)
+ except KeyError:
+ raise ResourceNotFoundException(
+ "Resource not found for ARN '{}'.".format(resource_arn)
+ )
+ return res.tags
+
+ def _find_environment_by_arn(self, arn):
+ for app in self.applications.keys():
+ for env in self.applications[app].environments.values():
+ if env.environment_arn == arn:
+ return env
+ raise KeyError()
+
+
+eb_backends = {}
+for region in Session().get_available_regions("elasticbeanstalk"):
+ eb_backends[region] = EBBackend(region)
+for region in Session().get_available_regions(
+ "elasticbeanstalk", partition_name="aws-us-gov"
+):
+ eb_backends[region] = EBBackend(region)
+for region in Session().get_available_regions(
+ "elasticbeanstalk", partition_name="aws-cn"
+):
+ eb_backends[region] = EBBackend(region)
diff --git a/moto/elasticbeanstalk/responses.py b/moto/elasticbeanstalk/responses.py
new file mode 100644
index 000000000..387cbb3ea
--- /dev/null
+++ b/moto/elasticbeanstalk/responses.py
@@ -0,0 +1,1386 @@
+from moto.core.responses import BaseResponse
+from moto.core.utils import tags_from_query_string
+from .models import eb_backends
+from .exceptions import InvalidParameterValueError
+
+
+class EBResponse(BaseResponse):
+ @property
+ def backend(self):
+ """
+ :rtype: EBBackend
+ """
+ return eb_backends[self.region]
+
+ def create_application(self):
+ app = self.backend.create_application(
+ application_name=self._get_param("ApplicationName"),
+ )
+
+ template = self.response_template(EB_CREATE_APPLICATION)
+ return template.render(region_name=self.backend.region, application=app,)
+
+ def describe_applications(self):
+ template = self.response_template(EB_DESCRIBE_APPLICATIONS)
+ return template.render(applications=self.backend.applications.values(),)
+
+ def create_environment(self):
+ application_name = self._get_param("ApplicationName")
+ try:
+ app = self.backend.applications[application_name]
+ except KeyError:
+ raise InvalidParameterValueError(
+ "No Application named '{}' found.".format(application_name)
+ )
+
+ tags = tags_from_query_string(self.querystring, prefix="Tags.member")
+ env = self.backend.create_environment(
+ app,
+ environment_name=self._get_param("EnvironmentName"),
+ stack_name=self._get_param("SolutionStackName"),
+ tags=tags,
+ )
+
+ template = self.response_template(EB_CREATE_ENVIRONMENT)
+ return template.render(environment=env, region=self.backend.region,)
+
+ def describe_environments(self):
+ envs = self.backend.describe_environments()
+
+ template = self.response_template(EB_DESCRIBE_ENVIRONMENTS)
+ return template.render(environments=envs,)
+
+ def list_available_solution_stacks(self):
+ return EB_LIST_AVAILABLE_SOLUTION_STACKS
+
+ def update_tags_for_resource(self):
+ resource_arn = self._get_param("ResourceArn")
+ tags_to_add = tags_from_query_string(
+ self.querystring, prefix="TagsToAdd.member"
+ )
+ tags_to_remove = self._get_multi_param("TagsToRemove.member")
+ self.backend.update_tags_for_resource(resource_arn, tags_to_add, tags_to_remove)
+
+ return EB_UPDATE_TAGS_FOR_RESOURCE
+
+ def list_tags_for_resource(self):
+ resource_arn = self._get_param("ResourceArn")
+ tags = self.backend.list_tags_for_resource(resource_arn)
+
+ template = self.response_template(EB_LIST_TAGS_FOR_RESOURCE)
+ return template.render(tags=tags, arn=resource_arn,)
+
+
+EB_CREATE_APPLICATION = """
+
+
+
+
+ 2019-09-03T13:08:29.049Z
+
+
+
+ false
+ 180
+ false
+
+
+ false
+ 200
+ false
+
+
+
+ arn:aws:elasticbeanstalk:{{ region_name }}:111122223333:application/{{ application_name }}
+ {{ application.application_name }}
+ 2019-09-03T13:08:29.049Z
+
+
+
+ 1b6173c8-13aa-4b0a-99e9-eb36a1fb2778
+
+
+"""
+
+
+EB_DESCRIBE_APPLICATIONS = """
+
+
+
+ {% for application in applications %}
+
+
+ 2019-09-03T13:08:29.049Z
+
+
+
+ 180
+ false
+ false
+
+
+ false
+ 200
+ false
+
+
+
+ arn:aws:elasticbeanstalk:{{ region_name }}:111122223333:application/{{ application.name }}
+ {{ application.application_name }}
+ 2019-09-03T13:08:29.049Z
+
+ {% endfor %}
+
+
+
+ 015a05eb-282e-4b76-bd18-663fdfaf42e4
+
+
+"""
+
+
+EB_CREATE_ENVIRONMENT = """
+
+
+ {{ environment.solution_stack_name }}
+ Grey
+ {{ environment.environment_arn }}
+ 2019-09-04T09:41:24.222Z
+ 2019-09-04T09:41:24.222Z
+ {{ environment_id }}
+ {{ environment.platform_arn }}
+
+ WebServer
+ Standard
+ 1.0
+
+ {{ environment.environment_name }}
+ {{ environment.application_name }}
+ Launching
+
+
+ 18dc8158-f5d7-4d5a-82ef-07fcaadf81c6
+
+
+"""
+
+
+EB_DESCRIBE_ENVIRONMENTS = """
+
+
+
+ {% for env in environments %}
+
+ {{ env.solution_stack_name }}
+ Grey
+ {{ env.environment_arn }}
+ false
+ 2019-08-30T09:35:10.913Z
+ false
+
+ 2019-08-22T07:02:47.332Z
+ {{ env.environment_id }}
+ 1
+ {{ env.platform_arn }}
+
+ WebServer
+ Standard
+ 1.0
+
+ No Data
+ {{ env.environment_name }}
+
+
+
+ {{ env.application_name }}
+ Ready
+
+ {% endfor %}
+
+
+
+ dd56b215-01a0-40b2-bd1e-57589c39424f
+
+
+"""
+
+
+# Current list as of 2019-09-04
+EB_LIST_AVAILABLE_SOLUTION_STACKS = """
+
+
+
+ 64bit Amazon Linux 2018.03 v4.10.1 running Node.js
+ 64bit Amazon Linux 2018.03 v4.9.2 running Node.js
+ 64bit Amazon Linux 2018.03 v4.8.0 running Node.js
+ 64bit Amazon Linux 2018.03 v4.6.0 running Node.js
+ 64bit Amazon Linux 2018.03 v4.5.3 running Node.js
+ 64bit Amazon Linux 2018.03 v4.5.1 running Node.js
+ 64bit Amazon Linux 2018.03 v4.5.0 running Node.js
+ 64bit Amazon Linux 2017.09 v4.4.6 running Node.js
+ 64bit Amazon Linux 2017.09 v4.4.5 running Node.js
+ 64bit Amazon Linux 2017.09 v4.4.4 running Node.js
+ 64bit Amazon Linux 2017.09 v4.4.2 running Node.js
+ 64bit Amazon Linux 2017.09 v4.4.0 running Node.js
+ 64bit Amazon Linux 2017.03 v4.3.0 running Node.js
+ 64bit Amazon Linux 2017.03 v4.2.2 running Node.js
+ 64bit Amazon Linux 2017.03 v4.2.1 running Node.js
+ 64bit Amazon Linux 2017.03 v4.2.0 running Node.js
+ 64bit Amazon Linux 2017.03 v4.1.1 running Node.js
+ 64bit Amazon Linux 2017.03 v4.1.0 running Node.js
+ 64bit Amazon Linux 2016.09 v4.0.1 running Node.js
+ 64bit Amazon Linux 2016.09 v4.0.0 running Node.js
+ 64bit Amazon Linux 2016.09 v3.3.1 running Node.js
+ 64bit Amazon Linux 2016.09 v3.1.0 running Node.js
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 5.4
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 5.5
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 5.6
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 7.0
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 7.1
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.12 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.7 running PHP 7.1
+ 64bit Amazon Linux 2018.03 v2.8.6 running PHP 7.1
+ 64bit Amazon Linux 2018.03 v2.8.6 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.5 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.4 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.3 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.2 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.1 running PHP 7.2
+ 64bit Amazon Linux 2018.03 v2.8.0 running PHP 7.1
+ 64bit Amazon Linux 2018.03 v2.7.1 running PHP 5.6
+ 64bit Amazon Linux 2018.03 v2.7.1 running PHP 7.0
+ 64bit Amazon Linux 2018.03 v2.7.1 running PHP 7.1
+ 64bit Amazon Linux 2018.03 v2.7.0 running PHP 7.0
+ 64bit Amazon Linux 2018.03 v2.7.0 running PHP 7.1
+ 64bit Amazon Linux 2017.09 v2.6.6 running PHP 5.4
+ 64bit Amazon Linux 2017.09 v2.6.6 running PHP 5.6
+ 64bit Amazon Linux 2017.09 v2.6.6 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.5 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 5.4
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 5.5
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 5.6
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 7.1
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 5.4
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 5.5
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 5.6
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 7.1
+ 64bit Amazon Linux 2017.09 v2.6.2 running PHP 5.6
+ 64bit Amazon Linux 2017.09 v2.6.2 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.1 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 5.4
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 5.5
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 5.6
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 7.0
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 7.1
+ 64bit Amazon Linux 2017.03 v2.5.0 running PHP 7.0
+ 64bit Amazon Linux 2017.03 v2.5.0 running PHP 7.1
+ 64bit Amazon Linux 2017.03 v2.4.4 running PHP 5.5
+ 64bit Amazon Linux 2017.03 v2.4.4 running PHP 5.6
+ 64bit Amazon Linux 2017.03 v2.4.4 running PHP 7.0
+ 64bit Amazon Linux 2017.03 v2.4.3 running PHP 7.0
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 5.4
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 5.5
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 5.6
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 7.0
+ 64bit Amazon Linux 2017.03 v2.4.1 running PHP 7.0
+ 64bit Amazon Linux 2017.03 v2.4.0 running PHP 7.0
+ 64bit Amazon Linux 2016.09 v2.3.2 running PHP 7.0
+ 64bit Amazon Linux 2016.09 v2.3.1 running PHP 7.0
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python 3.6
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python 3.4
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python 2.7
+ 64bit Amazon Linux 2018.03 v2.7.5 running Python 3.6
+ 64bit Amazon Linux 2018.03 v2.7.1 running Python 3.6
+ 64bit Amazon Linux 2018.03 v2.7.0 running Python 3.6
+ 64bit Amazon Linux 2017.09 v2.6.4 running Python 3.6
+ 64bit Amazon Linux 2017.09 v2.6.1 running Python 3.6
+ 64bit Amazon Linux 2017.03 v2.4.0 running Python 3.4
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.6 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.5 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.4 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.3 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.2 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.1 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.0 (Puma)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.6 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.5 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.4 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.3 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.2 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.1 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.0 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 1.9.3
+ 64bit Amazon Linux 2018.03 v2.8.0 running Ruby 2.5 (Passenger Standalone)
+ 64bit Amazon Linux 2017.03 v2.4.4 running Ruby 2.3 (Puma)
+ 64bit Amazon Linux 2017.03 v2.4.4 running Ruby 2.3 (Passenger Standalone)
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 8.5 Java 8
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 8 Java 8
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 7 Java 7
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 7 Java 6
+ 64bit Amazon Linux 2018.03 v3.1.1 running Tomcat 8.5 Java 8
+ 64bit Amazon Linux 2017.03 v2.6.5 running Tomcat 8 Java 8
+ 64bit Amazon Linux 2017.03 v2.6.2 running Tomcat 8 Java 8
+ 64bit Amazon Linux 2017.03 v2.6.1 running Tomcat 8 Java 8
+ 64bit Amazon Linux 2017.03 v2.6.0 running Tomcat 8 Java 8
+ 64bit Amazon Linux 2016.09 v2.5.4 running Tomcat 8 Java 8
+ 64bit Amazon Linux 2016.03 v2.1.0 running Tomcat 8 Java 8
+ 64bit Windows Server Core 2016 v2.2.1 running IIS 10.0
+ 64bit Windows Server 2016 v2.2.1 running IIS 10.0
+ 64bit Windows Server Core 2012 R2 v2.2.1 running IIS 8.5
+ 64bit Windows Server 2012 R2 v2.2.1 running IIS 8.5
+ 64bit Windows Server Core 2016 v1.2.0 running IIS 10.0
+ 64bit Windows Server 2016 v1.2.0 running IIS 10.0
+ 64bit Windows Server Core 2012 R2 v1.2.0 running IIS 8.5
+ 64bit Windows Server 2012 R2 v1.2.0 running IIS 8.5
+ 64bit Windows Server 2012 v1.2.0 running IIS 8
+ 64bit Windows Server 2008 R2 v1.2.0 running IIS 7.5
+ 64bit Windows Server Core 2012 R2 running IIS 8.5
+ 64bit Windows Server 2012 R2 running IIS 8.5
+ 64bit Windows Server 2012 running IIS 8
+ 64bit Windows Server 2008 R2 running IIS 7.5
+ 64bit Amazon Linux 2018.03 v2.12.16 running Docker 18.06.1-ce
+ 64bit Amazon Linux 2016.09 v2.5.2 running Docker 1.12.6
+ 64bit Amazon Linux 2018.03 v2.15.2 running Multi-container Docker 18.06.1-ce (Generic)
+ 64bit Debian jessie v2.12.16 running Go 1.4 (Preconfigured - Docker)
+ 64bit Debian jessie v2.12.16 running Go 1.3 (Preconfigured - Docker)
+ 64bit Debian jessie v2.12.16 running Python 3.4 (Preconfigured - Docker)
+ 64bit Debian jessie v2.10.0 running Python 3.4 (Preconfigured - Docker)
+ 64bit Amazon Linux 2018.03 v2.9.1 running Java 8
+ 64bit Amazon Linux 2018.03 v2.9.1 running Java 7
+ 64bit Amazon Linux 2018.03 v2.8.0 running Java 8
+ 64bit Amazon Linux 2018.03 v2.7.6 running Java 8
+ 64bit Amazon Linux 2018.03 v2.7.5 running Java 8
+ 64bit Amazon Linux 2018.03 v2.7.4 running Java 8
+ 64bit Amazon Linux 2018.03 v2.7.2 running Java 8
+ 64bit Amazon Linux 2018.03 v2.7.1 running Java 8
+ 64bit Amazon Linux 2017.09 v2.6.8 running Java 8
+ 64bit Amazon Linux 2017.09 v2.6.5 running Java 8
+ 64bit Amazon Linux 2017.09 v2.6.4 running Java 8
+ 64bit Amazon Linux 2017.09 v2.6.3 running Java 8
+ 64bit Amazon Linux 2017.09 v2.6.0 running Java 8
+ 64bit Amazon Linux 2017.03 v2.5.4 running Java 8
+ 64bit Amazon Linux 2017.03 v2.5.3 running Java 8
+ 64bit Amazon Linux 2017.03 v2.5.2 running Java 8
+ 64bit Amazon Linux 2016.09 v2.4.4 running Java 8
+ 64bit Amazon Linux 2018.03 v2.12.1 running Go 1.12.7
+ 64bit Amazon Linux 2018.03 v2.6.14 running Packer 1.0.3
+ 64bit Amazon Linux 2018.03 v2.12.16 running GlassFish 5.0 Java 8 (Preconfigured - Docker)
+
+
+
+ 64bit Amazon Linux 2018.03 v4.10.1 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v4.9.2 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v4.8.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v4.6.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v4.5.3 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v4.5.1 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v4.5.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v4.4.6 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v4.4.5 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v4.4.4 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v4.4.2 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v4.4.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v4.3.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v4.2.2 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v4.2.1 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v4.2.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v4.1.1 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v4.1.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v4.0.1 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v4.0.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v3.3.1 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v3.1.0 running Node.js
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 5.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 5.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.14 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.12 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.7 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.6 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.6 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.5 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.4 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.3 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.2 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.1 running PHP 7.2
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.0 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.1 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.1 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.1 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.0 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.0 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.6 running PHP 5.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.6 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.6 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.5 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 5.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 5.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 5.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 5.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.3 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.2 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.2 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.1 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 5.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 5.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.0 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.5.0 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.5.0 running PHP 7.1
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.4 running PHP 5.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.4 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.4 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.3 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 5.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 5.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 5.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.2 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.1 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.0 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v2.3.2 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v2.3.1 running PHP 7.0
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python 3.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python 3.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.9.1 running Python 2.7
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.5 running Python 3.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.1 running Python 3.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.0 running Python 3.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running Python 3.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.1 running Python 3.6
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.0 running Python 3.4
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.6 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.5 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.4 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.3 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.2 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.1 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.0 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.6 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.5 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.4 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.3 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.2 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.1 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 2.0 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.10.1 running Ruby 1.9.3
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.0 running Ruby 2.5 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.4 running Ruby 2.3 (Puma)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.4.4 running Ruby 2.3 (Passenger Standalone)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 8.5 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 7 Java 7
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v3.2.1 running Tomcat 7 Java 6
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v3.1.1 running Tomcat 8.5 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.6.5 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.6.2 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.6.1 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.6.0 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v2.5.4 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Amazon Linux 2016.03 v2.1.0 running Tomcat 8 Java 8
+
+ war
+ zip
+
+
+
+ 64bit Windows Server Core 2016 v2.2.1 running IIS 10.0
+
+ zip
+
+
+
+ 64bit Windows Server 2016 v2.2.1 running IIS 10.0
+
+ zip
+
+
+
+ 64bit Windows Server Core 2012 R2 v2.2.1 running IIS 8.5
+
+ zip
+
+
+
+ 64bit Windows Server 2012 R2 v2.2.1 running IIS 8.5
+
+ zip
+
+
+
+ 64bit Windows Server Core 2016 v1.2.0 running IIS 10.0
+
+ zip
+
+
+
+ 64bit Windows Server 2016 v1.2.0 running IIS 10.0
+
+ zip
+
+
+
+ 64bit Windows Server Core 2012 R2 v1.2.0 running IIS 8.5
+
+ zip
+
+
+
+ 64bit Windows Server 2012 R2 v1.2.0 running IIS 8.5
+
+ zip
+
+
+
+ 64bit Windows Server 2012 v1.2.0 running IIS 8
+
+ zip
+
+
+
+ 64bit Windows Server 2008 R2 v1.2.0 running IIS 7.5
+
+ zip
+
+
+
+ 64bit Windows Server Core 2012 R2 running IIS 8.5
+
+ zip
+
+
+
+ 64bit Windows Server 2012 R2 running IIS 8.5
+
+ zip
+
+
+
+ 64bit Windows Server 2012 running IIS 8
+
+ zip
+
+
+
+ 64bit Windows Server 2008 R2 running IIS 7.5
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.12.16 running Docker 18.06.1-ce
+
+
+
+ 64bit Amazon Linux 2016.09 v2.5.2 running Docker 1.12.6
+
+
+
+ 64bit Amazon Linux 2018.03 v2.15.2 running Multi-container Docker 18.06.1-ce (Generic)
+
+ zip
+ json
+
+
+
+ 64bit Debian jessie v2.12.16 running Go 1.4 (Preconfigured - Docker)
+
+ zip
+
+
+
+ 64bit Debian jessie v2.12.16 running Go 1.3 (Preconfigured - Docker)
+
+ zip
+
+
+
+ 64bit Debian jessie v2.12.16 running Python 3.4 (Preconfigured - Docker)
+
+ zip
+
+
+
+ 64bit Debian jessie v2.10.0 running Python 3.4 (Preconfigured - Docker)
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.9.1 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.9.1 running Java 7
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.8.0 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.6 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.5 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.4 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.2 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.7.1 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.8 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.5 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.4 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.3 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.09 v2.6.0 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.5.4 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.5.3 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2017.03 v2.5.2 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2016.09 v2.4.4 running Java 8
+
+ jar
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.12.1 running Go 1.12.7
+
+ zip
+
+
+
+ 64bit Amazon Linux 2018.03 v2.6.14 running Packer 1.0.3
+
+
+
+ 64bit Amazon Linux 2018.03 v2.12.16 running GlassFish 5.0 Java 8 (Preconfigured - Docker)
+
+ zip
+
+
+
+
+
+ bd6bd2b2-9983-4845-b53b-fe53e8a5e1e7
+
+
+"""
+
+
+EB_UPDATE_TAGS_FOR_RESOURCE = """
+
+
+ f355d788-e67e-440f-b915-99e35254ffee
+
+
+"""
+
+
+EB_LIST_TAGS_FOR_RESOURCE = """
+
+
+
+ {% for key, value in tags.items() %}
+
+ {{ key }}
+ {{ value }}
+
+ {% endfor %}
+
+ {{ arn }}
+
+
+ 178e410f-3b57-456f-a64c-a3b6a16da9ab
+
+
+"""
diff --git a/moto/elasticbeanstalk/urls.py b/moto/elasticbeanstalk/urls.py
new file mode 100644
index 000000000..2d57f7f9d
--- /dev/null
+++ b/moto/elasticbeanstalk/urls.py
@@ -0,0 +1,11 @@
+from __future__ import unicode_literals
+
+from .responses import EBResponse
+
+url_bases = [
+ r"https?://elasticbeanstalk.(?P[a-zA-Z0-9\-_]+).amazonaws.com",
+]
+
+url_paths = {
+ "{0}/$": EBResponse.dispatch,
+}
diff --git a/moto/emr/responses.py b/moto/emr/responses.py
index 3708db0ed..d2b234ced 100644
--- a/moto/emr/responses.py
+++ b/moto/emr/responses.py
@@ -10,9 +10,10 @@ from six.moves.urllib.parse import urlparse
from moto.core.responses import AWSServiceSpec
from moto.core.responses import BaseResponse
from moto.core.responses import xml_to_json_response
+from moto.core.utils import tags_from_query_string
from .exceptions import EmrError
from .models import emr_backends
-from .utils import steps_from_query_string, tags_from_query_string
+from .utils import steps_from_query_string
def generate_boto3_response(operation):
@@ -91,7 +92,7 @@ class ElasticMapReduceResponse(BaseResponse):
@generate_boto3_response("AddTags")
def add_tags(self):
cluster_id = self._get_param("ResourceId")
- tags = tags_from_query_string(self.querystring)
+ tags = tags_from_query_string(self.querystring, prefix="Tags")
self.backend.add_tags(cluster_id, tags)
template = self.response_template(ADD_TAGS_TEMPLATE)
return template.render()
diff --git a/moto/emr/utils.py b/moto/emr/utils.py
index 0f75995b8..fb33214c8 100644
--- a/moto/emr/utils.py
+++ b/moto/emr/utils.py
@@ -22,22 +22,6 @@ def random_instance_group_id(size=13):
return "i-{0}".format(random_id())
-def tags_from_query_string(querystring_dict):
- prefix = "Tags"
- suffix = "Key"
- response_values = {}
- for key, value in querystring_dict.items():
- if key.startswith(prefix) and key.endswith(suffix):
- tag_index = key.replace(prefix + ".", "").replace("." + suffix, "")
- tag_key = querystring_dict.get("Tags.{0}.Key".format(tag_index))[0]
- tag_value_key = "Tags.{0}.Value".format(tag_index)
- if tag_value_key in querystring_dict:
- response_values[tag_key] = querystring_dict.get(tag_value_key)[0]
- else:
- response_values[tag_key] = None
- return response_values
-
-
def steps_from_query_string(querystring_dict):
steps = []
for step in querystring_dict:
diff --git a/tests/test_eb/test_eb.py b/tests/test_eb/test_eb.py
new file mode 100644
index 000000000..42eb09be3
--- /dev/null
+++ b/tests/test_eb/test_eb.py
@@ -0,0 +1,130 @@
+import boto3
+import sure # noqa
+from botocore.exceptions import ClientError
+
+from moto import mock_elasticbeanstalk
+
+
+@mock_elasticbeanstalk
+def test_create_application():
+ # Create Elastic Beanstalk Application
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ app = conn.create_application(ApplicationName="myapp",)
+ app["Application"]["ApplicationName"].should.equal("myapp")
+
+
+@mock_elasticbeanstalk
+def test_create_application_dup():
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ conn.create_application(ApplicationName="myapp",)
+ conn.create_application.when.called_with(ApplicationName="myapp",).should.throw(
+ ClientError
+ )
+
+
+@mock_elasticbeanstalk
+def test_describe_applications():
+ # Create Elastic Beanstalk Application
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ conn.create_application(ApplicationName="myapp",)
+
+ apps = conn.describe_applications()
+ len(apps["Applications"]).should.equal(1)
+ apps["Applications"][0]["ApplicationName"].should.equal("myapp")
+
+
+@mock_elasticbeanstalk
+def test_create_environment():
+ # Create Elastic Beanstalk Environment
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ app = conn.create_application(ApplicationName="myapp",)
+ env = conn.create_environment(ApplicationName="myapp", EnvironmentName="myenv",)
+ env["EnvironmentName"].should.equal("myenv")
+
+
+@mock_elasticbeanstalk
+def test_describe_environments():
+ # List Elastic Beanstalk Envs
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ conn.create_application(ApplicationName="myapp",)
+ conn.create_environment(
+ ApplicationName="myapp", EnvironmentName="myenv",
+ )
+
+ envs = conn.describe_environments()
+ envs = envs["Environments"]
+ len(envs).should.equal(1)
+ envs[0]["ApplicationName"].should.equal("myapp")
+ envs[0]["EnvironmentName"].should.equal("myenv")
+
+
+def tags_dict_to_list(tag_dict):
+ tag_list = []
+ for key, value in tag_dict.items():
+ tag_list.append({"Key": key, "Value": value})
+ return tag_list
+
+
+def tags_list_to_dict(tag_list):
+ tag_dict = {}
+ for tag in tag_list:
+ tag_dict[tag["Key"]] = tag["Value"]
+ return tag_dict
+
+
+@mock_elasticbeanstalk
+def test_create_environment_tags():
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ conn.create_application(ApplicationName="myapp",)
+ env_tags = {"initial key": "initial value"}
+ env = conn.create_environment(
+ ApplicationName="myapp",
+ EnvironmentName="myenv",
+ Tags=tags_dict_to_list(env_tags),
+ )
+
+ tags = conn.list_tags_for_resource(ResourceArn=env["EnvironmentArn"],)
+ tags["ResourceArn"].should.equal(env["EnvironmentArn"])
+ tags_list_to_dict(tags["ResourceTags"]).should.equal(env_tags)
+
+
+@mock_elasticbeanstalk
+def test_update_tags():
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ conn.create_application(ApplicationName="myapp",)
+ env_tags = {
+ "initial key": "initial value",
+ "to remove": "delete me",
+ "to update": "original",
+ }
+ env = conn.create_environment(
+ ApplicationName="myapp",
+ EnvironmentName="myenv",
+ Tags=tags_dict_to_list(env_tags),
+ )
+
+ extra_env_tags = {
+ "to update": "new",
+ "extra key": "extra value",
+ }
+ conn.update_tags_for_resource(
+ ResourceArn=env["EnvironmentArn"],
+ TagsToAdd=tags_dict_to_list(extra_env_tags),
+ TagsToRemove=["to remove"],
+ )
+
+ total_env_tags = env_tags.copy()
+ total_env_tags.update(extra_env_tags)
+ del total_env_tags["to remove"]
+
+ tags = conn.list_tags_for_resource(ResourceArn=env["EnvironmentArn"],)
+ tags["ResourceArn"].should.equal(env["EnvironmentArn"])
+ tags_list_to_dict(tags["ResourceTags"]).should.equal(total_env_tags)
+
+
+@mock_elasticbeanstalk
+def test_list_available_solution_stacks():
+ conn = boto3.client("elasticbeanstalk", region_name="us-east-1")
+ stacks = conn.list_available_solution_stacks()
+ len(stacks["SolutionStacks"]).should.be.greater_than(0)
+ len(stacks["SolutionStacks"]).should.be.equal(len(stacks["SolutionStackDetails"]))