Added reboot instance and list_tags_for_resource. Still need to get the tags populated.

This commit is contained in:
Mike Fuller 2015-01-27 08:21:48 +11:00
parent 23ff33b145
commit 6232abfe2d
4 changed files with 140 additions and 11 deletions

View File

@ -79,6 +79,11 @@ It gets even better! Moto isn't just S3. Here's the status of the other AWS serv
|------------------------------------------------------------------------------|
| RDS | @mock_rds | core endpoints done |
|------------------------------------------------------------------------------|
| RDS2 | @mock_rds2 | core endpoints done |
| - Database | | core endpoints done |
| - Security Group | | not done |
| - Option Group | | core endpoints done |
|------------------------------------------------------------------------------|
| Route53 | @mock_route53 | core endpoints done |
|------------------------------------------------------------------------------|
| S3 | @mock_s3 | core endpoints done |

View File

@ -5,7 +5,7 @@ import copy
import boto.rds2
import json
from jinja2 import Template
from re import compile as re_compile
from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
from moto.core import BaseBackend
from moto.core.utils import get_random_hex
@ -82,7 +82,7 @@ class Database(object):
if not self.option_group_name and self.engine in self.default_option_groups:
self.option_group_name = self.default_option_groups[self.engine]
self.character_set_name = kwargs.get('character_set_name', None)
self.tags = kwargs.get('tags', None)
self.tags = kwargs.get('tags', [])
@property
def address(self):
@ -242,6 +242,9 @@ class Database(object):
}""")
return template.render(database=self)
def get_tags(self):
return self.tags
class SecurityGroup(object):
def __init__(self, group_name, description):
@ -384,6 +387,7 @@ class SubnetGroup(object):
class RDS2Backend(BaseBackend):
def __init__(self):
self.arn_regex = re_compile(r'^arn:aws:rds:.*:[0-9]*:db:.*$')
self.databases = {}
self.security_groups = {}
self.subnet_groups = {}
@ -419,6 +423,10 @@ class RDS2Backend(BaseBackend):
database.update(db_kwargs)
return database
def reboot_db_instance(self, db_instance_identifier):
database = self.describe_databases(db_instance_identifier)[0]
return database
def delete_database(self, db_instance_identifier):
if db_instance_identifier in self.databases:
database = self.databases.pop(db_instance_identifier)
@ -579,6 +587,17 @@ class RDS2Backend(BaseBackend):
self.option_groups[option_group_name].add_options(options_to_include)
return self.option_groups[option_group_name]
def list_tags_for_resource(self, arn):
if self.arn_regex.match(arn):
arn_breakdown = arn.split(':')
db_instance_name = arn_breakdown[len(arn_breakdown)-1]
if db_instance_name in self.databases:
return self.databases[db_instance_name].get_tags()
else:
return []
else:
raise RDSClientError('InvalidParameterValue',
'Invalid resource name: {}'.format(arn))
class OptionGroup(object):
def __init__(self, name, engine_name, major_engine_version, description=None):

View File

@ -4,6 +4,7 @@ from moto.core.responses import BaseResponse
from moto.ec2.models import ec2_backends
from .models import rds2_backends
import json
import re
class RDS2Response(BaseResponse):
@ -73,8 +74,10 @@ class RDS2Response(BaseResponse):
result = template.render(database=database)
return result
# TODO: Update function to new method
def create_dbinstance_read_replica(self):
return self.create_db_instance_read_replica()
def create_db_instance_read_replica(self):
db_kwargs = self._get_db_replica_kwargs()
database = self.backend.create_database_replica(db_kwargs)
@ -84,7 +87,7 @@ class RDS2Response(BaseResponse):
def describe_dbinstances(self):
return self.describe_db_instances()
def describe_dbinstances(self):
def describe_db_instances(self):
db_instance_identifier = self._get_param('DBInstanceIdentifier')
databases = self.backend.describe_databases(db_instance_identifier)
template = self.response_template(DESCRIBE_DATABASES_TEMPLATE)
@ -109,6 +112,21 @@ class RDS2Response(BaseResponse):
template = self.response_template(DELETE_DATABASE_TEMPLATE)
return template.render(database=database)
def reboot_dbinstance(self):
return self.reboot_db_instance()
def reboot_db_instance(self):
db_instance_identifier = self._get_param('DBInstanceIdentifier')
database = self.backend.reboot_db_instance(db_instance_identifier)
template = self.response_template(REBOOT_DATABASE_TEMPLATE)
return template.render(database=database)
def list_tags_for_resource(self):
arn = self._get_param('ResourceName')
template = self.response_template(LIST_TAGS_FOR_RESOURCE_TEMPLATE)
tags = self.backend.list_tags_for_resource(arn)
return template.render(tags=tags)
# TODO: Update function to new method
def create_dbsecurity_group(self):
group_name = self._get_param('DBSecurityGroupName')
@ -255,14 +273,24 @@ MODIFY_DATABASE_TEMPLATE = """{"ModifyDBInstanceResponse": {
}
}"""
# TODO: update delete DB TEMPLATE
DELETE_DATABASE_TEMPLATE = """{
"DeleteDBInstanceResponse": {
"DeleteDBInstanceResult": {
},
"ResponseMetadata": { "RequestId": "523e3218-afc7-11c3-90f5-f90431260ab4" }
REBOOT_DATABASE_TEMPLATE = """{"RebootDBInstanceResponse": {
"RebootDBInstanceResult": {
{{ database.to_json() }},
"ResponseMetadata": {
"RequestId": "d55711cb-a1ab-11e4-99cf-55e92d4bbada"
}
}
}"""
}}"""
# TODO: update delete DB TEMPLATE
DELETE_DATABASE_TEMPLATE = """{ "DeleteDBInstanceResponse": {
"DeleteDBInstanceResult": {
{{ database.to_json() }},
"ResponseMetadata": {
"RequestId": "523e3218-afc7-11c3-90f5-f90431260ab4"
}
}
}}"""
CREATE_SECURITY_GROUP_TEMPLATE = """<CreateDBSecurityGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
<CreateDBSecurityGroupResult>
@ -379,3 +407,20 @@ MODIFY_OPTION_GROUP_TEMPLATE = \
{{ option_group.to_json() }}
}
}"""
LIST_TAGS_FOR_RESOURCE_TEMPLATE = \
"""{"ListTagsForResourceResponse":
{"ListTagsForResourceResult":
{"TagList": [
{%- for tag in tags -%}
{%- if loop.index != 1 -%},{%- endif -%}
{%- for key in tag -%}
{"Value": "{{ tag[key] }}", "Key": "{{ key }}"}
{%- endfor -%}
{%- endfor -%}
]},
"ResponseMetadata": {
"RequestId": "8c21ba39-a598-11e4-b688-194eaf8658fa"
}
}
}"""

View File

@ -83,6 +83,36 @@ def test_modify_db_instance():
instances['DescribeDBInstanceResponse']['DescribeDBInstanceResult'][0]['DBInstance']['AllocatedStorage'].should.equal('20')
@disable_on_py3()
@mock_rds2
def test_modify_non_existant_database():
conn = boto.rds2.connect_to_region("us-west-2")
conn.modify_db_instance.when.called_with(db_instance_identifier='not-a-db',
allocated_storage=20,
apply_immediately=True).should.throw(BotoServerError)
@disable_on_py3()
@mock_rds2
def test_reboot_db_instance():
conn = boto.rds2.connect_to_region("us-west-2")
conn.create_db_instance(db_instance_identifier='db-master-1',
allocated_storage=10,
engine='postgres',
db_instance_class='db.m1.small',
master_username='root',
master_user_password='hunter2',
db_security_groups=["my_sg"])
database = conn.reboot_db_instance('db-master-1')
database['RebootDBInstanceResponse']['RebootDBInstanceResult']['DBInstance']['DBInstanceIdentifier'].should.equal("db-master-1")
@disable_on_py3()
@mock_rds2
def test_reboot_non_existant_database():
conn = boto.rds2.connect_to_region("us-west-2")
conn.reboot_db_instance.when.called_with("not-a-db").should.throw(BotoServerError)
@disable_on_py3()
@mock_rds2
def test_delete_database():
@ -104,6 +134,13 @@ def test_delete_database():
list(instances['DescribeDBInstanceResponse']['DescribeDBInstanceResult']).should.have.length_of(0)
@disable_on_py3()
@mock_rds2
def test_delete_non_existant_database():
conn = boto.rds2.connect_to_region("us-west-2")
conn.delete_db_instance.when.called_with("not-a-db").should.throw(BotoServerError)
@disable_on_py3()
@mock_rds2
def test_create_option_group():
@ -227,6 +264,29 @@ def test_delete_non_existant_database():
conn.delete_db_instance.when.called_with("not-a-db").should.throw(BotoServerError)
@disable_on_py3()
@mock_rds2
def test_list_tags_invalid_arn():
conn = boto.rds2.connect_to_region("us-west-2")
conn.list_tags_for_resource.when.called_with('arn:aws:rds:bad-arn').should.throw(BotoServerError)
@disable_on_py3()
@mock_rds2
def test_list_tags():
conn = boto.rds2.connect_to_region("us-west-2")
result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:foo')
result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList'].should.equal([])
conn.create_db_instance(db_instance_identifier='db-master-1',
allocated_storage=10,
engine='postgres',
db_instance_class='db.m1.small',
master_username='root',
master_user_password='hunter2',
db_security_groups=["my_sg"],
tags=[{'Key': 'foo', 'Value': 'bar'}])
result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-master-1')
#@disable_on_py3()
#@mock_rds2
#def test_create_database_security_group():