diff --git a/moto/redshift/responses.py b/moto/redshift/responses.py index 23c653332..cc0e72793 100644 --- a/moto/redshift/responses.py +++ b/moto/redshift/responses.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import json +import dicttoxml from moto.core.responses import BaseResponse from .models import redshift_backends @@ -12,6 +13,13 @@ class RedshiftResponse(BaseResponse): def redshift_backend(self): return redshift_backends[self.region] + def get_response(self, response): + if self.request_json: + return json.dumps(response) + else: + xml = dicttoxml.dicttoxml(response, attr_type=False, root=False) + return xml + def create_cluster(self): cluster_kwargs = { "cluster_identifier": self._get_param('ClusterIdentifier'), @@ -37,7 +45,7 @@ class RedshiftResponse(BaseResponse): } cluster = self.redshift_backend.create_cluster(**cluster_kwargs) - return json.dumps({ + return self.get_response({ "CreateClusterResponse": { "CreateClusterResult": { "Cluster": cluster.to_json(), @@ -52,7 +60,7 @@ class RedshiftResponse(BaseResponse): cluster_identifier = self._get_param("ClusterIdentifier") clusters = self.redshift_backend.describe_clusters(cluster_identifier) - return json.dumps({ + return self.get_response({ "DescribeClustersResponse": { "DescribeClustersResult": { "Clusters": [cluster.to_json() for cluster in clusters] @@ -84,7 +92,7 @@ class RedshiftResponse(BaseResponse): } cluster = self.redshift_backend.modify_cluster(**cluster_kwargs) - return json.dumps({ + return self.get_response({ "ModifyClusterResponse": { "ModifyClusterResult": { "Cluster": cluster.to_json(), @@ -99,7 +107,7 @@ class RedshiftResponse(BaseResponse): cluster_identifier = self._get_param("ClusterIdentifier") cluster = self.redshift_backend.delete_cluster(cluster_identifier) - return json.dumps({ + return self.get_response({ "DeleteClusterResponse": { "DeleteClusterResult": { "Cluster": cluster.to_json() @@ -121,7 +129,7 @@ class RedshiftResponse(BaseResponse): subnet_ids=subnet_ids, ) - return json.dumps({ + return self.get_response({ "CreateClusterSubnetGroupResponse": { "CreateClusterSubnetGroupResult": { "ClusterSubnetGroup": subnet_group.to_json(), @@ -137,7 +145,7 @@ class RedshiftResponse(BaseResponse): subnet_groups = self.redshift_backend.describe_cluster_subnet_groups( subnet_identifier) - return json.dumps({ + return self.get_response({ "DescribeClusterSubnetGroupsResponse": { "DescribeClusterSubnetGroupsResult": { "ClusterSubnetGroups": [subnet_group.to_json() for subnet_group in subnet_groups] @@ -152,7 +160,7 @@ class RedshiftResponse(BaseResponse): subnet_identifier = self._get_param("ClusterSubnetGroupName") self.redshift_backend.delete_cluster_subnet_group(subnet_identifier) - return json.dumps({ + return self.get_response({ "DeleteClusterSubnetGroupResponse": { "ResponseMetadata": { "RequestId": "384ac68d-3775-11df-8963-01868b7c937a", @@ -170,7 +178,7 @@ class RedshiftResponse(BaseResponse): description=description, ) - return json.dumps({ + return self.get_response({ "CreateClusterSecurityGroupResponse": { "CreateClusterSecurityGroupResult": { "ClusterSecurityGroup": security_group.to_json(), @@ -187,7 +195,7 @@ class RedshiftResponse(BaseResponse): security_groups = self.redshift_backend.describe_cluster_security_groups( cluster_security_group_name) - return json.dumps({ + return self.get_response({ "DescribeClusterSecurityGroupsResponse": { "DescribeClusterSecurityGroupsResult": { "ClusterSecurityGroups": [security_group.to_json() for security_group in security_groups] @@ -203,7 +211,7 @@ class RedshiftResponse(BaseResponse): self.redshift_backend.delete_cluster_security_group( security_group_identifier) - return json.dumps({ + return self.get_response({ "DeleteClusterSecurityGroupResponse": { "ResponseMetadata": { "RequestId": "384ac68d-3775-11df-8963-01868b7c937a", @@ -222,7 +230,7 @@ class RedshiftResponse(BaseResponse): description, ) - return json.dumps({ + return self.get_response({ "CreateClusterParameterGroupResponse": { "CreateClusterParameterGroupResult": { "ClusterParameterGroup": parameter_group.to_json(), @@ -238,7 +246,7 @@ class RedshiftResponse(BaseResponse): parameter_groups = self.redshift_backend.describe_cluster_parameter_groups( cluster_parameter_group_name) - return json.dumps({ + return self.get_response({ "DescribeClusterParameterGroupsResponse": { "DescribeClusterParameterGroupsResult": { "ParameterGroups": [parameter_group.to_json() for parameter_group in parameter_groups] @@ -254,7 +262,7 @@ class RedshiftResponse(BaseResponse): self.redshift_backend.delete_cluster_parameter_group( cluster_parameter_group_name) - return json.dumps({ + return self.get_response({ "DeleteClusterParameterGroupResponse": { "ResponseMetadata": { "RequestId": "384ac68d-3775-11df-8963-01868b7c937a", diff --git a/setup.py b/setup.py index a09438d69..37eb78ccf 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ install_requires = [ "cookies", "requests>=2.0", "xmltodict", + "dicttoxml", "six", "werkzeug", "pytz", diff --git a/tests/test_redshift/test_redshift.py b/tests/test_redshift/test_redshift.py index 41be8f022..045e30246 100644 --- a/tests/test_redshift/test_redshift.py +++ b/tests/test_redshift/test_redshift.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import boto +import boto3 from boto.redshift.exceptions import ( ClusterNotFound, ClusterParameterGroupNotFound, @@ -10,7 +11,21 @@ from boto.redshift.exceptions import ( ) import sure # noqa -from moto import mock_ec2_deprecated, mock_redshift_deprecated +from moto import mock_ec2_deprecated, mock_redshift_deprecated, mock_redshift + + +@mock_redshift +def test_create_cluster_boto3(): + client = boto3.client('redshift', region_name='us-east-1') + response = client.create_cluster( + DBName='test', + ClusterIdentifier='test', + ClusterType='single-node', + NodeType='ds2.xlarge', + MasterUsername='user', + MasterUserPassword='password', + ) + response['Cluster']['NodeType'].should.equal('ds2.xlarge') @mock_redshift_deprecated