diff --git a/moto/cloudformation/parsing.py b/moto/cloudformation/parsing.py
index 3e348ac37..521658cee 100644
--- a/moto/cloudformation/parsing.py
+++ b/moto/cloudformation/parsing.py
@@ -14,6 +14,7 @@ from moto.elb import models as elb_models
from moto.iam import models as iam_models
from moto.kms import models as kms_models
from moto.rds import models as rds_models
+from moto.rds2 import models as rds2_models
from moto.redshift import models as redshift_models
from moto.route53 import models as route53_models
from moto.s3 import models as s3_models
@@ -56,6 +57,7 @@ MODEL_MAP = {
"AWS::RDS::DBInstance": rds_models.Database,
"AWS::RDS::DBSecurityGroup": rds_models.SecurityGroup,
"AWS::RDS::DBSubnetGroup": rds_models.SubnetGroup,
+ "AWS::RDS::DBParameterGroup": rds2_models.DBParameterGroup,
"AWS::Redshift::Cluster": redshift_models.Cluster,
"AWS::Redshift::ClusterParameterGroup": redshift_models.ParameterGroup,
"AWS::Redshift::ClusterSubnetGroup": redshift_models.SubnetGroup,
@@ -311,7 +313,8 @@ class ResourceMap(collections.Mapping):
if not resource_json:
raise KeyError(resource_logical_id)
new_resource = parse_and_create_resource(resource_logical_id, resource_json, self, self._region_name)
- self._parsed_resources[resource_logical_id] = new_resource
+ if new_resource is not None:
+ self._parsed_resources[resource_logical_id] = new_resource
return new_resource
def __iter__(self):
diff --git a/moto/rds/models.py b/moto/rds/models.py
index 3ce005e5e..b63a30737 100644
--- a/moto/rds/models.py
+++ b/moto/rds/models.py
@@ -10,6 +10,7 @@ from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
from moto.core import BaseBackend
from moto.core.utils import get_random_hex
from moto.ec2.models import ec2_backends
+from moto.rds2.models import rds2_backends
from .exceptions import DBInstanceNotFoundError, DBSecurityGroupNotFoundError, DBSubnetGroupNotFoundError
@@ -26,6 +27,11 @@ class Database(object):
if self.engine_version is None:
self.engine_version = "5.6.21"
self.iops = kwargs.get("iops")
+ self.storage_encrypted = kwargs.get("storage_encrypted", False)
+ if self.storage_encrypted:
+ self.kms_key_id = kwargs.get("kms_key_id", "default_kms_key_id")
+ else:
+ self.kms_key_id = kwargs.get("kms_key_id")
self.storage_type = kwargs.get("storage_type")
self.master_username = kwargs.get('master_username')
self.master_password = kwargs.get('master_password')
@@ -119,6 +125,7 @@ class Database(object):
"engine": properties.get("Engine"),
"engine_version": properties.get("EngineVersion"),
"iops": properties.get("Iops"),
+ "kms_key_id": properties.get("KmsKeyId"),
"master_password": properties.get('MasterUserPassword'),
"master_username": properties.get('MasterUsername'),
"multi_az": properties.get("MultiAZ"),
@@ -126,7 +133,9 @@ class Database(object):
"publicly_accessible": properties.get("PubliclyAccessible"),
"region": region_name,
"security_groups": security_groups,
+ "storage_encrypted": properties.get("StorageEncrypted"),
"storage_type": properties.get("StorageType"),
+ "tags": properties.get("Tags"),
}
rds_backend = rds_backends[region_name]
@@ -204,6 +213,10 @@ class Database(object):
{{ database.publicly_accessible }}
{{ database.auto_minor_version_upgrade }}
{{ database.allocated_storage }}
+ {{ database.storage_encrypted }}
+ {% if database.kms_key_id %}
+ {{ database.kms_key_id }}
+ {% endif %}
{% if database.iops %}
{{ database.iops }}
io1
@@ -220,6 +233,10 @@ class Database(object):
""")
return template.render(database=self)
+ def delete(self, region_name):
+ backend = rds_backends[region_name]
+ backend.delete_database(self.db_instance_identifier)
+
class SecurityGroup(object):
def __init__(self, group_name, description):
@@ -267,25 +284,33 @@ class SecurityGroup(object):
properties = cloudformation_json['Properties']
group_name = resource_name.lower() + get_random_hex(12)
description = properties['GroupDescription']
- security_group_ingress = properties['DBSecurityGroupIngress']
+ security_group_ingress_rules = properties.get('DBSecurityGroupIngress', [])
+ tags = properties.get('Tags')
ec2_backend = ec2_backends[region_name]
rds_backend = rds_backends[region_name]
security_group = rds_backend.create_security_group(
group_name,
description,
+ tags,
)
- for ingress_type, ingress_value in security_group_ingress.items():
- if ingress_type == "CIDRIP":
- security_group.authorize_cidr(ingress_value)
- elif ingress_type == "EC2SecurityGroupName":
- subnet = ec2_backend.get_security_group_from_name(ingress_value)
- security_group.authorize_security_group(subnet)
- elif ingress_type == "EC2SecurityGroupId":
- subnet = ec2_backend.get_security_group_from_id(ingress_value)
- security_group.authorize_security_group(subnet)
+
+ for security_group_ingress in security_group_ingress_rules:
+ for ingress_type, ingress_value in security_group_ingress.items():
+ if ingress_type == "CIDRIP":
+ security_group.authorize_cidr(ingress_value)
+ elif ingress_type == "EC2SecurityGroupName":
+ subnet = ec2_backend.get_security_group_from_name(ingress_value)
+ security_group.authorize_security_group(subnet)
+ elif ingress_type == "EC2SecurityGroupId":
+ subnet = ec2_backend.get_security_group_from_id(ingress_value)
+ security_group.authorize_security_group(subnet)
return security_group
+ def delete(self, region_name):
+ backend = rds_backends[region_name]
+ backend.delete_security_group(self.group_name)
+
class SubnetGroup(object):
def __init__(self, subnet_name, description, subnets):
@@ -324,6 +349,7 @@ class SubnetGroup(object):
subnet_name = resource_name.lower() + get_random_hex(12)
description = properties['DBSubnetGroupDescription']
subnet_ids = properties['SubnetIds']
+ tags = properties.get('Tags')
ec2_backend = ec2_backends[region_name]
subnets = [ec2_backend.get_subnet(subnet_id) for subnet_id in subnet_ids]
@@ -332,102 +358,31 @@ class SubnetGroup(object):
subnet_name,
description,
subnets,
+ tags,
)
return subnet_group
+ def delete(self, region_name):
+ backend = rds_backends[region_name]
+ backend.delete_subnet_group(self.subnet_name)
+
class RDSBackend(BaseBackend):
- def __init__(self):
- self.databases = {}
- self.security_groups = {}
- self.subnet_groups = {}
+ def __init__(self, region):
+ self.region = region
- def create_database(self, db_kwargs):
- database_id = db_kwargs['db_instance_identifier']
- database = Database(**db_kwargs)
- self.databases[database_id] = database
- return database
+ def __getattr__(self, attr):
+ return self.rds2_backend().__getattribute__(attr)
- def create_database_replica(self, db_kwargs):
- database_id = db_kwargs['db_instance_identifier']
- source_database_id = db_kwargs['source_db_identifier']
- primary = self.describe_databases(source_database_id)[0]
- replica = copy.deepcopy(primary)
- replica.update(db_kwargs)
- replica.set_as_replica()
- self.databases[database_id] = replica
- primary.add_replica(replica)
- return replica
+ def reset(self):
+ # preserve region
+ region = self.region
+ self.rds2_backend().reset()
+ self.__dict__ = {}
+ self.__init__(region)
- def describe_databases(self, db_instance_identifier=None):
- if db_instance_identifier:
- if db_instance_identifier in self.databases:
- return [self.databases[db_instance_identifier]]
- else:
- raise DBInstanceNotFoundError(db_instance_identifier)
- return self.databases.values()
+ def rds2_backend(self):
+ return rds2_backends[self.region]
- def modify_database(self, db_instance_identifier, db_kwargs):
- database = self.describe_databases(db_instance_identifier)[0]
- database.update(db_kwargs)
- return database
-
- def delete_database(self, db_instance_identifier):
- if db_instance_identifier in self.databases:
- database = self.databases.pop(db_instance_identifier)
- if database.is_replica:
- primary = self.describe_databases(database.source_db_identifier)[0]
- primary.remove_replica(database)
- database.status = 'deleting'
- return database
- else:
- raise DBInstanceNotFoundError(db_instance_identifier)
-
- def create_security_group(self, group_name, description):
- security_group = SecurityGroup(group_name, description)
- self.security_groups[group_name] = security_group
- return security_group
-
- def describe_security_groups(self, security_group_name):
- if security_group_name:
- if security_group_name in self.security_groups:
- return [self.security_groups[security_group_name]]
- else:
- raise DBSecurityGroupNotFoundError(security_group_name)
- return self.security_groups.values()
-
- def delete_security_group(self, security_group_name):
- if security_group_name in self.security_groups:
- return self.security_groups.pop(security_group_name)
- else:
- raise DBSecurityGroupNotFoundError(security_group_name)
-
- def authorize_security_group(self, security_group_name, cidr_ip):
- security_group = self.describe_security_groups(security_group_name)[0]
- security_group.authorize_cidr(cidr_ip)
- return security_group
-
- def create_subnet_group(self, subnet_name, description, subnets):
- subnet_group = SubnetGroup(subnet_name, description, subnets)
- self.subnet_groups[subnet_name] = subnet_group
- return subnet_group
-
- def describe_subnet_groups(self, subnet_group_name):
- if subnet_group_name:
- if subnet_group_name in self.subnet_groups:
- return [self.subnet_groups[subnet_group_name]]
- else:
- raise DBSubnetGroupNotFoundError(subnet_group_name)
- return self.subnet_groups.values()
-
- def delete_subnet_group(self, subnet_name):
- if subnet_name in self.subnet_groups:
- return self.subnet_groups.pop(subnet_name)
- else:
- raise DBSubnetGroupNotFoundError(subnet_name)
-
-
-rds_backends = {}
-for region in boto.rds.regions():
- rds_backends[region.name] = RDSBackend()
+rds_backends = dict((region.name, RDSBackend(region.name)) for region in boto.rds.regions())
diff --git a/moto/rds/responses.py b/moto/rds/responses.py
index 98015e7bb..5207264f6 100644
--- a/moto/rds/responses.py
+++ b/moto/rds/responses.py
@@ -12,7 +12,7 @@ class RDSResponse(BaseResponse):
return rds_backends[self.region]
def _get_db_kwargs(self):
- return {
+ args = {
"auto_minor_version_upgrade": self._get_param('AutoMinorVersionUpgrade'),
"allocated_storage": self._get_int_param('AllocatedStorage'),
"availability_zone": self._get_param("AvailabilityZone"),
@@ -25,6 +25,7 @@ class RDSResponse(BaseResponse):
"engine": self._get_param("Engine"),
"engine_version": self._get_param("EngineVersion"),
"iops": self._get_int_param("Iops"),
+ "kms_key_id": self._get_param("KmsKeyId"),
"master_password": self._get_param('MasterUserPassword'),
"master_username": self._get_param('MasterUsername'),
"multi_az": self._get_bool_param("MultiAZ"),
@@ -35,9 +36,13 @@ class RDSResponse(BaseResponse):
"publicly_accessible": self._get_param("PubliclyAccessible"),
"region": self.region,
"security_groups": self._get_multi_param('DBSecurityGroups.member'),
+ "storage_encrypted": self._get_param("StorageEncrypted"),
"storage_type": self._get_param("StorageType"),
# VpcSecurityGroupIds.member.N
+ "tags": list(),
}
+ args['tags'] = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
+ return args
def _get_db_replica_kwargs(self):
return {
@@ -54,6 +59,17 @@ class RDSResponse(BaseResponse):
"storage_type": self._get_param("StorageType"),
}
+ def unpack_complex_list_params(self, label, names):
+ unpacked_list = list()
+ count = 1
+ while self._get_param('{0}.{1}.{2}'.format(label, count, names[0])):
+ param = dict()
+ for i in range(len(names)):
+ param[names[i]] = self._get_param('{0}.{1}.{2}'.format(label, count, names[i]))
+ unpacked_list.append(param)
+ count += 1
+ return unpacked_list
+
def create_dbinstance(self):
db_kwargs = self._get_db_kwargs()
@@ -90,7 +106,8 @@ class RDSResponse(BaseResponse):
def create_dbsecurity_group(self):
group_name = self._get_param('DBSecurityGroupName')
description = self._get_param('DBSecurityGroupDescription')
- security_group = self.backend.create_security_group(group_name, description)
+ tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
+ security_group = self.backend.create_security_group(group_name, description, tags)
template = self.response_template(CREATE_SECURITY_GROUP_TEMPLATE)
return template.render(security_group=security_group)
@@ -118,7 +135,8 @@ class RDSResponse(BaseResponse):
description = self._get_param('DBSubnetGroupDescription')
subnet_ids = self._get_multi_param('SubnetIds.member')
subnets = [ec2_backends[self.region].get_subnet(subnet_id) for subnet_id in subnet_ids]
- subnet_group = self.backend.create_subnet_group(subnet_name, description, subnets)
+ tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
+ subnet_group = self.backend.create_subnet_group(subnet_name, description, subnets, tags)
template = self.response_template(CREATE_SUBNET_GROUP_TEMPLATE)
return template.render(subnet_group=subnet_group)
diff --git a/moto/rds2/exceptions.py b/moto/rds2/exceptions.py
index a5c935659..6fcae4b56 100644
--- a/moto/rds2/exceptions.py
+++ b/moto/rds2/exceptions.py
@@ -1,20 +1,22 @@
from __future__ import unicode_literals
-import json
+from jinja2 import Template
from werkzeug.exceptions import BadRequest
class RDSClientError(BadRequest):
def __init__(self, code, message):
super(RDSClientError, self).__init__()
- self.description = json.dumps({
- "Error": {
- "Code": code,
- "Message": message,
- 'Type': 'Sender',
- },
- 'RequestId': '6876f774-7273-11e4-85dc-39e55ca848d1',
- })
+ template = Template("""
+
+
+ {{ code }}
+ {{ message }}
+ Sender
+
+ 6876f774-7273-11e4-85dc-39e55ca848d1
+ """)
+ self.description = template.render(code=code, message=message)
class DBInstanceNotFoundError(RDSClientError):
@@ -37,3 +39,8 @@ class DBSubnetGroupNotFoundError(RDSClientError):
'DBSubnetGroupNotFound',
"Subnet Group {0} not found.".format(subnet_group_name))
+class DBParameterGroupNotFoundError(RDSClientError):
+ def __init__(self, db_parameter_group_name):
+ super(DBParameterGroupNotFoundError, self).__init__(
+ 'DBParameterGroupNotFound',
+ 'DB Parameter Group {0} not found.'.format(db_parameter_group_name))
diff --git a/moto/rds2/models.py b/moto/rds2/models.py
index 37ecbf873..9bb1f8200 100644
--- a/moto/rds2/models.py
+++ b/moto/rds2/models.py
@@ -2,6 +2,7 @@ from __future__ import unicode_literals
import copy
+from collections import defaultdict
import boto.rds2
import json
from jinja2 import Template
@@ -10,7 +11,12 @@ from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
from moto.core import BaseBackend
from moto.core.utils import get_random_hex
from moto.ec2.models import ec2_backends
-from .exceptions import RDSClientError, DBInstanceNotFoundError, DBSecurityGroupNotFoundError, DBSubnetGroupNotFoundError
+from .exceptions import (RDSClientError,
+ DBInstanceNotFoundError,
+ DBSecurityGroupNotFoundError,
+ DBSubnetGroupNotFoundError,
+ DBParameterGroupNotFoundError)
+
class Database(object):
@@ -35,6 +41,11 @@ class Database(object):
if not self.engine_version and self.engine in self.default_engine_versions:
self.engine_version = self.default_engine_versions[self.engine]
self.iops = kwargs.get("iops")
+ self.storage_encrypted = kwargs.get("storage_encrypted", False)
+ if self.storage_encrypted:
+ self.kms_key_id = kwargs.get("kms_key_id", "default_kms_key_id")
+ else:
+ self.kms_key_id = kwargs.get("kms_key_id")
self.storage_type = kwargs.get("storage_type")
self.master_username = kwargs.get('master_username')
self.master_user_password = kwargs.get('master_user_password')
@@ -64,13 +75,9 @@ class Database(object):
self.security_groups = kwargs.get('security_groups', [])
self.vpc_security_group_ids = kwargs.get('vpc_security_group_ids', [])
self.preferred_maintenance_window = kwargs.get('preferred_maintenance_window', 'wed:06:38-wed:07:08')
- self.db_parameter_group_name = kwargs.get('db_parameter_group_name', None)
- self.default_parameter_groups = {"MySQL": "default.mysql5.6",
- "mysql": "default.mysql5.6",
- "postgres": "default.postgres9.3"
- }
- if not self.db_parameter_group_name and self.engine in self.default_parameter_groups:
- self.db_parameter_group_name = self.default_parameter_groups[self.engine]
+ self.db_parameter_group_name = kwargs.get('db_parameter_group_name')
+ if self.db_parameter_group_name and self.db_parameter_group_name not in rds2_backends[self.region].db_parameter_groups:
+ raise DBParameterGroupNotFoundError(self.db_parameter_group_name)
self.preferred_backup_window = kwargs.get('preferred_backup_window', '13:14-13:44')
self.license_model = kwargs.get('license_model', 'general-public-license')
@@ -84,6 +91,120 @@ class Database(object):
self.character_set_name = kwargs.get('character_set_name', None)
self.tags = kwargs.get('tags', [])
+ @property
+ def physical_resource_id(self):
+ return self.db_instance_identifier
+
+ def db_parameter_groups(self):
+ if not self.db_parameter_group_name:
+ db_family, db_parameter_group_name = self.default_db_parameter_group_details()
+ description = 'Default parameter group for {0}'.format(db_family)
+ return [DBParameterGroup(name=db_parameter_group_name,
+ family=db_family,
+ description=description,
+ tags={})]
+ else:
+ return [rds2_backends[self.region].db_parameter_groups[self.db_parameter_group_name]]
+
+ def default_db_parameter_group_details(self):
+ if not self.engine_version:
+ return (None, None)
+
+ minor_engine_version = '.'.join(self.engine_version.rsplit('.')[:-1])
+ db_family = '{0}{1}'.format(self.engine.lower(), minor_engine_version)
+
+ return db_family, 'default.{0}'.format(db_family)
+
+ def to_xml(self):
+ template = Template("""
+ {{ database.backup_retention_period }}
+ {{ database.status }}
+ {{ database.multi_az }}
+
+ {{ database.db_instance_identifier }}
+ 03:50-04:20
+ wed:06:38-wed:07:08
+
+ {% for replica_id in database.replicas %}
+ {{ replica_id }}
+ {% endfor %}
+
+
+ {% if database.is_replica %}
+
+ read replication
+ replicating
+ true
+
+
+ {% endif %}
+
+ {% if database.is_replica %}
+ {{ database.source_db_identifier }}
+ {% endif %}
+ {{ database.engine }}
+ general-public-license
+ {{ database.engine_version }}
+
+
+
+ {% for db_parameter_group in database.db_parameter_groups() %}
+
+ in-sync
+ {{ db_parameter_group.name }}
+
+ {% endfor %}
+
+
+ {% for security_group in database.security_groups %}
+
+ active
+ {{ security_group }}
+
+ {% endfor %}
+
+ {% if database.db_subnet_group %}
+
+ {{ database.db_subnet_group.subnet_name }}
+ {{ database.db_subnet_group.description }}
+ {{ database.db_subnet_group.status }}
+
+ {% for subnet in database.db_subnet_group.subnets %}
+
+ Active
+ {{ subnet.id }}
+
+ {{ subnet.availability_zone }}
+ false
+
+
+ {% endfor %}
+
+ {{ database.db_subnet_group.vpc_id }}
+
+ {% endif %}
+ {{ database.publicly_accessible }}
+ {{ database.auto_minor_version_upgrade }}
+ {{ database.allocated_storage }}
+ {{ database.storage_encrypted }}
+ {% if database.kms_key_id %}
+ {{ database.kms_key_id }}
+ {% endif %}
+ {% if database.iops %}
+ {{ database.iops }}
+ io1
+ {% else %}
+ {{ database.storage_type }}
+ {% endif %}
+ {{ database.db_instance_class }}
+ {{ database.master_username }}
+
+ {{ database.address }}
+ {{ database.port }}
+
+ """)
+ return template.render(database=self)
+
@property
def address(self):
return "{0}.aaaaaaaaaa.{1}.rds.amazonaws.com".format(self.db_instance_identifier, self.region)
@@ -135,21 +256,25 @@ class Database(object):
"engine": properties.get("Engine"),
"engine_version": properties.get("EngineVersion"),
"iops": properties.get("Iops"),
+ "kms_key_id": properties.get("KmsKeyId"),
"master_user_password": properties.get('MasterUserPassword'),
"master_username": properties.get('MasterUsername'),
"multi_az": properties.get("MultiAZ"),
+ "db_parameter_group_name": properties.get('DBParameterGroupName'),
"port": properties.get('Port', 3306),
"publicly_accessible": properties.get("PubliclyAccessible"),
"region": region_name,
"security_groups": security_groups,
+ "storage_encrypted": properties.get("StorageEncrypted"),
"storage_type": properties.get("StorageType"),
+ "tags": properties.get("Tags"),
}
rds2_backend = rds2_backends[region_name]
source_db_identifier = properties.get("SourceDBInstanceIdentifier")
if source_db_identifier:
# Replica
- db_kwargs["source_db_identifier"] = source_db_identifier.db_instance_identifier
+ db_kwargs["source_db_identifier"] = source_db_identifier
database = rds2_backend.create_database_replica(db_kwargs)
else:
database = rds2_backend.create_database(db_kwargs)
@@ -236,15 +361,19 @@ class Database(object):
def remove_tags(self, tag_keys):
self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in tag_keys]
+ def delete(self, region_name):
+ backend = rds2_backends[region_name]
+ backend.delete_database(self.db_instance_identifier)
+
class SecurityGroup(object):
- def __init__(self, group_name, description):
+ def __init__(self, group_name, description, tags):
self.group_name = group_name
self.description = description
self.status = "authorized"
self.ip_ranges = []
self.ec2_security_groups = []
- self.tags = []
+ self.tags = tags
self.owner_id = '1234567890'
self.vpc_id = None
@@ -301,27 +430,29 @@ class SecurityGroup(object):
properties = cloudformation_json['Properties']
group_name = resource_name.lower() + get_random_hex(12)
description = properties['GroupDescription']
- security_group_ingress = properties['DBSecurityGroupIngress']
+ security_group_ingress_rules = properties.get('DBSecurityGroupIngress', [])
+ tags = properties.get('Tags')
ec2_backend = ec2_backends[region_name]
rds2_backend = rds2_backends[region_name]
security_group = rds2_backend.create_security_group(
group_name,
description,
+ tags,
)
- for ingress_type, ingress_value in security_group_ingress.items():
- if ingress_type == "CIDRIP":
- security_group.authorize_cidr(ingress_value)
- elif ingress_type == "EC2SecurityGroupName":
- subnet = ec2_backend.get_security_group_from_name(ingress_value)
- security_group.authorize_security_group(subnet)
- elif ingress_type == "EC2SecurityGroupId":
- subnet = ec2_backend.get_security_group_from_id(ingress_value)
- security_group.authorize_security_group(subnet)
+ for security_group_ingress in security_group_ingress_rules:
+ for ingress_type, ingress_value in security_group_ingress.items():
+ if ingress_type == "CIDRIP":
+ security_group.authorize_cidr(ingress_value)
+ elif ingress_type == "EC2SecurityGroupName":
+ subnet = ec2_backend.get_security_group_from_name(ingress_value)
+ security_group.authorize_security_group(subnet)
+ elif ingress_type == "EC2SecurityGroupId":
+ subnet = ec2_backend.get_security_group_from_id(ingress_value)
+ security_group.authorize_security_group(subnet)
return security_group
def get_tags(self):
- # TODO: Write tags add/remove/list tests for SecurityGroups
return self.tags
def add_tags(self, tags):
@@ -333,14 +464,18 @@ class SecurityGroup(object):
def remove_tags(self, tag_keys):
self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in tag_keys]
+ def delete(self, region_name):
+ backend = rds2_backends[region_name]
+ backend.delete_security_group(self.group_name)
+
class SubnetGroup(object):
- def __init__(self, subnet_name, description, subnets):
+ def __init__(self, subnet_name, description, subnets, tags):
self.subnet_name = subnet_name
self.description = description
self.subnets = subnets
self.status = "Complete"
- self.tags = []
+ self.tags = tags
self.vpc_id = self.subnets[0].vpc_id
def to_xml(self):
@@ -392,6 +527,7 @@ class SubnetGroup(object):
subnet_name = resource_name.lower() + get_random_hex(12)
description = properties['DBSubnetGroupDescription']
subnet_ids = properties['SubnetIds']
+ tags = properties.get('Tags')
ec2_backend = ec2_backends[region_name]
subnets = [ec2_backend.get_subnet(subnet_id) for subnet_id in subnet_ids]
@@ -400,11 +536,11 @@ class SubnetGroup(object):
subnet_name,
description,
subnets,
+ tags,
)
return subnet_group
def get_tags(self):
- # TODO: Write tags add/remove/list tests for SubnetGroups
return self.tags
def add_tags(self, tags):
@@ -416,15 +552,27 @@ class SubnetGroup(object):
def remove_tags(self, tag_keys):
self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in tag_keys]
+ def delete(self, region_name):
+ backend = rds2_backends[region_name]
+ backend.delete_subnet_group(self.subnet_name)
+
class RDS2Backend(BaseBackend):
- def __init__(self):
+ def __init__(self, region):
+ self.region = region
self.arn_regex = re_compile(r'^arn:aws:rds:.*:[0-9]*:(db|es|og|pg|ri|secgrp|snapshot|subgrp):.*$')
self.databases = {}
+ self.db_parameter_groups = {}
+ self.option_groups = {}
self.security_groups = {}
self.subnet_groups = {}
- self.option_groups = {}
+
+ def reset(self):
+ # preserve region
+ region = self.region
+ self.__dict__ = {}
+ self.__init__(region)
def create_database(self, db_kwargs):
database_id = db_kwargs['db_instance_identifier']
@@ -435,7 +583,10 @@ class RDS2Backend(BaseBackend):
def create_database_replica(self, db_kwargs):
database_id = db_kwargs['db_instance_identifier']
source_database_id = db_kwargs['source_db_identifier']
- primary = self.describe_databases(source_database_id)[0]
+ primary = self.find_db_from_id(source_database_id)
+ if self.arn_regex.match(source_database_id):
+ db_kwargs['region'] = self.region
+
replica = copy.deepcopy(primary)
replica.update(db_kwargs)
replica.set_as_replica()
@@ -460,18 +611,31 @@ class RDS2Backend(BaseBackend):
database = self.describe_databases(db_instance_identifier)[0]
return database
+ def find_db_from_id(self, db_id):
+ if self.arn_regex.match(db_id):
+ arn_breakdown = db_id.split(':')
+ region = arn_breakdown[3]
+ backend = rds2_backends[region]
+ db_name = arn_breakdown[-1]
+ else:
+ backend = self
+ db_name = db_id
+
+ return backend.describe_databases(db_name)[0]
+
def delete_database(self, db_instance_identifier):
if db_instance_identifier in self.databases:
database = self.databases.pop(db_instance_identifier)
if database.is_replica:
- primary = self.describe_databases(database.source_db_identifier)[0]
+ primary = self.find_db_from_id(database.source_db_identifier)
primary.remove_replica(database)
+ database.status = 'deleting'
return database
else:
raise DBInstanceNotFoundError(db_instance_identifier)
- def create_security_group(self, group_name, description):
- security_group = SecurityGroup(group_name, description)
+ def create_security_group(self, group_name, description, tags):
+ security_group = SecurityGroup(group_name, description, tags)
self.security_groups[group_name] = security_group
return security_group
@@ -489,13 +653,19 @@ class RDS2Backend(BaseBackend):
else:
raise DBSecurityGroupNotFoundError(security_group_name)
+ def delete_db_parameter_group(self, db_parameter_group_name):
+ if db_parameter_group_name in self.db_parameter_groups:
+ return self.db_parameter_groups.pop(db_parameter_group_name)
+ else:
+ raise DBParameterGroupNotFoundError(db_parameter_group_name)
+
def authorize_security_group(self, security_group_name, cidr_ip):
security_group = self.describe_security_groups(security_group_name)[0]
security_group.authorize_cidr(cidr_ip)
return security_group
- def create_subnet_group(self, subnet_name, description, subnets):
- subnet_group = SubnetGroup(subnet_name, description, subnets)
+ def create_subnet_group(self, subnet_name, description, subnets, tags):
+ subnet_group = SubnetGroup(subnet_name, description, subnets, tags)
self.subnet_groups[subnet_name] = subnet_group
return subnet_group
@@ -580,24 +750,18 @@ class RDS2Backend(BaseBackend):
@staticmethod
def describe_option_group_options(engine_name, major_engine_version=None):
- default_option_group_options = {
- 'mysql': {'all': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "12", "OptionsDependedOn": [], "MajorEngineVersion": "5.6", "Persistent": false, "DefaultPort": 11211, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies how many memcached read operations (get) to perform before doing a COMMIT to start a new transaction", "DefaultValue": "1", "AllowedValues": "1-4294967295", "IsModifiable": true, "SettingName": "DAEMON_MEMCACHED_R_BATCH_SIZE", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies how many memcached write operations, such as add, set, or incr, to perform before doing a COMMIT to start a new transaction", "DefaultValue": "1", "AllowedValues": "1-4294967295", "IsModifiable": true, "SettingName": "DAEMON_MEMCACHED_W_BATCH_SIZE", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies how often to auto-commit idle connections that use the InnoDB memcached interface.", "DefaultValue": "5", "AllowedValues": "1-1073741824", "IsModifiable": true, "SettingName": "INNODB_API_BK_COMMIT_INTERVAL", "ApplyType": "DYNAMIC"}, {"SettingDescription": "Disables the use of row locks when using the InnoDB memcached interface.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "INNODB_API_DISABLE_ROWLOCK", "ApplyType": "STATIC"}, {"SettingDescription": "Locks the table used by the InnoDB memcached plugin, so that it cannot be dropped or altered by DDL through the SQL interface.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "INNODB_API_ENABLE_MDL", "ApplyType": "STATIC"}, {"SettingDescription": "Lets you control the transaction isolation level on queries processed by the memcached interface.", "DefaultValue": "0", "AllowedValues": "0-3", "IsModifiable": true, "SettingName": "INNODB_API_TRX_LEVEL", "ApplyType": "STATIC"}, {"SettingDescription": "The binding protocol to use which can be either auto, ascii, or binary. The default is auto which means the server automatically negotiates the protocol with the client.", "DefaultValue": "auto", "AllowedValues": "auto,ascii,binary", "IsModifiable": true, "SettingName": "BINDING_PROTOCOL", "ApplyType": "STATIC"}, {"SettingDescription": "The backlog queue configures how many network connections can be waiting to be processed by memcached", "DefaultValue": "1024", "AllowedValues": "1-2048", "IsModifiable": true, "SettingName": "BACKLOG_QUEUE_LIMIT", "ApplyType": "STATIC"}, {"SettingDescription": "Disable the use of compare and swap (CAS) which reduces the per-item size by 8 bytes.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "CAS_DISABLED", "ApplyType": "STATIC"}, {"SettingDescription": "Minimum chunk size in bytes to allocate for the smallest item\'s key, value, and flags. The default is 48 and you can get a significant memory efficiency gain with a lower value.", "DefaultValue": "48", "AllowedValues": "1-48", "IsModifiable": true, "SettingName": "CHUNK_SIZE", "ApplyType": "STATIC"}, {"SettingDescription": "Chunk size growth factor that controls the size of each successive chunk with each chunk growing times this amount larger than the previous chunk.", "DefaultValue": "1.25", "AllowedValues": "1-2", "IsModifiable": true, "SettingName": "CHUNK_SIZE_GROWTH_FACTOR", "ApplyType": "STATIC"}, {"SettingDescription": "If enabled when there is no more memory to store items, memcached will return an error rather than evicting items.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "ERROR_ON_MEMORY_EXHAUSTED", "ApplyType": "STATIC"}, {"SettingDescription": "Maximum number of concurrent connections. Setting this value to anything less than 10 prevents MySQL from starting.", "DefaultValue": "1024", "AllowedValues": "10-1024", "IsModifiable": true, "SettingName": "MAX_SIMULTANEOUS_CONNECTIONS", "ApplyType": "STATIC"}, {"SettingDescription": "Verbose level for memcached.", "DefaultValue": "v", "AllowedValues": "v,vv,vvv", "IsModifiable": true, "SettingName": "VERBOSITY", "ApplyType": "STATIC"}], "EngineName": "mysql", "Name": "MEMCACHED", "PortRequired": true, "Description": "Innodb Memcached for MySQL"}]}, "ResponseMetadata": {"RequestId": "c9847a08-9fca-11e4-9084-5754f80d5144"}}}',
- '5.6': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "12", "OptionsDependedOn": [], "MajorEngineVersion": "5.6", "Persistent": false, "DefaultPort": 11211, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies how many memcached read operations (get) to perform before doing a COMMIT to start a new transaction", "DefaultValue": "1", "AllowedValues": "1-4294967295", "IsModifiable": true, "SettingName": "DAEMON_MEMCACHED_R_BATCH_SIZE", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies how many memcached write operations, such as add, set, or incr, to perform before doing a COMMIT to start a new transaction", "DefaultValue": "1", "AllowedValues": "1-4294967295", "IsModifiable": true, "SettingName": "DAEMON_MEMCACHED_W_BATCH_SIZE", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies how often to auto-commit idle connections that use the InnoDB memcached interface.", "DefaultValue": "5", "AllowedValues": "1-1073741824", "IsModifiable": true, "SettingName": "INNODB_API_BK_COMMIT_INTERVAL", "ApplyType": "DYNAMIC"}, {"SettingDescription": "Disables the use of row locks when using the InnoDB memcached interface.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "INNODB_API_DISABLE_ROWLOCK", "ApplyType": "STATIC"}, {"SettingDescription": "Locks the table used by the InnoDB memcached plugin, so that it cannot be dropped or altered by DDL through the SQL interface.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "INNODB_API_ENABLE_MDL", "ApplyType": "STATIC"}, {"SettingDescription": "Lets you control the transaction isolation level on queries processed by the memcached interface.", "DefaultValue": "0", "AllowedValues": "0-3", "IsModifiable": true, "SettingName": "INNODB_API_TRX_LEVEL", "ApplyType": "STATIC"}, {"SettingDescription": "The binding protocol to use which can be either auto, ascii, or binary. The default is auto which means the server automatically negotiates the protocol with the client.", "DefaultValue": "auto", "AllowedValues": "auto,ascii,binary", "IsModifiable": true, "SettingName": "BINDING_PROTOCOL", "ApplyType": "STATIC"}, {"SettingDescription": "The backlog queue configures how many network connections can be waiting to be processed by memcached", "DefaultValue": "1024", "AllowedValues": "1-2048", "IsModifiable": true, "SettingName": "BACKLOG_QUEUE_LIMIT", "ApplyType": "STATIC"}, {"SettingDescription": "Disable the use of compare and swap (CAS) which reduces the per-item size by 8 bytes.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "CAS_DISABLED", "ApplyType": "STATIC"}, {"SettingDescription": "Minimum chunk size in bytes to allocate for the smallest item\'s key, value, and flags. The default is 48 and you can get a significant memory efficiency gain with a lower value.", "DefaultValue": "48", "AllowedValues": "1-48", "IsModifiable": true, "SettingName": "CHUNK_SIZE", "ApplyType": "STATIC"}, {"SettingDescription": "Chunk size growth factor that controls the size of each successive chunk with each chunk growing times this amount larger than the previous chunk.", "DefaultValue": "1.25", "AllowedValues": "1-2", "IsModifiable": true, "SettingName": "CHUNK_SIZE_GROWTH_FACTOR", "ApplyType": "STATIC"}, {"SettingDescription": "If enabled when there is no more memory to store items, memcached will return an error rather than evicting items.", "DefaultValue": "0", "AllowedValues": "0,1", "IsModifiable": true, "SettingName": "ERROR_ON_MEMORY_EXHAUSTED", "ApplyType": "STATIC"}, {"SettingDescription": "Maximum number of concurrent connections. Setting this value to anything less than 10 prevents MySQL from starting.", "DefaultValue": "1024", "AllowedValues": "10-1024", "IsModifiable": true, "SettingName": "MAX_SIMULTANEOUS_CONNECTIONS", "ApplyType": "STATIC"}, {"SettingDescription": "Verbose level for memcached.", "DefaultValue": "v", "AllowedValues": "v,vv,vvv", "IsModifiable": true, "SettingName": "VERBOSITY", "ApplyType": "STATIC"}], "EngineName": "mysql", "Name": "MEMCACHED", "PortRequired": true, "Description": "Innodb Memcached for MySQL"}]}, "ResponseMetadata": {"RequestId": "c9847a08-9fca-11e4-9084-5754f80d5144"}}}',
- },
- 'sqlserver-ee': {'all': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "2789.0.v1", "OptionsDependedOn": [], "MajorEngineVersion": "10.50", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "Mirroring", "PortRequired": false, "Description": "SQLServer Database Mirroring"}, {"MinimumRequiredMinorEngineVersion": "2789.0.v1", "OptionsDependedOn": [], "MajorEngineVersion": "10.50", "Persistent": true, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "TDE", "PortRequired": false, "Description": "SQL Server - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "2100.60.v1", "OptionsDependedOn": [], "MajorEngineVersion": "11.00", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "Mirroring", "PortRequired": false, "Description": "SQLServer Database Mirroring"}, {"MinimumRequiredMinorEngineVersion": "2100.60.v1", "OptionsDependedOn": [], "MajorEngineVersion": "11.00", "Persistent": true, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "TDE", "PortRequired": false, "Description": "SQL Server - Transparent Data Encryption"}]}, "ResponseMetadata": {"RequestId": "c9f2fd9b-9fcb-11e4-8add-31b6fe33145f"}}}',
- '10.50': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "2789.0.v1", "OptionsDependedOn": [], "MajorEngineVersion": "10.50", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "Mirroring", "PortRequired": false, "Description": "SQLServer Database Mirroring"}, {"MinimumRequiredMinorEngineVersion": "2789.0.v1", "OptionsDependedOn": [], "MajorEngineVersion": "10.50", "Persistent": true, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "TDE", "PortRequired": false, "Description": "SQL Server - Transparent Data Encryption"}]}, "ResponseMetadata": {"RequestId": "e6326fd0-9fcb-11e4-99cf-55e92d4bbada"}}}',
- '11.00': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "2100.60.v1", "OptionsDependedOn": [], "MajorEngineVersion": "11.00", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "Mirroring", "PortRequired": false, "Description": "SQLServer Database Mirroring"}, {"MinimumRequiredMinorEngineVersion": "2100.60.v1", "OptionsDependedOn": [], "MajorEngineVersion": "11.00", "Persistent": true, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "sqlserver-ee", "Name": "TDE", "PortRequired": false, "Description": "SQL Server - Transparent Data Encryption"}]}, "ResponseMetadata": {"RequestId": "222cbeeb-9fcc-11e4-bb07-576f5bf522b5"}}}'
- },
- 'oracle-ee': {'all': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["XMLDB"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX", "PortRequired": false, "Description": "Oracle Application Express Runtime Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["APEX"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX-DEV", "PortRequired": false, "Description": "Oracle Application Express Development Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the desired encryption behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies the desired data integrity behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of encryption algorithms in order of intended use", "DefaultValue": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "AllowedValues": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_TYPES_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of checksumming algorithms in order of intended use", "DefaultValue": "SHA1,MD5", "AllowedValues": "SHA1,MD5", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER", "ApplyType": "STATIC"}], "EngineName": "oracle-ee", "Name": "NATIVE_NETWORK_ENCRYPTION", "PortRequired": false, "Description": "Oracle Advanced Security - Native Network Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": 1158, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "OEM", "PortRequired": true, "Description": "Oracle Enterprise Manager (Database Control only)"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "STATSPACK", "PortRequired": false, "Description": "Oracle Statspack"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE", "PortRequired": false, "Description": "Oracle Advanced Security - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE_HSM", "PortRequired": false, "Description": "Oracle Advanced Security - TDE with HSM"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the timezone the user wants to change the system time to", "DefaultValue": "UTC", "AllowedValues": "Africa/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTC", "IsModifiable": true, "SettingName": "TIME_ZONE", "ApplyType": "DYNAMIC"}], "EngineName": "oracle-ee", "Name": "Timezone", "PortRequired": false, "Description": "Change time zone"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "XMLDB", "PortRequired": false, "Description": "Oracle XMLDB Repository"}]}, "ResponseMetadata": {"RequestId": "36a0a612-9fcc-11e4-a07c-e12b0fcebb71"}}}',
- '11.2': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["XMLDB"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX", "PortRequired": false, "Description": "Oracle Application Express Runtime Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["APEX"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX-DEV", "PortRequired": false, "Description": "Oracle Application Express Development Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the desired encryption behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies the desired data integrity behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of encryption algorithms in order of intended use", "DefaultValue": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "AllowedValues": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_TYPES_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of checksumming algorithms in order of intended use", "DefaultValue": "SHA1,MD5", "AllowedValues": "SHA1,MD5", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER", "ApplyType": "STATIC"}], "EngineName": "oracle-ee", "Name": "NATIVE_NETWORK_ENCRYPTION", "PortRequired": false, "Description": "Oracle Advanced Security - Native Network Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": 1158, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "OEM", "PortRequired": true, "Description": "Oracle Enterprise Manager (Database Control only)"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "STATSPACK", "PortRequired": false, "Description": "Oracle Statspack"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE", "PortRequired": false, "Description": "Oracle Advanced Security - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE_HSM", "PortRequired": false, "Description": "Oracle Advanced Security - TDE with HSM"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the timezone the user wants to change the system time to", "DefaultValue": "UTC", "AllowedValues": "Africa/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTC", "IsModifiable": true, "SettingName": "TIME_ZONE", "ApplyType": "DYNAMIC"}], "EngineName": "oracle-ee", "Name": "Timezone", "PortRequired": false, "Description": "Change time zone"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "XMLDB", "PortRequired": false, "Description": "Oracle XMLDB Repository"}]}, "ResponseMetadata": {"RequestId": "36a0a612-9fcc-11e4-a07c-e12b0fcebb71"}}}'
- },
- 'oracle-sa': {'all': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["XMLDB"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX", "PortRequired": false, "Description": "Oracle Application Express Runtime Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["APEX"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX-DEV", "PortRequired": false, "Description": "Oracle Application Express Development Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the desired encryption behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies the desired data integrity behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of encryption algorithms in order of intended use", "DefaultValue": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "AllowedValues": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_TYPES_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of checksumming algorithms in order of intended use", "DefaultValue": "SHA1,MD5", "AllowedValues": "SHA1,MD5", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER", "ApplyType": "STATIC"}], "EngineName": "oracle-ee", "Name": "NATIVE_NETWORK_ENCRYPTION", "PortRequired": false, "Description": "Oracle Advanced Security - Native Network Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": 1158, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "OEM", "PortRequired": true, "Description": "Oracle Enterprise Manager (Database Control only)"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "STATSPACK", "PortRequired": false, "Description": "Oracle Statspack"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE", "PortRequired": false, "Description": "Oracle Advanced Security - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE_HSM", "PortRequired": false, "Description": "Oracle Advanced Security - TDE with HSM"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the timezone the user wants to change the system time to", "DefaultValue": "UTC", "AllowedValues": "Africa/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTC", "IsModifiable": true, "SettingName": "TIME_ZONE", "ApplyType": "DYNAMIC"}], "EngineName": "oracle-ee", "Name": "Timezone", "PortRequired": false, "Description": "Change time zone"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "XMLDB", "PortRequired": false, "Description": "Oracle XMLDB Repository"}]}, "ResponseMetadata": {"RequestId": "36a0a612-9fcc-11e4-a07c-e12b0fcebb71"}}}',
- '11.2': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["XMLDB"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX", "PortRequired": false, "Description": "Oracle Application Express Runtime Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["APEX"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX-DEV", "PortRequired": false, "Description": "Oracle Application Express Development Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the desired encryption behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies the desired data integrity behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of encryption algorithms in order of intended use", "DefaultValue": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "AllowedValues": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_TYPES_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of checksumming algorithms in order of intended use", "DefaultValue": "SHA1,MD5", "AllowedValues": "SHA1,MD5", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER", "ApplyType": "STATIC"}], "EngineName": "oracle-ee", "Name": "NATIVE_NETWORK_ENCRYPTION", "PortRequired": false, "Description": "Oracle Advanced Security - Native Network Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": 1158, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "OEM", "PortRequired": true, "Description": "Oracle Enterprise Manager (Database Control only)"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "STATSPACK", "PortRequired": false, "Description": "Oracle Statspack"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE", "PortRequired": false, "Description": "Oracle Advanced Security - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE_HSM", "PortRequired": false, "Description": "Oracle Advanced Security - TDE with HSM"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the timezone the user wants to change the system time to", "DefaultValue": "UTC", "AllowedValues": "Africa/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTC", "IsModifiable": true, "SettingName": "TIME_ZONE", "ApplyType": "DYNAMIC"}], "EngineName": "oracle-ee", "Name": "Timezone", "PortRequired": false, "Description": "Change time zone"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "XMLDB", "PortRequired": false, "Description": "Oracle XMLDB Repository"}]}, "ResponseMetadata": {"RequestId": "36a0a612-9fcc-11e4-a07c-e12b0fcebb71"}}}'
- },
- 'oracle-sa1': {'all': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["XMLDB"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX", "PortRequired": false, "Description": "Oracle Application Express Runtime Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["APEX"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX-DEV", "PortRequired": false, "Description": "Oracle Application Express Development Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the desired encryption behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies the desired data integrity behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of encryption algorithms in order of intended use", "DefaultValue": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "AllowedValues": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_TYPES_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of checksumming algorithms in order of intended use", "DefaultValue": "SHA1,MD5", "AllowedValues": "SHA1,MD5", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER", "ApplyType": "STATIC"}], "EngineName": "oracle-ee", "Name": "NATIVE_NETWORK_ENCRYPTION", "PortRequired": false, "Description": "Oracle Advanced Security - Native Network Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": 1158, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "OEM", "PortRequired": true, "Description": "Oracle Enterprise Manager (Database Control only)"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "STATSPACK", "PortRequired": false, "Description": "Oracle Statspack"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE", "PortRequired": false, "Description": "Oracle Advanced Security - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE_HSM", "PortRequired": false, "Description": "Oracle Advanced Security - TDE with HSM"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the timezone the user wants to change the system time to", "DefaultValue": "UTC", "AllowedValues": "Africa/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTC", "IsModifiable": true, "SettingName": "TIME_ZONE", "ApplyType": "DYNAMIC"}], "EngineName": "oracle-ee", "Name": "Timezone", "PortRequired": false, "Description": "Change time zone"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "XMLDB", "PortRequired": false, "Description": "Oracle XMLDB Repository"}]}, "ResponseMetadata": {"RequestId": "36a0a612-9fcc-11e4-a07c-e12b0fcebb71"}}}',
- '11.2': '{"DescribeOptionGroupOptionsResponse": {"DescribeOptionGroupOptionsResult": {"Marker": null, "OptionGroupOptions": [{"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["XMLDB"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX", "PortRequired": false, "Description": "Oracle Application Express Runtime Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": ["APEX"], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "APEX-DEV", "PortRequired": false, "Description": "Oracle Application Express Development Environment"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the desired encryption behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies the desired data integrity behavior", "DefaultValue": "REQUESTED", "AllowedValues": "ACCEPTED,REJECTED,REQUESTED,REQUIRED", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of encryption algorithms in order of intended use", "DefaultValue": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "AllowedValues": "RC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40", "IsModifiable": true, "SettingName": "SQLNET.ENCRYPTION_TYPES_SERVER", "ApplyType": "STATIC"}, {"SettingDescription": "Specifies list of checksumming algorithms in order of intended use", "DefaultValue": "SHA1,MD5", "AllowedValues": "SHA1,MD5", "IsModifiable": true, "SettingName": "SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER", "ApplyType": "STATIC"}], "EngineName": "oracle-ee", "Name": "NATIVE_NETWORK_ENCRYPTION", "PortRequired": false, "Description": "Oracle Advanced Security - Native Network Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": 1158, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "OEM", "PortRequired": true, "Description": "Oracle Enterprise Manager (Database Control only)"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "STATSPACK", "PortRequired": false, "Description": "Oracle Statspack"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE", "PortRequired": false, "Description": "Oracle Advanced Security - Transparent Data Encryption"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "TDE_HSM", "PortRequired": false, "Description": "Oracle Advanced Security - TDE with HSM"}, {"MinimumRequiredMinorEngineVersion": "0.2.v3", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": true, "DefaultPort": null, "Permanent": true, "OptionGroupOptionSettings": [{"SettingDescription": "Specifies the timezone the user wants to change the system time to", "DefaultValue": "UTC", "AllowedValues": "Africa/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTC", "IsModifiable": true, "SettingName": "TIME_ZONE", "ApplyType": "DYNAMIC"}], "EngineName": "oracle-ee", "Name": "Timezone", "PortRequired": false, "Description": "Change time zone"}, {"MinimumRequiredMinorEngineVersion": "0.2.v4", "OptionsDependedOn": [], "MajorEngineVersion": "11.2", "Persistent": false, "DefaultPort": null, "Permanent": false, "OptionGroupOptionSettings": [], "EngineName": "oracle-ee", "Name": "XMLDB", "PortRequired": false, "Description": "Oracle XMLDB Repository"}]}, "ResponseMetadata": {"RequestId": "36a0a612-9fcc-11e4-a07c-e12b0fcebb71"}}}'
- }
- }
+ default_option_group_options = {'mysql': {'5.6': '\n \n \n \n 5.611211TrueInnodb Memcached for MySQLMEMCACHED1-4294967295STATIC1TrueSpecifies how many memcached read operations (get) to perform before doing a COMMIT to start a new transactionDAEMON_MEMCACHED_R_BATCH_SIZE1-4294967295STATIC1TrueSpecifies how many memcached write operations, such as add, set, or incr, to perform before doing a COMMIT to start a new transactionDAEMON_MEMCACHED_W_BATCH_SIZE1-1073741824DYNAMIC5TrueSpecifies how often to auto-commit idle connections that use the InnoDB memcached interface.INNODB_API_BK_COMMIT_INTERVAL0,1STATIC0TrueDisables the use of row locks when using the InnoDB memcached interface.INNODB_API_DISABLE_ROWLOCK0,1STATIC0TrueLocks the table used by the InnoDB memcached plugin, so that it cannot be dropped or altered by DDL through the SQL interface.INNODB_API_ENABLE_MDL0-3STATIC0TrueLets you control the transaction isolation level on queries processed by the memcached interface.INNODB_API_TRX_LEVELauto,ascii,binarySTATICautoTrueThe binding protocol to use which can be either auto, ascii, or binary. The default is auto which means the server automatically negotiates the protocol with the client.BINDING_PROTOCOL1-2048STATIC1024TrueThe backlog queue configures how many network connections can be waiting to be processed by memcachedBACKLOG_QUEUE_LIMIT0,1STATIC0TrueDisable the use of compare and swap (CAS) which reduces the per-item size by 8 bytes.CAS_DISABLED1-48STATIC48TrueMinimum chunk size in bytes to allocate for the smallest item\'s key, value, and flags. The default is 48 and you can get a significant memory efficiency gain with a lower value.CHUNK_SIZE1-2STATIC1.25TrueChunk size growth factor that controls the size of each successive chunk with each chunk growing times this amount larger than the previous chunk.CHUNK_SIZE_GROWTH_FACTOR0,1STATIC0TrueIf enabled when there is no more memory to store items, memcached will return an error rather than evicting items.ERROR_ON_MEMORY_EXHAUSTED10-1024STATIC1024TrueMaximum number of concurrent connections. Setting this value to anything less than 10 prevents MySQL from starting.MAX_SIMULTANEOUS_CONNECTIONSv,vv,vvvSTATICvTrueVerbose level for memcached.VERBOSITYmysql\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n',
+ 'all': '\n \n \n \n 5.611211TrueInnodb Memcached for MySQLMEMCACHED1-4294967295STATIC1TrueSpecifies how many memcached read operations (get) to perform before doing a COMMIT to start a new transactionDAEMON_MEMCACHED_R_BATCH_SIZE1-4294967295STATIC1TrueSpecifies how many memcached write operations, such as add, set, or incr, to perform before doing a COMMIT to start a new transactionDAEMON_MEMCACHED_W_BATCH_SIZE1-1073741824DYNAMIC5TrueSpecifies how often to auto-commit idle connections that use the InnoDB memcached interface.INNODB_API_BK_COMMIT_INTERVAL0,1STATIC0TrueDisables the use of row locks when using the InnoDB memcached interface.INNODB_API_DISABLE_ROWLOCK0,1STATIC0TrueLocks the table used by the InnoDB memcached plugin, so that it cannot be dropped or altered by DDL through the SQL interface.INNODB_API_ENABLE_MDL0-3STATIC0TrueLets you control the transaction isolation level on queries processed by the memcached interface.INNODB_API_TRX_LEVELauto,ascii,binarySTATICautoTrueThe binding protocol to use which can be either auto, ascii, or binary. The default is auto which means the server automatically negotiates the protocol with the client.BINDING_PROTOCOL1-2048STATIC1024TrueThe backlog queue configures how many network connections can be waiting to be processed by memcachedBACKLOG_QUEUE_LIMIT0,1STATIC0TrueDisable the use of compare and swap (CAS) which reduces the per-item size by 8 bytes.CAS_DISABLED1-48STATIC48TrueMinimum chunk size in bytes to allocate for the smallest item\'s key, value, and flags. The default is 48 and you can get a significant memory efficiency gain with a lower value.CHUNK_SIZE1-2STATIC1.25TrueChunk size growth factor that controls the size of each successive chunk with each chunk growing times this amount larger than the previous chunk.CHUNK_SIZE_GROWTH_FACTOR0,1STATIC0TrueIf enabled when there is no more memory to store items, memcached will return an error rather than evicting items.ERROR_ON_MEMORY_EXHAUSTED10-1024STATIC1024TrueMaximum number of concurrent connections. Setting this value to anything less than 10 prevents MySQL from starting.MAX_SIMULTANEOUS_CONNECTIONSv,vv,vvvSTATICvTrueVerbose level for memcached.VERBOSITYmysql\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n'},
+ 'oracle-ee': {'11.2': '\n \n \n \n 11.2XMLDBOracle Application Express Runtime EnvironmentAPEXoracle-ee\n \n 11.2APEXOracle Application Express Development EnvironmentAPEX-DEVoracle-ee\n \n 11.2Oracle Advanced Security - Native Network EncryptionNATIVE_NETWORK_ENCRYPTIONACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired encryption behaviorSQLNET.ENCRYPTION_SERVERACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired data integrity behaviorSQLNET.CRYPTO_CHECKSUM_SERVERRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40STATICRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40TrueSpecifies list of encryption algorithms in order of intended useSQLNET.ENCRYPTION_TYPES_SERVERSHA1,MD5STATICSHA1,MD5TrueSpecifies list of checksumming algorithms in order of intended useSQLNET.CRYPTO_CHECKSUM_TYPES_SERVERoracle-ee\n \n 11.21158TrueOracle Enterprise Manager (Database Control only)OEMoracle-ee\n \n 11.2Oracle StatspackSTATSPACKoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - Transparent Data EncryptionTDEoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - TDE with HSMTDE_HSMoracle-ee\n \n 11.2TrueTrueChange time zoneTimezoneAfrica/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTCDYNAMICUTCTrueSpecifies the timezone the user wants to change the system time toTIME_ZONEoracle-ee\n \n 11.2Oracle XMLDB RepositoryXMLDBoracle-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n',
+ 'all': '\n \n \n \n 11.2XMLDBOracle Application Express Runtime EnvironmentAPEXoracle-ee\n \n 11.2APEXOracle Application Express Development EnvironmentAPEX-DEVoracle-ee\n \n 11.2Oracle Advanced Security - Native Network EncryptionNATIVE_NETWORK_ENCRYPTIONACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired encryption behaviorSQLNET.ENCRYPTION_SERVERACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired data integrity behaviorSQLNET.CRYPTO_CHECKSUM_SERVERRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40STATICRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40TrueSpecifies list of encryption algorithms in order of intended useSQLNET.ENCRYPTION_TYPES_SERVERSHA1,MD5STATICSHA1,MD5TrueSpecifies list of checksumming algorithms in order of intended useSQLNET.CRYPTO_CHECKSUM_TYPES_SERVERoracle-ee\n \n 11.21158TrueOracle Enterprise Manager (Database Control only)OEMoracle-ee\n \n 11.2Oracle StatspackSTATSPACKoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - Transparent Data EncryptionTDEoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - TDE with HSMTDE_HSMoracle-ee\n \n 11.2TrueTrueChange time zoneTimezoneAfrica/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTCDYNAMICUTCTrueSpecifies the timezone the user wants to change the system time toTIME_ZONEoracle-ee\n \n 11.2Oracle XMLDB RepositoryXMLDBoracle-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n'},
+ 'oracle-sa': {'11.2': '\n \n \n \n 11.2XMLDBOracle Application Express Runtime EnvironmentAPEXoracle-ee\n \n 11.2APEXOracle Application Express Development EnvironmentAPEX-DEVoracle-ee\n \n 11.2Oracle Advanced Security - Native Network EncryptionNATIVE_NETWORK_ENCRYPTIONACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired encryption behaviorSQLNET.ENCRYPTION_SERVERACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired data integrity behaviorSQLNET.CRYPTO_CHECKSUM_SERVERRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40STATICRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40TrueSpecifies list of encryption algorithms in order of intended useSQLNET.ENCRYPTION_TYPES_SERVERSHA1,MD5STATICSHA1,MD5TrueSpecifies list of checksumming algorithms in order of intended useSQLNET.CRYPTO_CHECKSUM_TYPES_SERVERoracle-ee\n \n 11.21158TrueOracle Enterprise Manager (Database Control only)OEMoracle-ee\n \n 11.2Oracle StatspackSTATSPACKoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - Transparent Data EncryptionTDEoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - TDE with HSMTDE_HSMoracle-ee\n \n 11.2TrueTrueChange time zoneTimezoneAfrica/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTCDYNAMICUTCTrueSpecifies the timezone the user wants to change the system time toTIME_ZONEoracle-ee\n \n 11.2Oracle XMLDB RepositoryXMLDBoracle-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n',
+ 'all': '\n \n \n \n 11.2XMLDBOracle Application Express Runtime EnvironmentAPEXoracle-ee\n \n 11.2APEXOracle Application Express Development EnvironmentAPEX-DEVoracle-ee\n \n 11.2Oracle Advanced Security - Native Network EncryptionNATIVE_NETWORK_ENCRYPTIONACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired encryption behaviorSQLNET.ENCRYPTION_SERVERACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired data integrity behaviorSQLNET.CRYPTO_CHECKSUM_SERVERRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40STATICRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40TrueSpecifies list of encryption algorithms in order of intended useSQLNET.ENCRYPTION_TYPES_SERVERSHA1,MD5STATICSHA1,MD5TrueSpecifies list of checksumming algorithms in order of intended useSQLNET.CRYPTO_CHECKSUM_TYPES_SERVERoracle-ee\n \n 11.21158TrueOracle Enterprise Manager (Database Control only)OEMoracle-ee\n \n 11.2Oracle StatspackSTATSPACKoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - Transparent Data EncryptionTDEoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - TDE with HSMTDE_HSMoracle-ee\n \n 11.2TrueTrueChange time zoneTimezoneAfrica/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTCDYNAMICUTCTrueSpecifies the timezone the user wants to change the system time toTIME_ZONEoracle-ee\n \n 11.2Oracle XMLDB RepositoryXMLDBoracle-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n'},
+ 'oracle-sa1': {'11.2': '\n \n \n \n 11.2XMLDBOracle Application Express Runtime EnvironmentAPEXoracle-ee\n \n 11.2APEXOracle Application Express Development EnvironmentAPEX-DEVoracle-ee\n \n 11.2Oracle Advanced Security - Native Network EncryptionNATIVE_NETWORK_ENCRYPTIONACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired encryption behaviorSQLNET.ENCRYPTION_SERVERACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired data integrity behaviorSQLNET.CRYPTO_CHECKSUM_SERVERRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40STATICRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40TrueSpecifies list of encryption algorithms in order of intended useSQLNET.ENCRYPTION_TYPES_SERVERSHA1,MD5STATICSHA1,MD5TrueSpecifies list of checksumming algorithms in order of intended useSQLNET.CRYPTO_CHECKSUM_TYPES_SERVERoracle-ee\n \n 11.21158TrueOracle Enterprise Manager (Database Control only)OEMoracle-ee\n \n 11.2Oracle StatspackSTATSPACKoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - Transparent Data EncryptionTDEoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - TDE with HSMTDE_HSMoracle-ee\n \n 11.2TrueTrueChange time zoneTimezoneAfrica/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTCDYNAMICUTCTrueSpecifies the timezone the user wants to change the system time toTIME_ZONEoracle-ee\n \n 11.2Oracle XMLDB RepositoryXMLDBoracle-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n',
+ 'all': '\n \n \n \n 11.2XMLDBOracle Application Express Runtime EnvironmentAPEXoracle-ee\n \n 11.2APEXOracle Application Express Development EnvironmentAPEX-DEVoracle-ee\n \n 11.2Oracle Advanced Security - Native Network EncryptionNATIVE_NETWORK_ENCRYPTIONACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired encryption behaviorSQLNET.ENCRYPTION_SERVERACCEPTED,REJECTED,REQUESTED,REQUIREDSTATICREQUESTEDTrueSpecifies the desired data integrity behaviorSQLNET.CRYPTO_CHECKSUM_SERVERRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40STATICRC4_256,AES256,AES192,3DES168,RC4_128,AES128,3DES112,RC4_56,DES,RC4_40,DES40TrueSpecifies list of encryption algorithms in order of intended useSQLNET.ENCRYPTION_TYPES_SERVERSHA1,MD5STATICSHA1,MD5TrueSpecifies list of checksumming algorithms in order of intended useSQLNET.CRYPTO_CHECKSUM_TYPES_SERVERoracle-ee\n \n 11.21158TrueOracle Enterprise Manager (Database Control only)OEMoracle-ee\n \n 11.2Oracle StatspackSTATSPACKoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - Transparent Data EncryptionTDEoracle-ee\n \n 11.2TrueTrueOracle Advanced Security - TDE with HSMTDE_HSMoracle-ee\n \n 11.2TrueTrueChange time zoneTimezoneAfrica/Cairo,Africa/Casablanca,Africa/Harare,Africa/Monrovia,Africa/Nairobi,Africa/Tripoli,Africa/Windhoek,America/Araguaina,America/Asuncion,America/Bogota,America/Caracas,America/Chihuahua,America/Cuiaba,America/Denver,America/Fortaleza,America/Guatemala,America/Halifax,America/Manaus,America/Matamoros,America/Monterrey,America/Montevideo,America/Phoenix,America/Santiago,America/Tijuana,Asia/Amman,Asia/Ashgabat,Asia/Baghdad,Asia/Baku,Asia/Bangkok,Asia/Beirut,Asia/Calcutta,Asia/Damascus,Asia/Dhaka,Asia/Irkutsk,Asia/Jerusalem,Asia/Kabul,Asia/Karachi,Asia/Kathmandu,Asia/Krasnoyarsk,Asia/Magadan,Asia/Muscat,Asia/Novosibirsk,Asia/Riyadh,Asia/Seoul,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Tehran,Asia/Tokyo,Asia/Ulaanbaatar,Asia/Vladivostok,Asia/Yakutsk,Asia/Yerevan,Atlantic/Azores,Australia/Adelaide,Australia/Brisbane,Australia/Darwin,Australia/Hobart,Australia/Perth,Australia/Sydney,Brazil/East,Canada/Newfoundland,Canada/Saskatchewan,Europe/Amsterdam,Europe/Athens,Europe/Dublin,Europe/Helsinki,Europe/Istanbul,Europe/Kaliningrad,Europe/Moscow,Europe/Paris,Europe/Prague,Europe/Sarajevo,Pacific/Auckland,Pacific/Fiji,Pacific/Guam,Pacific/Honolulu,Pacific/Samoa,US/Alaska,US/Central,US/Eastern,US/East-Indiana,US/Pacific,UTCDYNAMICUTCTrueSpecifies the timezone the user wants to change the system time toTIME_ZONEoracle-ee\n \n 11.2Oracle XMLDB RepositoryXMLDBoracle-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n'},
+ 'sqlserver-ee': {'10.50': '\n \n \n \n 10.50SQLServer Database MirroringMirroringsqlserver-ee\n \n 10.50TrueSQL Server - Transparent Data EncryptionTDEsqlserver-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n',
+ '11.00': '\n \n \n \n 11.00SQLServer Database MirroringMirroringsqlserver-ee\n \n 11.00TrueSQL Server - Transparent Data EncryptionTDEsqlserver-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n',
+ 'all': '\n \n \n \n 10.50SQLServer Database MirroringMirroringsqlserver-ee\n \n 10.50TrueSQL Server - Transparent Data EncryptionTDEsqlserver-ee\n \n 11.00SQLServer Database MirroringMirroringsqlserver-ee\n \n 11.00TrueSQL Server - Transparent Data EncryptionTDEsqlserver-ee\n \n \n \n \n 457f7bb8-9fbf-11e4-9084-5754f80d5144\n \n'}}
+
if engine_name not in default_option_group_options:
raise RDSClientError('InvalidParameterValue', 'Invalid DB engine: {0}'.format(engine_name))
if major_engine_version and major_engine_version not in default_option_group_options[engine_name]:
@@ -620,6 +784,60 @@ class RDS2Backend(BaseBackend):
self.option_groups[option_group_name].add_options(options_to_include)
return self.option_groups[option_group_name]
+ def create_db_parameter_group(self, db_parameter_group_kwargs):
+ db_parameter_group_id = db_parameter_group_kwargs['name']
+ if db_parameter_group_kwargs['name'] in self.db_parameter_groups:
+ raise RDSClientError('DBParameterGroupAlreadyExistsFault',
+ 'A DB parameter group named {0} already exists.'.format(db_parameter_group_kwargs['name']))
+ if not db_parameter_group_kwargs.get('description'):
+ raise RDSClientError('InvalidParameterValue',
+ 'The parameter Description must be provided and must not be blank.')
+ if not db_parameter_group_kwargs.get('family'):
+ raise RDSClientError('InvalidParameterValue',
+ 'The parameter DBParameterGroupName must be provided and must not be blank.')
+
+ db_parameter_group = DBParameterGroup(**db_parameter_group_kwargs)
+ self.db_parameter_groups[db_parameter_group_id] = db_parameter_group
+ return db_parameter_group
+
+ def describe_db_parameter_groups(self, db_parameter_group_kwargs):
+ db_parameter_group_list = []
+
+ if db_parameter_group_kwargs.get('marker'):
+ marker = db_parameter_group_kwargs['marker']
+ else:
+ marker = 0
+ if db_parameter_group_kwargs.get('max_records'):
+ if db_parameter_group_kwargs['max_records'] < 20 or db_parameter_group_kwargs['max_records'] > 100:
+ raise RDSClientError('InvalidParameterValue',
+ 'Invalid value for max records. Must be between 20 and 100')
+ max_records = db_parameter_group_kwargs['max_records']
+ else:
+ max_records = 100
+
+ for db_parameter_group_name, db_parameter_group in self.db_parameter_groups.items():
+ if not db_parameter_group_kwargs.get('name') or db_parameter_group.name == db_parameter_group_kwargs.get('name'):
+ db_parameter_group_list.append(db_parameter_group)
+ else:
+ continue
+
+ return db_parameter_group_list[marker:max_records+marker]
+
+ def modify_db_parameter_group(self, db_parameter_group_name, db_parameter_group_parameters):
+ if db_parameter_group_name not in self.db_parameter_groups:
+ raise DBParameterGroupNotFoundError(db_parameter_group_name)
+
+ db_parameter_group = self.db_parameter_groups[db_parameter_group_name]
+ db_parameter_group.update_parameters(db_parameter_group_parameters)
+
+ return db_parameter_group
+
+ def delete_db_parameter_group(self, db_parameter_group_name):
+ if db_parameter_group_name in self.db_parameter_groups:
+ return self.db_parameter_groups.pop(db_parameter_group_name)
+ else:
+ raise DBParameterGroupNotFoundError(db_parameter_group_name)
+
def list_tags_for_resource(self, arn):
if self.arn_regex.match(arn):
arn_breakdown = arn.split(':')
@@ -635,19 +853,19 @@ class RDS2Backend(BaseBackend):
if resource_name in self.option_groups:
return self.option_groups[resource_name].get_tags()
elif resource_type == 'pg': # Parameter Group
- # TODO: Complete call to tags on resource type Parameter Group
- return []
+ if resource_name in self.db_parameter_groups:
+ return self.db_parameter_groups[resource_name].get_tags()
elif resource_type == 'ri': # Reserved DB instance
# TODO: Complete call to tags on resource type Reserved DB instance
return []
elif resource_type == 'secgrp': # DB security group
- if resource_type in self.security_groups:
+ if resource_name in self.security_groups:
return self.security_groups[resource_name].get_tags()
elif resource_type == 'snapshot': # DB Snapshot
# TODO: Complete call to tags on resource type DB Snapshot
return []
elif resource_type == 'subgrp': # DB subnet group
- if resource_type in self.subnet_groups:
+ if resource_name in self.subnet_groups:
return self.subnet_groups[resource_name].get_tags()
else:
raise RDSClientError('InvalidParameterValue',
@@ -672,16 +890,16 @@ class RDS2Backend(BaseBackend):
elif resource_type == 'ri': # Reserved DB instance
return None
elif resource_type == 'secgrp': # DB security group
- if resource_type in self.security_groups:
+ if resource_name in self.security_groups:
return self.security_groups[resource_name].remove_tags(tag_keys)
elif resource_type == 'snapshot': # DB Snapshot
return None
elif resource_type == 'subgrp': # DB subnet group
- if resource_type in self.subnet_groups:
+ if resource_name in self.subnet_groups:
return self.subnet_groups[resource_name].remove_tags(tag_keys)
else:
raise RDSClientError('InvalidParameterValue',
- 'Invalid resource name: {}'.format(arn))
+ 'Invalid resource name: {0}'.format(arn))
def add_tags_to_resource(self, arn, tags):
if self.arn_regex.match(arn):
@@ -701,16 +919,16 @@ class RDS2Backend(BaseBackend):
elif resource_type == 'ri': # Reserved DB instance
return []
elif resource_type == 'secgrp': # DB security group
- if resource_type in self.security_groups:
+ if resource_name in self.security_groups:
return self.security_groups[resource_name].add_tags(tags)
elif resource_type == 'snapshot': # DB Snapshot
return []
elif resource_type == 'subgrp': # DB subnet group
- if resource_type in self.subnet_groups:
+ if resource_name in self.subnet_groups:
return self.subnet_groups[resource_name].add_tags(tags)
else:
raise RDSClientError('InvalidParameterValue',
- 'Invalid resource name: {}'.format(arn))
+ 'Invalid resource name: {0}'.format(arn))
class OptionGroup(object):
@@ -736,6 +954,17 @@ class OptionGroup(object):
}""")
return template.render(option_group=self)
+ def to_xml(self):
+ template = Template("""
+ {{ option_group.name }}
+ {{ option_group.vpc_and_non_vpc_instance_memberships }}
+ {{ option_group.major_engine_version }}
+ {{ option_group.engine_name }}
+ {{ option_group.description }}
+
+ """)
+ return template.render(option_group=self)
+
def remove_options(self, options_to_remove):
# TODO: Check for option in self.options and remove if exists. Raise error otherwise
return
@@ -758,11 +987,20 @@ class OptionGroup(object):
class OptionGroupOption(object):
- def __init__(self, engine_name, major_engine_version):
- self.engine_name = engine_name
- self.major_engine_version = major_engine_version
- #TODO: Create validation for Options
- #TODO: formulate way to store options settings
+ def __init__(self, **kwargs):
+ self.default_port = kwargs.get('default_port')
+ self.description = kwargs.get('description')
+ self.engine_name = kwargs.get('engine_name')
+ self.major_engine_version = kwargs.get('major_engine_version')
+ self.name = kwargs.get('name')
+ self.option_group_option_settings = self._make_option_group_option_settings(kwargs.get('option_group_option_settings', []))
+ self.options_depended_on = kwargs.get('options_depended_on', [])
+ self.permanent = kwargs.get('permanent')
+ self.persistent = kwargs.get('persistent')
+ self.port_required = kwargs.get('port_required')
+
+ def _make_option_group_option_settings(self, option_group_option_settings_kwargs):
+ return [OptionGroupOptionSetting(**setting_kwargs) for setting_kwargs in option_group_option_settings_kwargs]
def to_json(self):
template = Template("""{ "MinimumRequiredMinorEngineVersion":
@@ -780,7 +1018,109 @@ class OptionGroupOption(object):
}""")
return template.render(option_group=self)
+ def to_xml(self):
+ template = Template("""
+ {{ option_group.major_engine_version }}
+ {{ option_group.default_port }}
+ {{ option_group.port_required }}
+ {{ option_group.persistent }}
+
+ {%- for option_name in option_group.options_depended_on -%}
+ {{ option_name }}
+ {%- endfor -%}
+
+ {{ option_group.permanent }}
+ {{ option_group.description }}
+ {{ option_group.name }}
+
+ {%- for setting in option_group.option_group_option_settings -%}
+ {{ setting.to_xml() }}
+ {%- endfor -%}
+
+ {{ option_group.engine_name }}
+ {{ option_group.minimum_required_minor_engine_version }}
+""")
+ return template.render(option_group=self)
-rds2_backends = {}
-for region in boto.rds2.regions():
- rds2_backends[region.name] = RDS2Backend()
+
+class OptionGroupOptionSetting(object):
+ def __init__(self, *kwargs):
+ self.allowed_values = kwargs.get('allowed_values')
+ self.apply_type = kwargs.get('apply_type')
+ self.default_value = kwargs.get('default_value')
+ self.is_modifiable = kwargs.get('is_modifiable')
+ self.setting_description = kwargs.get('setting_description')
+ self.setting_name = kwargs.get('setting_name')
+
+ def to_xml(self):
+ template = Template("""
+ {{ option_group_option_setting.allowed_values }}
+ {{ option_group_option_setting.apply_type }}
+ {{ option_group_option_setting.default_value }}
+ {{ option_group_option_setting.is_modifiable }}
+ {{ option_group_option_setting.setting_description }}
+ {{ option_group_option_setting.setting_name }}
+""")
+ return template.render(option_group_option_setting=self)
+
+class DBParameterGroup(object):
+ def __init__(self, name, description, family, tags):
+ self.name = name
+ self.description = description
+ self.family = family
+ self.tags = tags
+ self.parameters = defaultdict(dict)
+
+ def to_xml(self):
+ template = Template("""
+ {{ param_group.name }}
+ {{ param_group.family }}
+ {{ param_group.description }}
+ """)
+ return template.render(param_group=self)
+
+ def get_tags(self):
+ return self.tags
+
+ def add_tags(self, tags):
+ new_keys = [tag_set['Key'] for tag_set in tags]
+ self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in new_keys]
+ self.tags.extend(tags)
+ return self.tags
+
+ def remove_tags(self, tag_keys):
+ self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in tag_keys]
+
+ def update_parameters(self, new_parameters):
+ for new_parameter in new_parameters:
+ parameter = self.parameters[new_parameter['ParameterName']]
+ parameter.update(new_parameter)
+
+ def delete(self, region_name):
+ backend = rds2_backends[region_name]
+ backend.delete_db_parameter_group(self.name)
+
+ @classmethod
+ def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
+ properties = cloudformation_json['Properties']
+
+ db_parameter_group_kwargs = {
+ 'description': properties['Description'],
+ 'family': properties['Family'],
+ 'name': resource_name.lower(),
+ 'tags': properties.get("Tags"),
+ }
+ db_parameter_group_parameters = []
+ for db_parameter, db_parameter_value in properties.get('Parameters', {}).items():
+ db_parameter_group_parameters.append({
+ 'ParameterName': db_parameter,
+ 'ParameterValue': db_parameter_value,
+ })
+
+ rds2_backend = rds2_backends[region_name]
+ db_parameter_group = rds2_backend.create_db_parameter_group(db_parameter_group_kwargs)
+ db_parameter_group.update_parameters(db_parameter_group_parameters)
+ return db_parameter_group
+
+
+rds2_backends = dict((region.name, RDS2Backend(region.name)) for region in boto.rds2.regions())
diff --git a/moto/rds2/responses.py b/moto/rds2/responses.py
index bd51f6ea0..879edbdd3 100644
--- a/moto/rds2/responses.py
+++ b/moto/rds2/responses.py
@@ -1,8 +1,10 @@
from __future__ import unicode_literals
+from collections import defaultdict
from moto.core.responses import BaseResponse
from moto.ec2.models import ec2_backends
from .models import rds2_backends
+from .exceptions import DBParameterGroupNotFoundError
import json
import re
@@ -22,11 +24,12 @@ class RDS2Response(BaseResponse):
"db_instance_class": self._get_param('DBInstanceClass'),
"db_instance_identifier": self._get_param('DBInstanceIdentifier'),
"db_name": self._get_param("DBName"),
- # DBParameterGroupName
+ "db_parameter_group_name": self._get_param("DBParameterGroupName"),
"db_subnet_group_name": self._get_param("DBSubnetGroupName"),
"engine": self._get_param("Engine"),
"engine_version": self._get_param("EngineVersion"),
"iops": self._get_int_param("Iops"),
+ "kms_key_id": self._get_param("KmsKeyId"),
"master_user_password": self._get_param('MasterUserPassword'),
"master_username": self._get_param('MasterUsername'),
"multi_az": self._get_bool_param("MultiAZ"),
@@ -36,12 +39,13 @@ class RDS2Response(BaseResponse):
# PreferredMaintenanceWindow
"publicly_accessible": self._get_param("PubliclyAccessible"),
"region": self.region,
- "security_groups": self._get_multi_param('DBSecurityGroups.member'),
+ "security_groups": self._get_multi_param('DBSecurityGroups.DBSecurityGroupName'),
+ "storage_encrypted": self._get_param("StorageEncrypted"),
"storage_type": self._get_param("StorageType"),
# VpcSecurityGroupIds.member.N
- "tags": list()
+ "tags": list(),
}
- args['tags'] = self.unpack_complex_list_params('Tags.member', ('Key', 'Value'))
+ args['tags'] = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
return args
def _get_db_replica_kwargs(self):
@@ -67,6 +71,14 @@ class RDS2Response(BaseResponse):
'name': self._get_param('OptionGroupName')
}
+ def _get_db_parameter_group_kwargs(self):
+ return {
+ 'description': self._get_param('Description'),
+ 'family': self._get_param('DBParameterGroupFamily'),
+ 'name': self._get_param('DBParameterGroupName'),
+ 'tags': self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value')),
+ }
+
def unpack_complex_list_params(self, label, names):
unpacked_list = list()
count = 1
@@ -150,7 +162,7 @@ class RDS2Response(BaseResponse):
def add_tags_to_resource(self):
arn = self._get_param('ResourceName')
- tags = self.unpack_complex_list_params('Tags.member', ('Key', 'Value'))
+ tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
tags = self.backend.add_tags_to_resource(arn, tags)
template = self.response_template(ADD_TAGS_TO_RESOURCE_TEMPLATE)
return template.render(tags=tags)
@@ -168,7 +180,8 @@ class RDS2Response(BaseResponse):
def create_db_security_group(self):
group_name = self._get_param('DBSecurityGroupName')
description = self._get_param('DBSecurityGroupDescription')
- security_group = self.backend.create_security_group(group_name, description)
+ tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
+ security_group = self.backend.create_security_group(group_name, description, tags)
template = self.response_template(CREATE_SECURITY_GROUP_TEMPLATE)
return template.render(security_group=security_group)
@@ -206,9 +219,10 @@ class RDS2Response(BaseResponse):
def create_db_subnet_group(self):
subnet_name = self._get_param('DBSubnetGroupName')
description = self._get_param('DBSubnetGroupDescription')
- subnet_ids = self._get_multi_param('SubnetIds.member')
+ subnet_ids = self._get_multi_param('SubnetIds.SubnetIdentifier')
+ tags = self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value'))
subnets = [ec2_backends[self.region].get_subnet(subnet_id) for subnet_id in subnet_ids]
- subnet_group = self.backend.create_subnet_group(subnet_name, description, subnets)
+ subnet_group = self.backend.create_subnet_group(subnet_name, description, subnets, tags)
template = self.response_template(CREATE_SUBNET_GROUP_TEMPLATE)
return template.render(subnet_group=subnet_group)
@@ -283,225 +297,326 @@ class RDS2Response(BaseResponse):
template = self.response_template(MODIFY_OPTION_GROUP_TEMPLATE)
return template.render(option_group=option_group)
+ def create_dbparameter_group(self):
+ return self.create_db_parameter_group()
-CREATE_DATABASE_TEMPLATE = """{
- "CreateDBInstanceResponse": {
- "CreateDBInstanceResult": {
- "DBInstance": {{ database.to_json() }}
- },
- "ResponseMetadata": { "RequestId": "523e3218-afc7-11c3-90f5-f90431260ab4" }
- }
-}"""
+ def create_db_parameter_group(self):
+ kwargs = self._get_db_parameter_group_kwargs()
+ db_parameter_group = self.backend.create_db_parameter_group(kwargs)
+ template = self.response_template(CREATE_DB_PARAMETER_GROUP_TEMPLATE)
+ return template.render(db_parameter_group=db_parameter_group)
-CREATE_DATABASE_REPLICA_TEMPLATE = """{"CreateDBInstanceReadReplicaResponse": {
- "ResponseMetadata": {
- "RequestId": "5e60c46d-a844-11e4-bb68-17f36418e58f"
- },
- "CreateDBInstanceReadReplicaResult": {
- "DBInstance": {{ database.to_json() }}
- }
-}}"""
+ def describe_dbparameter_groups(self):
+ return self.describe_db_parameter_groups()
-DESCRIBE_DATABASES_TEMPLATE = """{
- "DescribeDBInstancesResponse": {
- "DescribeDBInstancesResult": {
- "DBInstances": [
- {%- for database in databases -%}
- {%- if loop.index != 1 -%},{%- endif -%}
- {{ database.to_json() }}
+ def describe_db_parameter_groups(self):
+ kwargs = self._get_db_parameter_group_kwargs()
+ kwargs['max_records'] = self._get_param('MaxRecords')
+ kwargs['marker'] = self._get_param('Marker')
+ db_parameter_groups = self.backend.describe_db_parameter_groups(kwargs)
+ template = self.response_template(DESCRIBE_DB_PARAMETER_GROUPS_TEMPLATE)
+ return template.render(db_parameter_groups=db_parameter_groups)
+
+ def modify_dbparameter_group(self):
+ return self.modify_db_parameter_group()
+
+ def modify_db_parameter_group(self):
+ db_parameter_group_name = self._get_param('DBParameterGroupName')
+ db_parameter_group_parameters = self._get_db_parameter_group_paramters()
+ db_parameter_group = self.backend.modify_db_parameter_group(db_parameter_group_name,
+ db_parameter_group_parameters)
+ template = self.response_template(MODIFY_DB_PARAMETER_GROUP_TEMPLATE)
+ return template.render(db_parameter_group=db_parameter_group)
+
+ def _get_db_parameter_group_paramters(self):
+ parameter_group_parameters = defaultdict(dict)
+ for param_name, value in self.querystring.items():
+ if not param_name.startswith('Parameters.Parameter'):
+ continue
+
+ split_param_name = param_name.split('.')
+ param_id = split_param_name[2]
+ param_setting = split_param_name[3]
+
+ parameter_group_parameters[param_id][param_setting] = value[0]
+
+ return parameter_group_parameters.values()
+
+ def describe_dbparameters(self):
+ return self.describe_db_parameters()
+
+ def describe_db_parameters(self):
+ db_parameter_group_name = self._get_param('DBParameterGroupName')
+ db_parameter_groups = self.backend.describe_db_parameter_groups({'name': db_parameter_group_name})
+ if not db_parameter_groups:
+ raise DBParameterGroupNotFoundError(db_parameter_group_name)
+
+ template = self.response_template(DESCRIBE_DB_PARAMETERS_TEMPLATE)
+ return template.render(db_parameter_group=db_parameter_groups[0])
+
+ def delete_dbparameter_group(self):
+ return self.delete_db_parameter_group()
+
+ def delete_db_parameter_group(self):
+ kwargs = self._get_db_parameter_group_kwargs()
+ db_parameter_group = self.backend.delete_db_parameter_group(kwargs['name'])
+ template = self.response_template(DELETE_DB_PARAMETER_GROUP_TEMPLATE)
+ return template.render(db_parameter_group=db_parameter_group)
+
+
+CREATE_DATABASE_TEMPLATE = """
+
+ {{ database.to_xml() }}
+
+
+ 523e3218-afc7-11c3-90f5-f90431260ab4
+
+"""
+
+CREATE_DATABASE_REPLICA_TEMPLATE = """
+
+ {{ database.to_xml() }}
+
+
+ 5e60c46d-a844-11e4-bb68-17f36418e58f
+
+"""
+
+DESCRIBE_DATABASES_TEMPLATE = """
+
+
+ {%- for database in databases -%}
+ {{ database.to_xml() }}
+ {%- endfor -%}
+
+
+
+ 523e3218-afc7-11c3-90f5-f90431260ab4
+
+"""
+
+MODIFY_DATABASE_TEMPLATE = """
+
+ {{ database.to_xml() }}
+
+
+ bb58476c-a1a8-11e4-99cf-55e92d4bbada
+
+"""
+
+REBOOT_DATABASE_TEMPLATE = """
+
+ {{ database.to_xml() }}
+
+
+ d55711cb-a1ab-11e4-99cf-55e92d4bbada
+
+"""
+
+
+DELETE_DATABASE_TEMPLATE = """
+
+ {{ database.to_xml() }}
+
+
+ 7369556f-b70d-11c3-faca-6ba18376ea1b
+
+"""
+
+CREATE_SECURITY_GROUP_TEMPLATE = """
+
+ {{ security_group.to_xml() }}
+
+
+ 462165d0-a77a-11e4-a5fa-75b30c556f97
+
+"""
+
+DESCRIBE_SECURITY_GROUPS_TEMPLATE = """
+
+
+ {% for security_group in security_groups %}
+ {{ security_group.to_xml() }}
+ {% endfor %}
+
+
+
+ 5df2014e-a779-11e4-bdb0-594def064d0c
+
+"""
+
+DELETE_SECURITY_GROUP_TEMPLATE = """
+
+ 97e846bd-a77d-11e4-ac58-91351c0f3426
+
+"""
+
+AUTHORIZE_SECURITY_GROUP_TEMPLATE = """
+
+ {{ security_group.to_xml() }}
+
+
+ 75d32fd5-a77e-11e4-8892-b10432f7a87d
+
+"""
+
+CREATE_SUBNET_GROUP_TEMPLATE = """
+
+ {{ subnet_group.to_xml() }}
+
+
+ 3a401b3f-bb9e-11d3-f4c6-37db295f7674
+
+"""
+
+DESCRIBE_SUBNET_GROUPS_TEMPLATE = """
+
+
+ {% for subnet_group in subnet_groups %}
+ {{ subnet_group.to_xml() }}
+ {% endfor %}
+
+
+
+ b783db3b-b98c-11d3-fbc7-5c0aad74da7c
+
+"""
+
+DELETE_SUBNET_GROUP_TEMPLATE = """
+
+ 13785dd5-a7fc-11e4-bb9c-7f371d0859b0
+
+"""
+
+CREATE_OPTION_GROUP_TEMPLATE = """
+
+ {{ option_group.to_xml() }}
+
+
+ 1e38dad4-9f50-11e4-87ea-a31c60ed2e36
+
+"""
+
+DELETE_OPTION_GROUP_TEMPLATE = """
+
+ e2590367-9fa2-11e4-99cf-55e92d41c60e
+
+"""
+
+DESCRIBE_OPTION_GROUP_TEMPLATE = """
+
+
+ {%- for option_group in option_groups -%}
+ {{ option_group.to_xml() }}
+ {%- endfor -%}
+
+
+
+ 4caf445d-9fbc-11e4-87ea-a31c60ed2e36
+
+"""
+
+DESCRIBE_OPTION_GROUP_OPTIONS_TEMPLATE = """
+
+
+ {%- for option_group_option in option_group_options -%}
+ {{ option_group_option.to_xml() }}
+ {%- endfor -%}
+
+
+
+ 457f7bb8-9fbf-11e4-9084-5754f80d5144
+
+"""
+
+MODIFY_OPTION_GROUP_TEMPLATE = """
+
+ {{ option_group.to_xml() }}
+
+
+ ce9284a5-a0de-11e4-b984-a11a53e1f328
+
+"""
+
+CREATE_DB_PARAMETER_GROUP_TEMPLATE = """
+
+ {{ db_parameter_group.to_xml() }}
+
+
+ 7805c127-af22-11c3-96ac-6999cc5f7e72
+
+"""
+
+DESCRIBE_DB_PARAMETER_GROUPS_TEMPLATE = """
+
+
+ {%- for db_parameter_group in db_parameter_groups -%}
+ {{ db_parameter_group.to_xml() }}
+ {%- endfor -%}
+
+
+
+ b75d527a-b98c-11d3-f272-7cd6cce12cc5
+
+"""
+
+MODIFY_DB_PARAMETER_GROUP_TEMPLATE = """
+
+ {{ db_parameter_group.name }}
+
+
+ 12d7435e-bba0-11d3-fe11-33d33a9bb7e3
+
+"""
+
+DELETE_DB_PARAMETER_GROUP_TEMPLATE = """
+
+ cad6c267-ba25-11d3-fe11-33d33a9bb7e3
+
+"""
+
+DESCRIBE_DB_PARAMETERS_TEMPLATE = """
+
+
+ {%- for db_parameter_name, db_parameter in db_parameter_group.parameters.items() -%}
+
+ {%- for parameter_name, parameter_value in db_parameter.items() -%}
+ <{{ parameter_name }}>{{ parameter_value }}{{ parameter_name }}>
{%- endfor -%}
- ]
- },
- "ResponseMetadata": { "RequestId": "523e3218-afc7-11c3-90f5-f90431260ab4" }
- }
-}"""
+
+ {%- endfor -%}
+
+
+
+ 8c40488f-b9ff-11d3-a15e-7ac49293f4fa
+
+
+"""
-MODIFY_DATABASE_TEMPLATE = """{"ModifyDBInstanceResponse": {
- "ModifyDBInstanceResult": {
- "DBInstance": {{ database.to_json() }},
- "ResponseMetadata": {
- "RequestId": "bb58476c-a1a8-11e4-99cf-55e92d4bbada"
- }
- }
- }
-}"""
+LIST_TAGS_FOR_RESOURCE_TEMPLATE = """
+
+
+ {%- for tag in tags -%}
+
+ {{ tag['Key'] }}
+ {{ tag['Value'] }}
+
+ {%- endfor -%}
+
+
+
+ 8c21ba39-a598-11e4-b688-194eaf8658fa
+
+"""
-REBOOT_DATABASE_TEMPLATE = """{"RebootDBInstanceResponse": {
- "RebootDBInstanceResult": {
- "DBInstance": {{ database.to_json() }},
- "ResponseMetadata": {
- "RequestId": "d55711cb-a1ab-11e4-99cf-55e92d4bbada"
- }
- }
- }
-}"""
+ADD_TAGS_TO_RESOURCE_TEMPLATE = """
+
+ b194d9ca-a664-11e4-b688-194eaf8658fa
+
+"""
-
-DELETE_DATABASE_TEMPLATE = """{ "DeleteDBInstanceResponse": {
- "DeleteDBInstanceResult": {
- "DBInstance": {{ database.to_json() }}
- },
- "ResponseMetadata": {
- "RequestId": "523e3218-afc7-11c3-90f5-f90431260ab4"
- }
- }
-}"""
-
-CREATE_SECURITY_GROUP_TEMPLATE = """{"CreateDBSecurityGroupResponse": {
- "CreateDBSecurityGroupResult": {
- "DBSecurityGroup":
- {{ security_group.to_json() }},
- "ResponseMetadata": {
- "RequestId": "462165d0-a77a-11e4-a5fa-75b30c556f97"
- }}
- }
-}"""
-
-DESCRIBE_SECURITY_GROUPS_TEMPLATE = """{
- "DescribeDBSecurityGroupsResponse": {
- "ResponseMetadata": {
- "RequestId": "5df2014e-a779-11e4-bdb0-594def064d0c"
- },
- "DescribeDBSecurityGroupsResult": {
- "Marker": "null",
- "DBSecurityGroups": [
- {% for security_group in security_groups %}
- {%- if loop.index != 1 -%},{%- endif -%}
- {{ security_group.to_json() }}
- {% endfor %}
- ]
- }
- }
-}"""
-
-DELETE_SECURITY_GROUP_TEMPLATE = """{"DeleteDBSecurityGroupResponse": {
- "ResponseMetadata": {
- "RequestId": "97e846bd-a77d-11e4-ac58-91351c0f3426"
- }
-}}"""
-
-AUTHORIZE_SECURITY_GROUP_TEMPLATE = """{
- "AuthorizeDBSecurityGroupIngressResponse": {
- "AuthorizeDBSecurityGroupIngressResult": {
- "DBSecurityGroup": {{ security_group.to_json() }}
- },
- "ResponseMetadata": {
- "RequestId": "75d32fd5-a77e-11e4-8892-b10432f7a87d"
- }
- }
-}"""
-
-CREATE_SUBNET_GROUP_TEMPLATE = """{
- "CreateDBSubnetGroupResponse": {
- "CreateDBSubnetGroupResult":
- { {{ subnet_group.to_json() }} },
- "ResponseMetadata": { "RequestId": "3a401b3f-bb9e-11d3-f4c6-37db295f7674" }
- }
-}"""
-
-DESCRIBE_SUBNET_GROUPS_TEMPLATE = """{
- "DescribeDBSubnetGroupsResponse": {
- "DescribeDBSubnetGroupsResult": {
- "DBSubnetGroups": [
- {% for subnet_group in subnet_groups %}
- { {{ subnet_group.to_json() }} }{%- if not loop.last -%},{%- endif -%}
- {% endfor %}
- ],
- "Marker": null
- },
- "ResponseMetadata": { "RequestId": "b783db3b-b98c-11d3-fbc7-5c0aad74da7c" }
- }
-}"""
-
-
-DELETE_SUBNET_GROUP_TEMPLATE = """{"DeleteDBSubnetGroupResponse": {"ResponseMetadata": {"RequestId": "13785dd5-a7fc-11e4-bb9c-7f371d0859b0"}}}"""
-
-CREATE_OPTION_GROUP_TEMPLATE = """{
- "CreateOptionGroupResponse": {
- "CreateOptionGroupResult": {
- "OptionGroup": {{ option_group.to_json() }}
- },
- "ResponseMetadata": {
- "RequestId": "1e38dad4-9f50-11e4-87ea-a31c60ed2e36"
- }
- }
-}"""
-
-DELETE_OPTION_GROUP_TEMPLATE = \
- """{"DeleteOptionGroupResponse": {"ResponseMetadata": {"RequestId": "e2590367-9fa2-11e4-99cf-55e92d41c60e"}}}"""
-
-DESCRIBE_OPTION_GROUP_TEMPLATE = \
- """{"DescribeOptionGroupsResponse": {
- "DescribeOptionGroupsResult": {
- "Marker": null,
- "OptionGroupsList": [
- {%- for option_group in option_groups -%}
- {%- if loop.index != 1 -%},{%- endif -%}
- {{ option_group.to_json() }}
- {%- endfor -%}
- ]},
- "ResponseMetadata": {"RequestId": "4caf445d-9fbc-11e4-87ea-a31c60ed2e36"}
- }}"""
-
-DESCRIBE_OPTION_GROUP_OPTIONS_TEMPLATE = \
- """{"DescribeOptionGroupOptionsResponse": {
- "DescribeOptionGroupOptionsResult": {
- "Marker": null,
- "OptionGroupOptions": [
- {%- for option_group_option in option_group_options -%}
- {%- if loop.index != 1 -%},{%- endif -%}
- {{ option_group_option.to_json() }}
- {%- endfor -%}
- ]},
- "ResponseMetadata": {"RequestId": "457f7bb8-9fbf-11e4-9084-5754f80d5144"}
- }}"""
-
-MODIFY_OPTION_GROUP_TEMPLATE = \
- """{"ModifyOptionGroupResponse": {
- "ResponseMetadata": {
- "RequestId": "ce9284a5-a0de-11e4-b984-a11a53e1f328"
- },
- "ModifyOptionGroupResult":
- {{ option_group.to_json() }}
- }
- }"""
-
-LIST_TAGS_FOR_RESOURCE_TEMPLATE = \
- """{"ListTagsForResourceResponse":
- {"ListTagsForResourceResult":
- {"TagList": [
- {%- for tag in tags -%}
- {%- if loop.index != 1 -%},{%- endif -%}
- {
- "Key": "{{ tag['Key'] }}",
- "Value": "{{ tag['Value'] }}"
- }
- {%- endfor -%}
- ]},
- "ResponseMetadata": {
- "RequestId": "8c21ba39-a598-11e4-b688-194eaf8658fa"
- }
- }
- }"""
-
-ADD_TAGS_TO_RESOURCE_TEMPLATE = \
- """{"ListTagsForResourceResponse": {
- "ListTagsForResourceResult": {
- "TagList": [
- {%- for tag in tags -%}
- {%- if loop.index != 1 -%},{%- endif -%}
- {
- "Key": "{{ tag['Key'] }}",
- "Value": "{{ tag['Value'] }}"
- }
- {%- endfor -%}
- ]},
- "ResponseMetadata": {
- "RequestId": "b194d9ca-a664-11e4-b688-194eaf8658fa"
- }
- }
- }"""
-
-REMOVE_TAGS_FROM_RESOURCE_TEMPLATE = \
- """{"RemoveTagsFromResourceResponse": {"ResponseMetadata": {"RequestId": "c6499a01-a664-11e4-8069-fb454b71a80e"}}}
- """
+REMOVE_TAGS_FROM_RESOURCE_TEMPLATE = """
+
+ b194d9ca-a664-11e4-b688-194eaf8658fa
+
+"""
diff --git a/tests/test_cloudformation/fixtures/rds_mysql_with_db_parameter_group.py b/tests/test_cloudformation/fixtures/rds_mysql_with_db_parameter_group.py
new file mode 100644
index 000000000..866197125
--- /dev/null
+++ b/tests/test_cloudformation/fixtures/rds_mysql_with_db_parameter_group.py
@@ -0,0 +1,201 @@
+from __future__ import unicode_literals
+
+template = {
+ "AWSTemplateFormatVersion" : "2010-09-09",
+
+ "Description" : "AWS CloudFormation Sample Template RDS_MySQL_With_Read_Replica: Sample template showing how to create a highly-available, RDS DBInstance with a read replica. **WARNING** This template creates an Amazon Relational Database Service database instance and Amazon CloudWatch alarms. You will be billed for the AWS resources used if you create a stack from this template.",
+
+ "Parameters": {
+ "DBName": {
+ "Default": "MyDatabase",
+ "Description" : "The database name",
+ "Type": "String",
+ "MinLength": "1",
+ "MaxLength": "64",
+ "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
+ "ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
+ },
+
+ "DBInstanceIdentifier": {
+ "Type": "String"
+ },
+
+ "DBUser": {
+ "NoEcho": "true",
+ "Description" : "The database admin account username",
+ "Type": "String",
+ "MinLength": "1",
+ "MaxLength": "16",
+ "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
+ "ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
+ },
+
+ "DBPassword": {
+ "NoEcho": "true",
+ "Description" : "The database admin account password",
+ "Type": "String",
+ "MinLength": "1",
+ "MaxLength": "41",
+ "AllowedPattern" : "[a-zA-Z0-9]+",
+ "ConstraintDescription" : "must contain only alphanumeric characters."
+ },
+
+ "DBAllocatedStorage": {
+ "Default": "5",
+ "Description" : "The size of the database (Gb)",
+ "Type": "Number",
+ "MinValue": "5",
+ "MaxValue": "1024",
+ "ConstraintDescription" : "must be between 5 and 1024Gb."
+ },
+
+ "DBInstanceClass": {
+ "Description" : "The database instance type",
+ "Type": "String",
+ "Default": "db.m1.small",
+ "AllowedValues" : [ "db.t1.micro", "db.m1.small", "db.m1.medium", "db.m1.large", "db.m1.xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.m3.medium", "db.m3.large", "db.m3.xlarge", "db.m3.2xlarge", "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.cr1.8xlarge"]
+,
+ "ConstraintDescription" : "must select a valid database instance type."
+ },
+
+ "EC2SecurityGroup": {
+ "Description" : "The EC2 security group that contains instances that need access to the database",
+ "Default": "default",
+ "Type": "String",
+ "AllowedPattern" : "[a-zA-Z0-9\\-]+",
+ "ConstraintDescription" : "must be a valid security group name."
+ },
+
+ "MultiAZ" : {
+ "Description" : "Multi-AZ master database",
+ "Type" : "String",
+ "Default" : "false",
+ "AllowedValues" : [ "true", "false" ],
+ "ConstraintDescription" : "must be true or false."
+ }
+ },
+
+ "Conditions" : {
+ "Is-EC2-VPC" : { "Fn::Or" : [ {"Fn::Equals" : [{"Ref" : "AWS::Region"}, "eu-central-1" ]},
+ {"Fn::Equals" : [{"Ref" : "AWS::Region"}, "cn-north-1" ]}]},
+ "Is-EC2-Classic" : { "Fn::Not" : [{ "Condition" : "Is-EC2-VPC"}]}
+ },
+
+ "Resources" : {
+ "DBParameterGroup": {
+ "Type": "AWS::RDS::DBParameterGroup",
+ "Properties" : {
+ "Description": "DB Parameter Goup",
+ "Family" : "MySQL5.1",
+ "Parameters": {
+ "BACKLOG_QUEUE_LIMIT": "2048"
+ }
+ }
+ },
+
+ "DBEC2SecurityGroup": {
+ "Type": "AWS::EC2::SecurityGroup",
+ "Condition" : "Is-EC2-VPC",
+ "Properties" : {
+ "GroupDescription": "Open database for access",
+ "SecurityGroupIngress" : [{
+ "IpProtocol" : "tcp",
+ "FromPort" : "3306",
+ "ToPort" : "3306",
+ "SourceSecurityGroupName" : { "Ref" : "EC2SecurityGroup" }
+ }]
+ }
+ },
+
+ "DBSecurityGroup": {
+ "Type": "AWS::RDS::DBSecurityGroup",
+ "Condition" : "Is-EC2-Classic",
+ "Properties": {
+ "DBSecurityGroupIngress": [{
+ "EC2SecurityGroupName": { "Ref": "EC2SecurityGroup" }
+ }],
+ "GroupDescription": "database access"
+ }
+ },
+
+ "my_vpc": {
+ "Type" : "AWS::EC2::VPC",
+ "Properties" : {
+ "CidrBlock" : "10.0.0.0/16",
+ }
+ },
+
+ "EC2Subnet": {
+ "Type" : "AWS::EC2::Subnet",
+ "Condition" : "Is-EC2-VPC",
+ "Properties" : {
+ "AvailabilityZone" : "eu-central-1a",
+ "CidrBlock" : "10.0.1.0/24",
+ "VpcId" : { "Ref" : "my_vpc" }
+ }
+ },
+
+ "DBSubnet": {
+ "Type": "AWS::RDS::DBSubnetGroup",
+ "Condition" : "Is-EC2-VPC",
+ "Properties": {
+ "DBSubnetGroupDescription": "my db subnet group",
+ "SubnetIds" : [ { "Ref": "EC2Subnet" } ],
+ }
+ },
+
+ "MasterDB" : {
+ "Type" : "AWS::RDS::DBInstance",
+ "Properties" : {
+ "DBInstanceIdentifier": { "Ref": "DBInstanceIdentifier" },
+ "DBName" : { "Ref" : "DBName" },
+ "AllocatedStorage" : { "Ref" : "DBAllocatedStorage" },
+ "DBInstanceClass" : { "Ref" : "DBInstanceClass" },
+ "Engine" : "MySQL",
+ "DBSubnetGroupName": {"Fn::If": ["Is-EC2-VPC", { "Ref": "DBSubnet" }, { "Ref": "AWS::NoValue" }]},
+ "MasterUsername" : { "Ref" : "DBUser" },
+ "MasterUserPassword" : { "Ref" : "DBPassword" },
+ "MultiAZ" : { "Ref" : "MultiAZ" },
+ "Tags" : [{ "Key" : "Name", "Value" : "Master Database" }],
+ "VPCSecurityGroups": { "Fn::If" : [ "Is-EC2-VPC", [ { "Fn::GetAtt": [ "DBEC2SecurityGroup", "GroupId" ] } ], { "Ref" : "AWS::NoValue"}]},
+ "DBSecurityGroups": { "Fn::If" : [ "Is-EC2-Classic", [ { "Ref": "DBSecurityGroup" } ], { "Ref" : "AWS::NoValue"}]}
+ },
+ "DeletionPolicy" : "Snapshot"
+ },
+
+ "ReplicaDB" : {
+ "Type" : "AWS::RDS::DBInstance",
+ "Properties" : {
+ "SourceDBInstanceIdentifier" : { "Ref" : "MasterDB" },
+ "DBInstanceClass" : { "Ref" : "DBInstanceClass" },
+ "Tags" : [{ "Key" : "Name", "Value" : "Read Replica Database" }]
+ }
+ }
+ },
+
+ "Outputs" : {
+ "EC2Platform" : {
+ "Description" : "Platform in which this stack is deployed",
+ "Value" : { "Fn::If" : [ "Is-EC2-VPC", "EC2-VPC", "EC2-Classic" ]}
+ },
+
+ "MasterJDBCConnectionString": {
+ "Description" : "JDBC connection string for the master database",
+ "Value" : { "Fn::Join": [ "", [ "jdbc:mysql://",
+ { "Fn::GetAtt": [ "MasterDB", "Endpoint.Address" ] },
+ ":",
+ { "Fn::GetAtt": [ "MasterDB", "Endpoint.Port" ] },
+ "/",
+ { "Ref": "DBName" }]]}
+ },
+ "ReplicaJDBCConnectionString": {
+ "Description" : "JDBC connection string for the replica database",
+ "Value" : { "Fn::Join": [ "", [ "jdbc:mysql://",
+ { "Fn::GetAtt": [ "ReplicaDB", "Endpoint.Address" ] },
+ ":",
+ { "Fn::GetAtt": [ "ReplicaDB", "Endpoint.Port" ] },
+ "/",
+ { "Ref": "DBName" }]]}
+ }
+ }
+}
diff --git a/tests/test_cloudformation/fixtures/rds_mysql_with_read_replica.py b/tests/test_cloudformation/fixtures/rds_mysql_with_read_replica.py
index b743f46f4..3e5efa04a 100644
--- a/tests/test_cloudformation/fixtures/rds_mysql_with_read_replica.py
+++ b/tests/test_cloudformation/fixtures/rds_mysql_with_read_replica.py
@@ -82,7 +82,6 @@ template = {
},
"Resources" : {
-
"DBEC2SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Condition" : "Is-EC2-VPC",
@@ -101,9 +100,9 @@ template = {
"Type": "AWS::RDS::DBSecurityGroup",
"Condition" : "Is-EC2-Classic",
"Properties": {
- "DBSecurityGroupIngress": {
+ "DBSecurityGroupIngress": [{
"EC2SecurityGroupName": { "Ref": "EC2SecurityGroup" }
- },
+ }],
"GroupDescription": "database access"
}
},
@@ -188,4 +187,4 @@ template = {
{ "Ref": "DBName" }]]}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/test_cloudformation/test_cloudformation_stack_integration.py b/tests/test_cloudformation/test_cloudformation_stack_integration.py
index 0fb74bef9..ff2cad29e 100644
--- a/tests/test_cloudformation/test_cloudformation_stack_integration.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_integration.py
@@ -27,6 +27,7 @@ from moto import (
mock_kms,
mock_lambda,
mock_rds,
+ mock_rds2,
mock_redshift,
mock_route53,
mock_sns,
@@ -36,6 +37,7 @@ from moto import (
from .fixtures import (
ec2_classic_eip,
fn_join,
+ rds_mysql_with_db_parameter_group,
rds_mysql_with_read_replica,
redshift,
route53_ec2_instance_with_public_ip,
@@ -693,6 +695,44 @@ def test_vpc_single_instance_in_subnet():
eip_resource = [resource for resource in resources if resource.resource_type == 'AWS::EC2::EIP'][0]
eip_resource.physical_resource_id.should.equal(eip.allocation_id)
+@mock_cloudformation()
+@mock_ec2()
+@mock_rds2()
+def test_rds_db_parameter_groups():
+ ec2_conn = boto.ec2.connect_to_region("us-west-1")
+ ec2_conn.create_security_group('application', 'Our Application Group')
+
+ template_json = json.dumps(rds_mysql_with_db_parameter_group.template)
+ conn = boto.cloudformation.connect_to_region("us-west-1")
+ conn.create_stack(
+ "test_stack",
+ template_body=template_json,
+ parameters=[
+ ("DBInstanceIdentifier", "master_db"),
+ ("DBName", "my_db"),
+ ("DBUser", "my_user"),
+ ("DBPassword", "my_password"),
+ ("DBAllocatedStorage", "20"),
+ ("DBInstanceClass", "db.m1.medium"),
+ ("EC2SecurityGroup", "application"),
+ ("MultiAZ", "true"),
+ ],
+ )
+
+ rds_conn = boto3.client('rds', region_name="us-west-1")
+
+ db_parameter_groups = rds_conn.describe_db_parameter_groups()
+ len(db_parameter_groups['DBParameterGroups']).should.equal(1)
+ db_parameter_group_name = db_parameter_groups['DBParameterGroups'][0]['DBParameterGroupName']
+
+ found_cloudformation_set_parameter = False
+ for db_parameter in rds_conn.describe_db_parameters(DBParameterGroupName=db_parameter_group_name)['Parameters']:
+ if db_parameter['ParameterName'] == 'BACKLOG_QUEUE_LIMIT' and db_parameter['ParameterValue'] == '2048':
+ found_cloudformation_set_parameter = True
+
+ found_cloudformation_set_parameter.should.equal(True)
+
+
@mock_cloudformation()
@mock_ec2()
diff --git a/tests/test_rds/test_rds.py b/tests/test_rds/test_rds.py
index df8ede179..6078b5f6b 100644
--- a/tests/test_rds/test_rds.py
+++ b/tests/test_rds/test_rds.py
@@ -238,6 +238,32 @@ def test_create_database_replica():
primary = conn.get_all_dbinstances("db-master-1")[0]
list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0)
+@disable_on_py3()
+@mock_rds
+def test_create_cross_region_database_replica():
+ west_1_conn = boto.rds.connect_to_region("us-west-1")
+ west_2_conn = boto.rds.connect_to_region("us-west-2")
+
+ primary = west_1_conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
+
+ primary_arn = "arn:aws:rds:us-west-1:1234567890:db:db-master-1"
+ replica = west_2_conn.create_dbinstance_read_replica(
+ "replica",
+ primary_arn,
+ "db.m1.small",
+ )
+
+ primary = west_1_conn.get_all_dbinstances("db-master-1")[0]
+ primary.read_replica_dbinstance_identifiers[0].should.equal("replica")
+
+ replica = west_2_conn.get_all_dbinstances("replica")[0]
+ replica.instance_class.should.equal("db.m1.small")
+
+ west_2_conn.delete_dbinstance("replica")
+
+ primary = west_1_conn.get_all_dbinstances("db-master-1")[0]
+ list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0)
+
@disable_on_py3()
@mock_rds
diff --git a/tests/test_rds2/test_rds2.py b/tests/test_rds2/test_rds2.py
index 7ca48f0aa..4e1c2b73c 100644
--- a/tests/test_rds2/test_rds2.py
+++ b/tests/test_rds2/test_rds2.py
@@ -2,479 +2,648 @@ from __future__ import unicode_literals
import boto.rds2
import boto.vpc
-from boto.exception import BotoServerError
+from botocore.exceptions import ClientError, ParamValidationError
+import boto3
import sure # noqa
-from moto import mock_ec2, mock_rds2
+from moto import mock_ec2, mock_kms, mock_rds2
from tests.helpers import disable_on_py3
@disable_on_py3()
@mock_rds2
def test_create_database():
- conn = boto.rds2.connect_to_region("us-west-2")
- database = 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['CreateDBInstanceResponse']['CreateDBInstanceResult']['DBInstance']['DBInstanceStatus'].should.equal('available')
- database['CreateDBInstanceResponse']['CreateDBInstanceResult']['DBInstance']['DBInstanceIdentifier'].should.equal("db-master-1")
- database['CreateDBInstanceResponse']['CreateDBInstanceResult']['DBInstance']['AllocatedStorage'].should.equal('10')
- database['CreateDBInstanceResponse']['CreateDBInstanceResult']['DBInstance']['DBInstanceClass'].should.equal("db.m1.small")
- database['CreateDBInstanceResponse']['CreateDBInstanceResult']['DBInstance']['MasterUsername'].should.equal("root")
- database['CreateDBInstanceResponse']['CreateDBInstanceResult']['DBInstance']['DBSecurityGroups'][0]['DBSecurityGroup']['DBSecurityGroupName'].should.equal('my_sg')
+ conn = boto3.client('rds', region_name='us-west-2')
+ database = conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ Engine='postgres',
+ DBInstanceClass='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=["my_sg"])
+ database['DBInstance']['DBInstanceStatus'].should.equal('available')
+ database['DBInstance']['DBInstanceIdentifier'].should.equal("db-master-1")
+ database['DBInstance']['AllocatedStorage'].should.equal(10)
+ database['DBInstance']['DBInstanceClass'].should.equal("db.m1.small")
+ database['DBInstance']['MasterUsername'].should.equal("root")
+ database['DBInstance']['DBSecurityGroups'][0]['DBSecurityGroupName'].should.equal('my_sg')
@disable_on_py3()
@mock_rds2
def test_get_databases():
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='us-west-2')
instances = conn.describe_db_instances()
- list(instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances']).should.have.length_of(0)
+ list(instances['DBInstances']).should.have.length_of(0)
- 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"])
- conn.create_db_instance(db_instance_identifier='db-master-2',
- allocated_storage=10,
- engine='postgres',
- db_instance_class='db.m1.small',
- master_username='root',
- master_user_password='hunter2',
- db_security_groups=["my_sg"])
+ conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'])
+ conn.create_db_instance(DBInstanceIdentifier='db-master-2',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'])
instances = conn.describe_db_instances()
- list(instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances']).should.have.length_of(2)
+ list(instances['DBInstances']).should.have.length_of(2)
- instances = conn.describe_db_instances("db-master-1")
- list(instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances']).should.have.length_of(1)
- instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['DBInstanceIdentifier'].should.equal("db-master-1")
+ instances = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
+ list(instances['DBInstances']).should.have.length_of(1)
+ instances['DBInstances'][0]['DBInstanceIdentifier'].should.equal("db-master-1")
@disable_on_py3()
@mock_rds2
def test_describe_non_existant_database():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.describe_db_instances.when.called_with("not-a-db").should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.describe_db_instances.when.called_with(DBInstanceIdentifier="not-a-db").should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_modify_db_instance():
- conn = boto.rds2.connect_to_region("us-west-2")
- database = 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"])
- instances = conn.describe_db_instances('db-master-1')
- instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['AllocatedStorage'].should.equal('10')
- conn.modify_db_instance(db_instance_identifier='db-master-1', allocated_storage=20, apply_immediately=True)
- instances = conn.describe_db_instances('db-master-1')
- instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['AllocatedStorage'].should.equal('20')
+ conn = boto3.client('rds', region_name='us-west-2')
+ database = conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'])
+ instances = conn.describe_db_instances(DBInstanceIdentifier='db-master-1')
+ instances['DBInstances'][0]['AllocatedStorage'].should.equal(10)
+ conn.modify_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=20,
+ ApplyImmediately=True)
+ instances = conn.describe_db_instances(DBInstanceIdentifier='db-master-1')
+ instances['DBInstances'][0]['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)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.modify_db_instance.when.called_with(DBInstanceIdentifier='not-a-db',
+ AllocatedStorage=20,
+ ApplyImmediately=True).should.throw(ClientError)
@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")
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'])
+ database = conn.reboot_db_instance(DBInstanceIdentifier='db-master-1')
+ database['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)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.reboot_db_instance.when.called_with(DBInstanceIdentifier="not-a-db").should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_delete_database():
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='us-west-2')
instances = conn.describe_db_instances()
- list(instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances']).should.have.length_of(0)
- 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"])
+ list(instances['DBInstances']).should.have.length_of(0)
+ conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'])
instances = conn.describe_db_instances()
- list(instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances']).should.have.length_of(1)
+ list(instances['DBInstances']).should.have.length_of(1)
- conn.delete_db_instance("db-master-1")
+ conn.delete_db_instance(DBInstanceIdentifier="db-master-1")
instances = conn.describe_db_instances()
- list(instances['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances']).should.have.length_of(0)
+ list(instances['DBInstances']).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)
+ conn = boto3.client('rds2', region_name="us-west-2")
+ conn.delete_db_instance.when.called_with(DBInstanceIdentifier="not-a-db").should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_create_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- option_group = conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- option_group['CreateOptionGroupResponse']['CreateOptionGroupResult']['OptionGroup']['OptionGroupName'].should.equal('test')
- option_group['CreateOptionGroupResponse']['CreateOptionGroupResult']['OptionGroup']['EngineName'].should.equal('mysql')
- option_group['CreateOptionGroupResponse']['CreateOptionGroupResult']['OptionGroup']['OptionGroupDescription'].should.equal('test option group')
- option_group['CreateOptionGroupResponse']['CreateOptionGroupResult']['OptionGroup']['MajorEngineVersion'].should.equal('5.6')
+ conn = boto3.client('rds', region_name='us-west-2')
+ option_group = conn.create_option_group(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group')
+ option_group['OptionGroup']['OptionGroupName'].should.equal('test')
+ option_group['OptionGroup']['EngineName'].should.equal('mysql')
+ option_group['OptionGroup']['OptionGroupDescription'].should.equal('test option group')
+ option_group['OptionGroup']['MajorEngineVersion'].should.equal('5.6')
@disable_on_py3()
@mock_rds2
def test_create_option_group_bad_engine_name():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group.when.called_with('test', 'invalid_engine', '5.6', 'test invalid engine').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group.when.called_with(OptionGroupName='test',
+ EngineName='invalid_engine',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test invalid engine').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_create_option_group_bad_engine_major_version():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group.when.called_with('test', 'mysql', '6.6.6', 'test invalid engine version').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group.when.called_with(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='6.6.6',
+ OptionGroupDescription='test invalid engine version').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_create_option_group_empty_description():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group.when.called_with('test', 'mysql', '5.6', '').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group.when.called_with(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_create_option_group_duplicate():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- conn.create_option_group.when.called_with('test', 'mysql', '5.6', 'foo').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group')
+ conn.create_option_group.when.called_with(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_describe_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- option_groups = conn.describe_option_groups('test')
- option_groups['DescribeOptionGroupsResponse']['DescribeOptionGroupsResult']['OptionGroupsList'][0]['OptionGroupName'].should.equal('test')
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group')
+ option_groups = conn.describe_option_groups(OptionGroupName='test')
+ option_groups['OptionGroupsList'][0]['OptionGroupName'].should.equal('test')
@disable_on_py3()
@mock_rds2
def test_describe_non_existant_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.describe_option_groups.when.called_with("not-a-option-group").should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.describe_option_groups.when.called_with(OptionGroupName="not-a-option-group").should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_delete_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- option_groups = conn.describe_option_groups('test')
- option_groups['DescribeOptionGroupsResponse']['DescribeOptionGroupsResult']['OptionGroupsList'][0]['OptionGroupName'].should.equal('test')
- conn.delete_option_group('test')
- conn.describe_option_groups.when.called_with('test').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group')
+ option_groups = conn.describe_option_groups(OptionGroupName='test')
+ option_groups['OptionGroupsList'][0]['OptionGroupName'].should.equal('test')
+ conn.delete_option_group(OptionGroupName='test')
+ conn.describe_option_groups.when.called_with(OptionGroupName='test').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_delete_non_existant_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.delete_option_group.when.called_with('non-existant').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.delete_option_group.when.called_with(OptionGroupName='non-existant').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_describe_option_group_options():
- conn = boto.rds2.connect_to_region("us-west-2")
- option_group_options = conn.describe_option_group_options('sqlserver-ee')
- len(option_group_options['DescribeOptionGroupOptionsResponse']['DescribeOptionGroupOptionsResult']['OptionGroupOptions']).should.equal(4)
- option_group_options = conn.describe_option_group_options('sqlserver-ee', '11.00')
- len(option_group_options['DescribeOptionGroupOptionsResponse']['DescribeOptionGroupOptionsResult']['OptionGroupOptions']).should.equal(2)
- option_group_options = conn.describe_option_group_options('mysql', '5.6')
- len(option_group_options['DescribeOptionGroupOptionsResponse']['DescribeOptionGroupOptionsResult']['OptionGroupOptions']).should.equal(1)
- conn.describe_option_group_options.when.called_with('non-existent').should.throw(BotoServerError)
- conn.describe_option_group_options.when.called_with('mysql', 'non-existent').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ option_group_options = conn.describe_option_group_options(EngineName='sqlserver-ee')
+ len(option_group_options['OptionGroupOptions']).should.equal(4)
+ option_group_options = conn.describe_option_group_options(EngineName='sqlserver-ee', MajorEngineVersion='11.00')
+ len(option_group_options['OptionGroupOptions']).should.equal(2)
+ option_group_options = conn.describe_option_group_options(EngineName='mysql', MajorEngineVersion='5.6')
+ len(option_group_options['OptionGroupOptions']).should.equal(1)
+ conn.describe_option_group_options.when.called_with(EngineName='non-existent').should.throw(ClientError)
+ conn.describe_option_group_options.when.called_with(EngineName='mysql', MajorEngineVersion='non-existent').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_modify_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test', EngineName='mysql', MajorEngineVersion='5.6', OptionGroupDescription='test option group')
# TODO: create option and validate before deleting.
# if Someone can tell me how the hell to use this function
# to add options to an option_group, I can finish coding this.
- result = conn.modify_option_group('test', [], ['MEMCACHED'], True)
- result['ModifyOptionGroupResponse']['ModifyOptionGroupResult']['EngineName'].should.equal('mysql')
- result['ModifyOptionGroupResponse']['ModifyOptionGroupResult']['Options'].should.equal([])
- result['ModifyOptionGroupResponse']['ModifyOptionGroupResult']['OptionGroupName'].should.equal('test')
+ result = conn.modify_option_group(OptionGroupName='test', OptionsToInclude=[], OptionsToRemove=['MEMCACHED'], ApplyImmediately=True)
+ result['OptionGroup']['EngineName'].should.equal('mysql')
+ result['OptionGroup']['Options'].should.equal([])
+ result['OptionGroup']['OptionGroupName'].should.equal('test')
@disable_on_py3()
@mock_rds2
def test_modify_option_group_no_options():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- conn.modify_option_group.when.called_with('test').should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test', EngineName='mysql', MajorEngineVersion='5.6', OptionGroupDescription='test option group')
+ conn.modify_option_group.when.called_with(OptionGroupName='test').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_modify_non_existant_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.modify_option_group.when.called_with('non-existant', [('OptionName', 'Port', 'DBSecurityGroupMemberships', 'VpcSecurityGroupMemberships', 'OptionSettings')]).should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.modify_option_group.when.called_with(OptionGroupName='non-existant', OptionsToInclude=[('OptionName', 'Port', 'DBSecurityGroupMemberships', 'VpcSecurityGroupMemberships', 'OptionSettings')]).should.throw(ParamValidationError)
@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)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.delete_db_instance.when.called_with(DBInstanceIdentifier="not-a-db").should.throw(ClientError)
@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)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.list_tags_for_resource.when.called_with(ResourceName='arn:aws:rds:bad-arn').should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_list_tags_db():
- 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-with-tags',
- allocated_storage=10,
- engine='postgres',
- db_instance_class='db.m1.small',
- master_username='root',
- master_user_password='hunter2',
- db_security_groups=["my_sg"],
- tags=[('foo', 'bar'), ('foo1', 'bar1')])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags')
- result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList'].should.equal([{'Value': 'bar',
- 'Key': 'foo'},
- {'Value': 'bar1',
- 'Key': 'foo1'}])
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:foo')
+ result['TagList'].should.equal([])
+ conn.create_db_instance(DBInstanceIdentifier='db-with-tags',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'],
+ Tags=[
+ {
+ 'Key': 'foo',
+ 'Value': 'bar',
+ },
+ {
+ 'Key': 'foo1',
+ 'Value': 'bar1',
+ },
+ ])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-with-tags')
+ result['TagList'].should.equal([{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
@disable_on_py3()
@mock_rds2
def test_add_tags_db():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_db_instance(db_instance_identifier='db-without-tags',
- allocated_storage=10,
- engine='postgres',
- db_instance_class='db.m1.small',
- master_username='root',
- master_user_password='hunter2',
- db_security_groups=["my_sg"],
- tags=[('foo', 'bar'), ('foo1', 'bar1')])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-without-tags')
- list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(2)
- conn.add_tags_to_resource('arn:aws:rds:us-west-2:1234567890:db:db-without-tags',
- [('foo', 'fish'), ('foo2', 'bar2')])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-without-tags')
- list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(3)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_instance(DBInstanceIdentifier='db-without-tags',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'],
+ Tags=[
+ {
+ 'Key': 'foo',
+ 'Value': 'bar',
+ },
+ {
+ 'Key': 'foo1',
+ 'Value': 'bar1',
+ },
+ ])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-without-tags')
+ list(result['TagList']).should.have.length_of(2)
+ conn.add_tags_to_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-without-tags',
+ Tags=[
+ {
+ 'Key': 'foo',
+ 'Value': 'fish',
+ },
+ {
+ 'Key': 'foo2',
+ 'Value': 'bar2',
+ },
+ ])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-without-tags')
+ list(result['TagList']).should.have.length_of(3)
@disable_on_py3()
@mock_rds2
def test_remove_tags_db():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_db_instance(db_instance_identifier='db-with-tags',
- allocated_storage=10,
- engine='postgres',
- db_instance_class='db.m1.small',
- master_username='root',
- master_user_password='hunter2',
- db_security_groups=["my_sg"],
- tags=[('foo', 'bar'), ('foo1', 'bar1')])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags')
- len(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.equal(2)
- conn.remove_tags_from_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags', ['foo'])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags')
- len(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.equal(1)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_instance(DBInstanceIdentifier='db-with-tags',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=['my_sg'],
+ Tags=[
+ {
+ 'Key': 'foo',
+ 'Value': 'bar',
+ },
+ {
+ 'Key': 'foo1',
+ 'Value': 'bar1',
+ },
+ ])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-with-tags')
+ list(result['TagList']).should.have.length_of(2)
+ conn.remove_tags_from_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-with-tags', TagKeys=['foo'])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:db:db-with-tags')
+ len(result['TagList']).should.equal(1)
@disable_on_py3()
@mock_rds2
def test_add_tags_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:og:test')
- list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(0)
- conn.add_tags_to_resource('arn:aws:rds:us-west-2:1234567890:og:test',
- [('foo', 'fish'), ('foo2', 'bar2')])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:og:test')
- list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(2)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group')
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test')
+ list(result['TagList']).should.have.length_of(0)
+ conn.add_tags_to_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test',
+ Tags=[
+ {
+ 'Key': 'foo',
+ 'Value': 'fish',
+ },
+ {
+ 'Key': 'foo2',
+ 'Value': 'bar2',
+ }])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test')
+ list(result['TagList']).should.have.length_of(2)
@disable_on_py3()
@mock_rds2
def test_remove_tags_option_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_option_group('test', 'mysql', '5.6', 'test option group')
- conn.add_tags_to_resource('arn:aws:rds:us-west-2:1234567890:og:test',
- [('foo', 'fish'), ('foo2', 'bar2')])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:og:test')
- list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(2)
- conn.remove_tags_from_resource('arn:aws:rds:us-west-2:1234567890:og:test',
- ['foo'])
- result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:og:test')
- list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(1)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_option_group(OptionGroupName='test',
+ EngineName='mysql',
+ MajorEngineVersion='5.6',
+ OptionGroupDescription='test option group')
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test')
+ conn.add_tags_to_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test',
+ Tags=[
+ {
+ 'Key': 'foo',
+ 'Value': 'fish',
+ },
+ {
+ 'Key': 'foo2',
+ 'Value': 'bar2',
+ }])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test')
+ list(result['TagList']).should.have.length_of(2)
+ conn.remove_tags_from_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test',
+ TagKeys=['foo'])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:og:test')
+ list(result['TagList']).should.have.length_of(1)
@disable_on_py3()
@mock_rds2
def test_create_database_security_group():
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='us-west-2')
- result = conn.create_db_security_group('db_sg', 'DB Security Group')
- result['CreateDBSecurityGroupResponse']['CreateDBSecurityGroupResult']['DBSecurityGroup']['DBSecurityGroupName'].should.equal("db_sg")
- result['CreateDBSecurityGroupResponse']['CreateDBSecurityGroupResult']['DBSecurityGroup']['DBSecurityGroupDescription'].should.equal("DB Security Group")
- result['CreateDBSecurityGroupResponse']['CreateDBSecurityGroupResult']['DBSecurityGroup']['IPRanges'].should.equal([])
+ result = conn.create_db_security_group(DBSecurityGroupName='db_sg', DBSecurityGroupDescription='DB Security Group')
+ result['DBSecurityGroup']['DBSecurityGroupName'].should.equal("db_sg")
+ result['DBSecurityGroup']['DBSecurityGroupDescription'].should.equal("DB Security Group")
+ result['DBSecurityGroup']['IPRanges'].should.equal([])
@disable_on_py3()
@mock_rds2
def test_get_security_groups():
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='us-west-2')
result = conn.describe_db_security_groups()
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'].should.have.length_of(0)
+ result['DBSecurityGroups'].should.have.length_of(0)
- conn.create_db_security_group('db_sg1', 'DB Security Group')
- conn.create_db_security_group('db_sg2', 'DB Security Group')
+ conn.create_db_security_group(DBSecurityGroupName='db_sg1', DBSecurityGroupDescription='DB Security Group')
+ conn.create_db_security_group(DBSecurityGroupName='db_sg2', DBSecurityGroupDescription='DB Security Group')
result = conn.describe_db_security_groups()
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'].should.have.length_of(2)
+ result['DBSecurityGroups'].should.have.length_of(2)
- result = conn.describe_db_security_groups("db_sg1")
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'].should.have.length_of(1)
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'][0]['DBSecurityGroupName'].should.equal("db_sg1")
+ result = conn.describe_db_security_groups(DBSecurityGroupName="db_sg1")
+ result['DBSecurityGroups'].should.have.length_of(1)
+ result['DBSecurityGroups'][0]['DBSecurityGroupName'].should.equal("db_sg1")
@disable_on_py3()
@mock_rds2
def test_get_non_existant_security_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.describe_db_security_groups.when.called_with("not-a-sg").should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.describe_db_security_groups.when.called_with(DBSecurityGroupName="not-a-sg").should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_delete_database_security_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_db_security_group('db_sg', 'DB Security Group')
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_security_group(DBSecurityGroupName='db_sg', DBSecurityGroupDescription='DB Security Group')
result = conn.describe_db_security_groups()
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'].should.have.length_of(1)
+ result['DBSecurityGroups'].should.have.length_of(1)
- conn.delete_db_security_group("db_sg")
+ conn.delete_db_security_group(DBSecurityGroupName="db_sg")
result = conn.describe_db_security_groups()
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'].should.have.length_of(0)
+ result['DBSecurityGroups'].should.have.length_of(0)
@disable_on_py3()
@mock_rds2
def test_delete_non_existant_security_group():
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.delete_db_security_group.when.called_with("not-a-db").should.throw(BotoServerError)
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.delete_db_security_group.when.called_with(DBSecurityGroupName="not-a-db").should.throw(ClientError)
@disable_on_py3()
@mock_rds2
def test_security_group_authorize():
- conn = boto.rds2.connect_to_region("us-west-2")
- security_group = conn.create_db_security_group('db_sg', 'DB Security Group')
- security_group['CreateDBSecurityGroupResponse']['CreateDBSecurityGroupResult']['DBSecurityGroup']['IPRanges'].should.equal([])
+ conn = boto3.client('rds', region_name='us-west-2')
+ security_group = conn.create_db_security_group(DBSecurityGroupName='db_sg',
+ DBSecurityGroupDescription='DB Security Group')
+ security_group['DBSecurityGroup']['IPRanges'].should.equal([])
- conn.authorize_db_security_group_ingress(db_security_group_name='db_sg',
- cidrip='10.3.2.45/32')
+ conn.authorize_db_security_group_ingress(DBSecurityGroupName='db_sg',
+ CIDRIP='10.3.2.45/32')
- result = conn.describe_db_security_groups("db_sg")
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'][0]['IPRanges'].should.have.length_of(1)
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'][0]['IPRanges'].should.equal(['10.3.2.45/32'])
+ result = conn.describe_db_security_groups(DBSecurityGroupName="db_sg")
+ result['DBSecurityGroups'][0]['IPRanges'].should.have.length_of(1)
+ result['DBSecurityGroups'][0]['IPRanges'].should.equal([{'Status': 'authorized', 'CIDRIP': '10.3.2.45/32'}])
- conn.authorize_db_security_group_ingress(db_security_group_name='db_sg',
- cidrip='10.3.2.46/32')
- result = conn.describe_db_security_groups("db_sg")
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'][0]['IPRanges'].should.have.length_of(2)
- result['DescribeDBSecurityGroupsResponse']['DescribeDBSecurityGroupsResult']['DBSecurityGroups'][0]['IPRanges'].should.equal(['10.3.2.45/32', '10.3.2.46/32'])
+ conn.authorize_db_security_group_ingress(DBSecurityGroupName='db_sg',
+ CIDRIP='10.3.2.46/32')
+ result = conn.describe_db_security_groups(DBSecurityGroupName="db_sg")
+ result['DBSecurityGroups'][0]['IPRanges'].should.have.length_of(2)
+ result['DBSecurityGroups'][0]['IPRanges'].should.equal([
+ {'Status': 'authorized', 'CIDRIP': '10.3.2.45/32'},
+ {'Status': 'authorized', 'CIDRIP': '10.3.2.46/32'},
+ ])
@disable_on_py3()
@mock_rds2
def test_add_security_group_to_database():
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='us-west-2')
+
+ conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ DBInstanceClass='postgres',
+ Engine='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234)
- 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')
result = conn.describe_db_instances()
- result['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['DBSecurityGroups'].should.equal([])
- conn.create_db_security_group('db_sg', 'DB Security Group')
- conn.modify_db_instance(db_instance_identifier='db-master-1',
- db_security_groups=['db_sg'])
+ result['DBInstances'][0]['DBSecurityGroups'].should.equal([])
+ conn.create_db_security_group(DBSecurityGroupName='db_sg',
+ DBSecurityGroupDescription='DB Security Group')
+ conn.modify_db_instance(DBInstanceIdentifier='db-master-1',
+ DBSecurityGroups=['db_sg'])
result = conn.describe_db_instances()
- result['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['DBSecurityGroups'][0]['DBSecurityGroup']['DBSecurityGroupName'].should.equal('db_sg')
+ result['DBInstances'][0]['DBSecurityGroups'][0]['DBSecurityGroupName'].should.equal('db_sg')
+
+
+@disable_on_py3()
+@mock_rds2
+def test_list_tags_security_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.describe_db_subnet_groups()
+ result['DBSubnetGroups'].should.have.length_of(0)
+
+ security_group = conn.create_db_security_group(DBSecurityGroupName="db_sg",
+ DBSecurityGroupDescription='DB Security Group',
+ Tags=[{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])['DBSecurityGroup']['DBSecurityGroupName']
+ resource = 'arn:aws:rds:us-west-2:1234567890:secgrp:{0}'.format(security_group)
+ result = conn.list_tags_for_resource(ResourceName=resource)
+ result['TagList'].should.equal([{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
+
+
+@disable_on_py3()
+@mock_rds2
+def test_add_tags_security_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.describe_db_subnet_groups()
+ result['DBSubnetGroups'].should.have.length_of(0)
+
+ security_group = conn.create_db_security_group(DBSecurityGroupName="db_sg",
+ DBSecurityGroupDescription='DB Security Group')['DBSecurityGroup']['DBSecurityGroupName']
+
+ resource = 'arn:aws:rds:us-west-2:1234567890:secgrp:{0}'.format(security_group)
+ conn.add_tags_to_resource(ResourceName=resource,
+ Tags=[{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
+
+ result = conn.list_tags_for_resource(ResourceName=resource)
+ result['TagList'].should.equal([{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
+
+@disable_on_py3()
+@mock_rds2
+def test_remove_tags_security_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.describe_db_subnet_groups()
+ result['DBSubnetGroups'].should.have.length_of(0)
+
+ security_group = conn.create_db_security_group(DBSecurityGroupName="db_sg",
+ DBSecurityGroupDescription='DB Security Group',
+ Tags=[{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])['DBSecurityGroup']['DBSecurityGroupName']
+
+ resource = 'arn:aws:rds:us-west-2:1234567890:secgrp:{0}'.format(security_group)
+ conn.remove_tags_from_resource(ResourceName=resource, TagKeys=['foo'])
+
+ result = conn.list_tags_for_resource(ResourceName=resource)
+ result['TagList'].should.equal([{'Value': 'bar1', 'Key': 'foo1'}])
@disable_on_py3()
@mock_ec2
@mock_rds2
def test_create_database_subnet_group():
- vpc_conn = boto.vpc.connect_to_region("us-west-2")
- vpc = vpc_conn.create_vpc("10.0.0.0/16")
- subnet1 = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
- subnet2 = vpc_conn.create_subnet(vpc.id, "10.2.0.0/24")
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet1 = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
+ subnet2 = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/26')['Subnet']
- subnet_ids = [subnet1.id, subnet2.id]
- conn = boto.rds2.connect_to_region("us-west-2")
- result = conn.create_db_subnet_group("db_subnet", "my db subnet", subnet_ids)
- result['CreateDBSubnetGroupResponse']['CreateDBSubnetGroupResult']['DBSubnetGroup']['DBSubnetGroupName'].should.equal("db_subnet")
- result['CreateDBSubnetGroupResponse']['CreateDBSubnetGroupResult']['DBSubnetGroup']['DBSubnetGroupDescription'].should.equal("my db subnet")
- subnets = result['CreateDBSubnetGroupResponse']['CreateDBSubnetGroupResult']['DBSubnetGroup']['Subnets']
- subnet_group_ids = [subnets['Subnet'][0]['SubnetIdentifier'], subnets['Subnet'][1]['SubnetIdentifier']]
+ subnet_ids = [subnet1['SubnetId'], subnet2['SubnetId']]
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.create_db_subnet_group(DBSubnetGroupName='db_subnet',
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=subnet_ids)
+ result['DBSubnetGroup']['DBSubnetGroupName'].should.equal("db_subnet")
+ result['DBSubnetGroup']['DBSubnetGroupDescription'].should.equal("my db subnet")
+ subnets = result['DBSubnetGroup']['Subnets']
+ subnet_group_ids = [subnets[0]['SubnetIdentifier'], subnets[1]['SubnetIdentifier']]
list(subnet_group_ids).should.equal(subnet_ids)
@@ -482,96 +651,370 @@ def test_create_database_subnet_group():
@mock_ec2
@mock_rds2
def test_create_database_in_subnet_group():
- vpc_conn = boto.vpc.connect_to_region("us-west-2")
- vpc = vpc_conn.create_vpc("10.0.0.0/16")
- subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
- 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_subnet_group_name='db_subnet1')
- result = conn.describe_db_instances("db-master-1")
- result['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['DBSubnetGroup']['DBSubnetGroupName'].should.equal("db_subnet1")
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_subnet_group(DBSubnetGroupName='db_subnet1',
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']])
+ conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ Engine='postgres',
+ DBInstanceClass='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSubnetGroupName='db_subnet1')
+ result = conn.describe_db_instances(DBInstanceIdentifier='db-master-1')
+ result['DBInstances'][0]['DBSubnetGroup']['DBSubnetGroupName'].should.equal('db_subnet1')
@disable_on_py3()
@mock_ec2
@mock_rds2
def test_describe_database_subnet_group():
- vpc_conn = boto.vpc.connect_to_region("us-west-2")
- vpc = vpc_conn.create_vpc("10.0.0.0/16")
- subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
- conn = boto.rds2.connect_to_region("us-west-2")
- conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
- conn.create_db_subnet_group("db_subnet2", "my db subnet", [subnet.id])
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_subnet_group(DBSubnetGroupName="db_subnet1",
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']])
+ conn.create_db_subnet_group(DBSubnetGroupName='db_subnet2',
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']])
- resp = conn.describe_db_subnet_groups()
- groups_resp = resp['DescribeDBSubnetGroupsResponse']
+ resp = conn.describe_db_subnet_groups()
+ resp['DBSubnetGroups'].should.have.length_of(2)
- subnet_groups = groups_resp['DescribeDBSubnetGroupsResult']['DBSubnetGroups']
- subnet_groups.should.have.length_of(2)
+ subnets = resp['DBSubnetGroups'][0]['Subnets']
+ subnets.should.have.length_of(1)
- subnets = groups_resp['DescribeDBSubnetGroupsResult']['DBSubnetGroups'][0]['DBSubnetGroup']['Subnets']
- subnets.should.have.length_of(1)
+ list(conn.describe_db_subnet_groups(DBSubnetGroupName="db_subnet1")['DBSubnetGroups']).should.have.length_of(1)
- list(resp).should.have.length_of(1)
- list(groups_resp).should.have.length_of(2)
- list(conn.describe_db_subnet_groups("db_subnet1")).should.have.length_of(1)
-
- conn.describe_db_subnet_groups.when.called_with("not-a-subnet").should.throw(BotoServerError)
+ conn.describe_db_subnet_groups.when.called_with(DBSubnetGroupName="not-a-subnet").should.throw(ClientError)
@disable_on_py3()
@mock_ec2
@mock_rds2
def test_delete_database_subnet_group():
- vpc_conn = boto.vpc.connect_to_region("us-west-2")
- vpc = vpc_conn.create_vpc("10.0.0.0/16")
- subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='us-west-2')
result = conn.describe_db_subnet_groups()
- result['DescribeDBSubnetGroupsResponse']['DescribeDBSubnetGroupsResult']['DBSubnetGroups'].should.have.length_of(0)
+ result['DBSubnetGroups'].should.have.length_of(0)
- conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
+ conn.create_db_subnet_group(DBSubnetGroupName="db_subnet1",
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']])
result = conn.describe_db_subnet_groups()
- result['DescribeDBSubnetGroupsResponse']['DescribeDBSubnetGroupsResult']['DBSubnetGroups'].should.have.length_of(1)
+ result['DBSubnetGroups'].should.have.length_of(1)
- conn.delete_db_subnet_group("db_subnet1")
+ conn.delete_db_subnet_group(DBSubnetGroupName="db_subnet1")
result = conn.describe_db_subnet_groups()
- result['DescribeDBSubnetGroupsResponse']['DescribeDBSubnetGroupsResult']['DBSubnetGroups'].should.have.length_of(0)
+ result['DBSubnetGroups'].should.have.length_of(0)
- conn.delete_db_subnet_group.when.called_with("db_subnet1").should.throw(BotoServerError)
+ conn.delete_db_subnet_group.when.called_with(DBSubnetGroupName="db_subnet1").should.throw(ClientError)
+
+
+@disable_on_py3()
+@mock_ec2
+@mock_rds2
+def test_list_tags_database_subnet_group():
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
+
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.describe_db_subnet_groups()
+ result['DBSubnetGroups'].should.have.length_of(0)
+
+ subnet = conn.create_db_subnet_group(DBSubnetGroupName="db_subnet1",
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']],
+ Tags=[{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])['DBSubnetGroup']['DBSubnetGroupName']
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:subgrp:{0}'.format(subnet))
+ result['TagList'].should.equal([{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
+
+@disable_on_py3()
+@mock_ec2
+@mock_rds2
+def test_add_tags_database_subnet_group():
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
+
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.describe_db_subnet_groups()
+ result['DBSubnetGroups'].should.have.length_of(0)
+
+ subnet = conn.create_db_subnet_group(DBSubnetGroupName="db_subnet1",
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']],
+ Tags=[])['DBSubnetGroup']['DBSubnetGroupName']
+ resource = 'arn:aws:rds:us-west-2:1234567890:subgrp:{0}'.format(subnet)
+
+ conn.add_tags_to_resource(ResourceName=resource,
+ Tags=[{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
+
+ result = conn.list_tags_for_resource(ResourceName=resource)
+ result['TagList'].should.equal([{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])
+
+@disable_on_py3()
+@mock_ec2
+@mock_rds2
+def test_remove_tags_database_subnet_group():
+ vpc_conn = boto3.client('ec2', 'us-west-2')
+ vpc = vpc_conn.create_vpc(CidrBlock='10.0.0.0/16')['Vpc']
+ subnet = vpc_conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.1.0.0/24')['Subnet']
+
+ conn = boto3.client('rds', region_name='us-west-2')
+ result = conn.describe_db_subnet_groups()
+ result['DBSubnetGroups'].should.have.length_of(0)
+
+ subnet = conn.create_db_subnet_group(DBSubnetGroupName="db_subnet1",
+ DBSubnetGroupDescription='my db subnet',
+ SubnetIds=[subnet['SubnetId']],
+ Tags=[{'Value': 'bar',
+ 'Key': 'foo'},
+ {'Value': 'bar1',
+ 'Key': 'foo1'}])['DBSubnetGroup']['DBSubnetGroupName']
+ resource = 'arn:aws:rds:us-west-2:1234567890:subgrp:{0}'.format(subnet)
+
+ conn.remove_tags_from_resource(ResourceName=resource, TagKeys=['foo'])
+
+ result = conn.list_tags_for_resource(ResourceName=resource)
+ result['TagList'].should.equal([{'Value': 'bar1', 'Key': 'foo1'}])
@disable_on_py3()
@mock_rds2
def test_create_database_replica():
- conn = boto.rds2.connect_to_region("us-west-2")
+ conn = boto3.client('rds', region_name='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.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ Engine='postgres',
+ DBInstanceClass='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=["my_sg"])
- replica = conn.create_db_instance_read_replica("db-replica-1", "db-master-1", "db.m1.small")
- replica['CreateDBInstanceReadReplicaResponse']['CreateDBInstanceReadReplicaResult']['DBInstance']['ReadReplicaSourceDBInstanceIdentifier'].should.equal('db-master-1')
- replica['CreateDBInstanceReadReplicaResponse']['CreateDBInstanceReadReplicaResult']['DBInstance']['DBInstanceClass'].should.equal('db.m1.small')
- replica['CreateDBInstanceReadReplicaResponse']['CreateDBInstanceReadReplicaResult']['DBInstance']['DBInstanceIdentifier'].should.equal('db-replica-1')
+ replica = conn.create_db_instance_read_replica(DBInstanceIdentifier="db-replica-1",
+ SourceDBInstanceIdentifier="db-master-1",
+ DBInstanceClass="db.m1.small")
+ replica['DBInstance']['ReadReplicaSourceDBInstanceIdentifier'].should.equal('db-master-1')
+ replica['DBInstance']['DBInstanceClass'].should.equal('db.m1.small')
+ replica['DBInstance']['DBInstanceIdentifier'].should.equal('db-replica-1')
- master = conn.describe_db_instances("db-master-1")
- master['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['ReadReplicaDBInstanceIdentifiers'].should.equal(['db-replica-1'])
+ master = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
+ master['DBInstances'][0]['ReadReplicaDBInstanceIdentifiers'].should.equal(['db-replica-1'])
- conn.delete_db_instance("db-replica-1")
+ conn.delete_db_instance(DBInstanceIdentifier="db-replica-1", SkipFinalSnapshot=True)
- master = conn.describe_db_instances("db-master-1")
- master['DescribeDBInstancesResponse']['DescribeDBInstancesResult']['DBInstances'][0]['ReadReplicaDBInstanceIdentifiers'].should.equal([])
+ master = conn.describe_db_instances(DBInstanceIdentifier="db-master-1")
+ master['DBInstances'][0]['ReadReplicaDBInstanceIdentifiers'].should.equal([])
+
+@disable_on_py3()
+@mock_rds2
+@mock_kms
+def test_create_database_with_encrypted_storage():
+ kms_conn = boto3.client('kms', region_name='us-west-2')
+ key = kms_conn.create_key(Policy='my RDS encryption policy',
+ Description='RDS encryption key',
+ KeyUsage='ENCRYPT_DECRYPT')
+
+ conn = boto3.client('rds', region_name='us-west-2')
+ database = conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ Engine='postgres',
+ DBInstanceClass='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234,
+ DBSecurityGroups=["my_sg"],
+ StorageEncrypted=True,
+ KmsKeyId=key['KeyMetadata']['KeyId'])
+
+ database['DBInstance']['StorageEncrypted'].should.equal(True)
+ database['DBInstance']['KmsKeyId'].should.equal(key['KeyMetadata']['KeyId'])
+
+@disable_on_py3()
+@mock_rds2
+def test_create_db_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ db_parameter_group = conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+
+ db_parameter_group['DBParameterGroup']['DBParameterGroupName'].should.equal('test')
+ db_parameter_group['DBParameterGroup']['DBParameterGroupFamily'].should.equal('mysql5.6')
+ db_parameter_group['DBParameterGroup']['Description'].should.equal('test parameter group')
+
+@disable_on_py3()
+@mock_rds2
+def test_create_db_instance_with_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ db_parameter_group = conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+
+ database = conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ Engine='mysql',
+ DBInstanceClass='db.m1.small',
+ DBParameterGroupName='test',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234)
+
+ len(database['DBInstance']['DBParameterGroups']).should.equal(1)
+ database['DBInstance']['DBParameterGroups'][0]['DBParameterGroupName'].should.equal('test')
+ database['DBInstance']['DBParameterGroups'][0]['ParameterApplyStatus'].should.equal('in-sync')
+
+@disable_on_py3()
+@mock_rds2
+def test_modify_db_instance_with_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ database = conn.create_db_instance(DBInstanceIdentifier='db-master-1',
+ AllocatedStorage=10,
+ Engine='mysql',
+ DBInstanceClass='db.m1.small',
+ MasterUsername='root',
+ MasterUserPassword='hunter2',
+ Port=1234)
+
+ len(database['DBInstance']['DBParameterGroups']).should.equal(1)
+ database['DBInstance']['DBParameterGroups'][0]['DBParameterGroupName'].should.equal('default.mysql5.6')
+ database['DBInstance']['DBParameterGroups'][0]['ParameterApplyStatus'].should.equal('in-sync')
+
+ db_parameter_group = conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+ conn.modify_db_instance(DBInstanceIdentifier='db-master-1',
+ DBParameterGroupName='test',
+ ApplyImmediately=True)
+
+ database = conn.describe_db_instances(DBInstanceIdentifier='db-master-1')['DBInstances'][0]
+ len(database['DBParameterGroups']).should.equal(1)
+ database['DBParameterGroups'][0]['DBParameterGroupName'].should.equal('test')
+ database['DBParameterGroups'][0]['ParameterApplyStatus'].should.equal('in-sync')
+
+
+@disable_on_py3()
+@mock_rds2
+def test_create_db_parameter_group_empty_description():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_parameter_group.when.called_with(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='').should.throw(ClientError)
+
+
+@disable_on_py3()
+@mock_rds2
+def test_create_db_parameter_group_duplicate():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+ conn.create_db_parameter_group.when.called_with(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group').should.throw(ClientError)
+
+
+@disable_on_py3()
+@mock_rds2
+def test_describe_db_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+ db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName='test')
+ db_parameter_groups['DBParameterGroups'][0]['DBParameterGroupName'].should.equal('test')
+
+
+@disable_on_py3()
+@mock_rds2
+def test_describe_non_existant_db_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName='test')
+ len(db_parameter_groups['DBParameterGroups']).should.equal(0)
+
+
+@disable_on_py3()
+@mock_rds2
+def test_delete_db_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+ db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName='test')
+ db_parameter_groups['DBParameterGroups'][0]['DBParameterGroupName'].should.equal('test')
+ conn.delete_db_parameter_group(DBParameterGroupName='test')
+ db_parameter_groups = conn.describe_db_parameter_groups(DBParameterGroupName='test')
+ len(db_parameter_groups['DBParameterGroups']).should.equal(0)
+
+@disable_on_py3()
+@mock_rds2
+def test_modify_db_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group')
+
+ modify_result = conn.modify_db_parameter_group(DBParameterGroupName='test',
+ Parameters=[{
+ 'ParameterName': 'foo',
+ 'ParameterValue': 'foo_val',
+ 'Description': 'test param',
+ 'ApplyMethod': 'immediate'
+ }]
+ )
+
+ modify_result['DBParameterGroupName'].should.equal('test')
+
+ db_parameters = conn.describe_db_parameters(DBParameterGroupName='test')
+ db_parameters['Parameters'][0]['ParameterName'].should.equal('foo')
+ db_parameters['Parameters'][0]['ParameterValue'].should.equal('foo_val')
+ db_parameters['Parameters'][0]['Description'].should.equal('test param')
+ db_parameters['Parameters'][0]['ApplyMethod'].should.equal('immediate')
+
+
+@disable_on_py3()
+@mock_rds2
+def test_delete_non_existant_db_parameter_group():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.delete_db_parameter_group.when.called_with(DBParameterGroupName='non-existant').should.throw(ClientError)
+
+@disable_on_py3()
+@mock_rds2
+def test_create_parameter_group_with_tags():
+ conn = boto3.client('rds', region_name='us-west-2')
+ conn.create_db_parameter_group(DBParameterGroupName='test',
+ DBParameterGroupFamily='mysql5.6',
+ Description='test parameter group',
+ Tags=[{
+ 'Key': 'foo',
+ 'Value': 'bar',
+ }])
+ result = conn.list_tags_for_resource(ResourceName='arn:aws:rds:us-west-2:1234567890:pg:test')
+ result['TagList'].should.equal([{'Value': 'bar', 'Key': 'foo'}])