Merge pull request #2401 from rocky4570/redshift-enhanced-vpc-routing
add enhanced vpc routing option to redshift moto
This commit is contained in:
		
						commit
						eb5bf2ed55
					
				| @ -74,7 +74,7 @@ class Cluster(TaggableResourceMixin, BaseModel): | |||||||
|                  automated_snapshot_retention_period, port, cluster_version, |                  automated_snapshot_retention_period, port, cluster_version, | ||||||
|                  allow_version_upgrade, number_of_nodes, publicly_accessible, |                  allow_version_upgrade, number_of_nodes, publicly_accessible, | ||||||
|                  encrypted, region_name, tags=None, iam_roles_arn=None, |                  encrypted, region_name, tags=None, iam_roles_arn=None, | ||||||
|                  restored_from_snapshot=False): |                  enhanced_vpc_routing=None, restored_from_snapshot=False): | ||||||
|         super(Cluster, self).__init__(region_name, tags) |         super(Cluster, self).__init__(region_name, tags) | ||||||
|         self.redshift_backend = redshift_backend |         self.redshift_backend = redshift_backend | ||||||
|         self.cluster_identifier = cluster_identifier |         self.cluster_identifier = cluster_identifier | ||||||
| @ -85,6 +85,7 @@ class Cluster(TaggableResourceMixin, BaseModel): | |||||||
|         self.master_user_password = master_user_password |         self.master_user_password = master_user_password | ||||||
|         self.db_name = db_name if db_name else "dev" |         self.db_name = db_name if db_name else "dev" | ||||||
|         self.vpc_security_group_ids = vpc_security_group_ids |         self.vpc_security_group_ids = vpc_security_group_ids | ||||||
|  |         self.enhanced_vpc_routing = enhanced_vpc_routing if enhanced_vpc_routing is not None else False | ||||||
|         self.cluster_subnet_group_name = cluster_subnet_group_name |         self.cluster_subnet_group_name = cluster_subnet_group_name | ||||||
|         self.publicly_accessible = publicly_accessible |         self.publicly_accessible = publicly_accessible | ||||||
|         self.encrypted = encrypted |         self.encrypted = encrypted | ||||||
| @ -154,6 +155,7 @@ class Cluster(TaggableResourceMixin, BaseModel): | |||||||
|             port=properties.get('Port'), |             port=properties.get('Port'), | ||||||
|             cluster_version=properties.get('ClusterVersion'), |             cluster_version=properties.get('ClusterVersion'), | ||||||
|             allow_version_upgrade=properties.get('AllowVersionUpgrade'), |             allow_version_upgrade=properties.get('AllowVersionUpgrade'), | ||||||
|  |             enhanced_vpc_routing=properties.get('EnhancedVpcRouting'), | ||||||
|             number_of_nodes=properties.get('NumberOfNodes'), |             number_of_nodes=properties.get('NumberOfNodes'), | ||||||
|             publicly_accessible=properties.get("PubliclyAccessible"), |             publicly_accessible=properties.get("PubliclyAccessible"), | ||||||
|             encrypted=properties.get("Encrypted"), |             encrypted=properties.get("Encrypted"), | ||||||
| @ -241,6 +243,7 @@ class Cluster(TaggableResourceMixin, BaseModel): | |||||||
|             'ClusterCreateTime': self.create_time, |             'ClusterCreateTime': self.create_time, | ||||||
|             "PendingModifiedValues": [], |             "PendingModifiedValues": [], | ||||||
|             "Tags": self.tags, |             "Tags": self.tags, | ||||||
|  |             "EnhancedVpcRouting": self.enhanced_vpc_routing, | ||||||
|             "IamRoles": [{ |             "IamRoles": [{ | ||||||
|                 "ApplyStatus": "in-sync", |                 "ApplyStatus": "in-sync", | ||||||
|                 "IamRoleArn": iam_role_arn |                 "IamRoleArn": iam_role_arn | ||||||
| @ -427,6 +430,7 @@ class Snapshot(TaggableResourceMixin, BaseModel): | |||||||
|             'NumberOfNodes': self.cluster.number_of_nodes, |             'NumberOfNodes': self.cluster.number_of_nodes, | ||||||
|             'DBName': self.cluster.db_name, |             'DBName': self.cluster.db_name, | ||||||
|             'Tags': self.tags, |             'Tags': self.tags, | ||||||
|  |             'EnhancedVpcRouting': self.cluster.enhanced_vpc_routing, | ||||||
|             "IamRoles": [{ |             "IamRoles": [{ | ||||||
|                 "ApplyStatus": "in-sync", |                 "ApplyStatus": "in-sync", | ||||||
|                 "IamRoleArn": iam_role_arn |                 "IamRoleArn": iam_role_arn | ||||||
| @ -678,7 +682,8 @@ class RedshiftBackend(BaseBackend): | |||||||
|             "number_of_nodes": snapshot.cluster.number_of_nodes, |             "number_of_nodes": snapshot.cluster.number_of_nodes, | ||||||
|             "encrypted": snapshot.cluster.encrypted, |             "encrypted": snapshot.cluster.encrypted, | ||||||
|             "tags": snapshot.cluster.tags, |             "tags": snapshot.cluster.tags, | ||||||
|             "restored_from_snapshot": True |             "restored_from_snapshot": True, | ||||||
|  |             "enhanced_vpc_routing": snapshot.cluster.enhanced_vpc_routing | ||||||
|         } |         } | ||||||
|         create_kwargs.update(kwargs) |         create_kwargs.update(kwargs) | ||||||
|         return self.create_cluster(**create_kwargs) |         return self.create_cluster(**create_kwargs) | ||||||
|  | |||||||
| @ -135,6 +135,7 @@ class RedshiftResponse(BaseResponse): | |||||||
|             "region_name": self.region, |             "region_name": self.region, | ||||||
|             "tags": self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value')), |             "tags": self.unpack_complex_list_params('Tags.Tag', ('Key', 'Value')), | ||||||
|             "iam_roles_arn": self._get_iam_roles(), |             "iam_roles_arn": self._get_iam_roles(), | ||||||
|  |             "enhanced_vpc_routing": self._get_param('EnhancedVpcRouting'), | ||||||
|         } |         } | ||||||
|         cluster = self.redshift_backend.create_cluster(**cluster_kwargs).to_json() |         cluster = self.redshift_backend.create_cluster(**cluster_kwargs).to_json() | ||||||
|         cluster['ClusterStatus'] = 'creating' |         cluster['ClusterStatus'] = 'creating' | ||||||
| @ -150,6 +151,7 @@ class RedshiftResponse(BaseResponse): | |||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|     def restore_from_cluster_snapshot(self): |     def restore_from_cluster_snapshot(self): | ||||||
|  |         enhanced_vpc_routing = self._get_bool_param('EnhancedVpcRouting') | ||||||
|         restore_kwargs = { |         restore_kwargs = { | ||||||
|             "snapshot_identifier": self._get_param('SnapshotIdentifier'), |             "snapshot_identifier": self._get_param('SnapshotIdentifier'), | ||||||
|             "cluster_identifier": self._get_param('ClusterIdentifier'), |             "cluster_identifier": self._get_param('ClusterIdentifier'), | ||||||
| @ -171,6 +173,8 @@ class RedshiftResponse(BaseResponse): | |||||||
|             "region_name": self.region, |             "region_name": self.region, | ||||||
|             "iam_roles_arn": self._get_iam_roles(), |             "iam_roles_arn": self._get_iam_roles(), | ||||||
|         } |         } | ||||||
|  |         if enhanced_vpc_routing is not None: | ||||||
|  |             restore_kwargs['enhanced_vpc_routing'] = enhanced_vpc_routing | ||||||
|         cluster = self.redshift_backend.restore_from_cluster_snapshot(**restore_kwargs).to_json() |         cluster = self.redshift_backend.restore_from_cluster_snapshot(**restore_kwargs).to_json() | ||||||
|         cluster['ClusterStatus'] = 'creating' |         cluster['ClusterStatus'] = 'creating' | ||||||
|         return self.get_response({ |         return self.get_response({ | ||||||
| @ -218,6 +222,7 @@ class RedshiftResponse(BaseResponse): | |||||||
|             "publicly_accessible": self._get_param("PubliclyAccessible"), |             "publicly_accessible": self._get_param("PubliclyAccessible"), | ||||||
|             "encrypted": self._get_param("Encrypted"), |             "encrypted": self._get_param("Encrypted"), | ||||||
|             "iam_roles_arn": self._get_iam_roles(), |             "iam_roles_arn": self._get_iam_roles(), | ||||||
|  |             "enhanced_vpc_routing": self._get_param("EnhancedVpcRouting") | ||||||
|         } |         } | ||||||
|         cluster_kwargs = {} |         cluster_kwargs = {} | ||||||
|         # We only want parameters that were actually passed in, otherwise |         # We only want parameters that were actually passed in, otherwise | ||||||
|  | |||||||
| @ -37,6 +37,25 @@ def test_create_cluster_boto3(): | |||||||
|     create_time = response['Cluster']['ClusterCreateTime'] |     create_time = response['Cluster']['ClusterCreateTime'] | ||||||
|     create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo)) |     create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo)) | ||||||
|     create_time.should.be.greater_than(datetime.datetime.now(create_time.tzinfo) - datetime.timedelta(minutes=1)) |     create_time.should.be.greater_than(datetime.datetime.now(create_time.tzinfo) - datetime.timedelta(minutes=1)) | ||||||
|  |     response['Cluster']['EnhancedVpcRouting'].should.equal(False) | ||||||
|  | 
 | ||||||
|  | @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', | ||||||
|  |         EnhancedVpcRouting=True | ||||||
|  |     ) | ||||||
|  |     response['Cluster']['NodeType'].should.equal('ds2.xlarge') | ||||||
|  |     create_time = response['Cluster']['ClusterCreateTime'] | ||||||
|  |     create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo)) | ||||||
|  |     create_time.should.be.greater_than(datetime.datetime.now(create_time.tzinfo) - datetime.timedelta(minutes=1)) | ||||||
|  |     response['Cluster']['EnhancedVpcRouting'].should.equal(True) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @mock_redshift | @mock_redshift | ||||||
| @ -425,6 +444,58 @@ def test_delete_cluster(): | |||||||
|         "not-a-cluster").should.throw(ClusterNotFound) |         "not-a-cluster").should.throw(ClusterNotFound) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @mock_redshift | ||||||
|  | def test_modify_cluster_vpc_routing(): | ||||||
|  |     iam_roles_arn = ['arn:aws:iam:::role/my-iam-role', ] | ||||||
|  |     client = boto3.client('redshift', region_name='us-east-1') | ||||||
|  |     cluster_identifier = 'my_cluster' | ||||||
|  | 
 | ||||||
|  |     client.create_cluster( | ||||||
|  |         ClusterIdentifier=cluster_identifier, | ||||||
|  |         NodeType="single-node", | ||||||
|  |         MasterUsername="username", | ||||||
|  |         MasterUserPassword="password", | ||||||
|  |         IamRoles=iam_roles_arn | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     cluster_response = client.describe_clusters(ClusterIdentifier=cluster_identifier) | ||||||
|  |     cluster = cluster_response['Clusters'][0] | ||||||
|  |     cluster['EnhancedVpcRouting'].should.equal(False) | ||||||
|  | 
 | ||||||
|  |     client.create_cluster_security_group(ClusterSecurityGroupName='security_group', | ||||||
|  |                                          Description='security_group') | ||||||
|  | 
 | ||||||
|  |     client.create_cluster_parameter_group(ParameterGroupName='my_parameter_group', | ||||||
|  |                                           ParameterGroupFamily='redshift-1.0', | ||||||
|  |                                           Description='my_parameter_group') | ||||||
|  | 
 | ||||||
|  |     client.modify_cluster( | ||||||
|  |         ClusterIdentifier=cluster_identifier, | ||||||
|  |         ClusterType='multi-node', | ||||||
|  |         NodeType="ds2.8xlarge", | ||||||
|  |         NumberOfNodes=3, | ||||||
|  |         ClusterSecurityGroups=["security_group"], | ||||||
|  |         MasterUserPassword="new_password", | ||||||
|  |         ClusterParameterGroupName="my_parameter_group", | ||||||
|  |         AutomatedSnapshotRetentionPeriod=7, | ||||||
|  |         PreferredMaintenanceWindow="Tue:03:00-Tue:11:00", | ||||||
|  |         AllowVersionUpgrade=False, | ||||||
|  |         NewClusterIdentifier=cluster_identifier, | ||||||
|  |         EnhancedVpcRouting=True | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     cluster_response = client.describe_clusters(ClusterIdentifier=cluster_identifier) | ||||||
|  |     cluster = cluster_response['Clusters'][0] | ||||||
|  |     cluster['ClusterIdentifier'].should.equal(cluster_identifier) | ||||||
|  |     cluster['NodeType'].should.equal("ds2.8xlarge") | ||||||
|  |     cluster['PreferredMaintenanceWindow'].should.equal("Tue:03:00-Tue:11:00") | ||||||
|  |     cluster['AutomatedSnapshotRetentionPeriod'].should.equal(7) | ||||||
|  |     cluster['AllowVersionUpgrade'].should.equal(False) | ||||||
|  |     # This one should remain unmodified. | ||||||
|  |     cluster['NumberOfNodes'].should.equal(3) | ||||||
|  |     cluster['EnhancedVpcRouting'].should.equal(True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| @mock_redshift_deprecated | @mock_redshift_deprecated | ||||||
| def test_modify_cluster(): | def test_modify_cluster(): | ||||||
|     conn = boto.connect_redshift() |     conn = boto.connect_redshift() | ||||||
| @ -446,6 +517,10 @@ def test_modify_cluster(): | |||||||
|         master_user_password="password", |         master_user_password="password", | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |     cluster_response = conn.describe_clusters(cluster_identifier) | ||||||
|  |     cluster = cluster_response['DescribeClustersResponse']['DescribeClustersResult']['Clusters'][0] | ||||||
|  |     cluster['EnhancedVpcRouting'].should.equal(False) | ||||||
|  | 
 | ||||||
|     conn.modify_cluster( |     conn.modify_cluster( | ||||||
|         cluster_identifier, |         cluster_identifier, | ||||||
|         cluster_type="multi-node", |         cluster_type="multi-node", | ||||||
| @ -456,14 +531,13 @@ def test_modify_cluster(): | |||||||
|         automated_snapshot_retention_period=7, |         automated_snapshot_retention_period=7, | ||||||
|         preferred_maintenance_window="Tue:03:00-Tue:11:00", |         preferred_maintenance_window="Tue:03:00-Tue:11:00", | ||||||
|         allow_version_upgrade=False, |         allow_version_upgrade=False, | ||||||
|         new_cluster_identifier="new_identifier", |         new_cluster_identifier=cluster_identifier, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     cluster_response = conn.describe_clusters("new_identifier") |     cluster_response = conn.describe_clusters(cluster_identifier) | ||||||
|     cluster = cluster_response['DescribeClustersResponse'][ |     cluster = cluster_response['DescribeClustersResponse'][ | ||||||
|         'DescribeClustersResult']['Clusters'][0] |         'DescribeClustersResult']['Clusters'][0] | ||||||
| 
 |     cluster['ClusterIdentifier'].should.equal(cluster_identifier) | ||||||
|     cluster['ClusterIdentifier'].should.equal("new_identifier") |  | ||||||
|     cluster['NodeType'].should.equal("dw.hs1.xlarge") |     cluster['NodeType'].should.equal("dw.hs1.xlarge") | ||||||
|     cluster['ClusterSecurityGroups'][0][ |     cluster['ClusterSecurityGroups'][0][ | ||||||
|         'ClusterSecurityGroupName'].should.equal("security_group") |         'ClusterSecurityGroupName'].should.equal("security_group") | ||||||
| @ -674,6 +748,7 @@ def test_create_cluster_snapshot(): | |||||||
|         NodeType='ds2.xlarge', |         NodeType='ds2.xlarge', | ||||||
|         MasterUsername='username', |         MasterUsername='username', | ||||||
|         MasterUserPassword='password', |         MasterUserPassword='password', | ||||||
|  |         EnhancedVpcRouting=True | ||||||
|     ) |     ) | ||||||
|     cluster_response['Cluster']['NodeType'].should.equal('ds2.xlarge') |     cluster_response['Cluster']['NodeType'].should.equal('ds2.xlarge') | ||||||
| 
 | 
 | ||||||
| @ -823,11 +898,14 @@ def test_create_cluster_from_snapshot(): | |||||||
|         NodeType='ds2.xlarge', |         NodeType='ds2.xlarge', | ||||||
|         MasterUsername='username', |         MasterUsername='username', | ||||||
|         MasterUserPassword='password', |         MasterUserPassword='password', | ||||||
|  |         EnhancedVpcRouting=True, | ||||||
|     ) |     ) | ||||||
|  | 
 | ||||||
|     client.create_cluster_snapshot( |     client.create_cluster_snapshot( | ||||||
|         SnapshotIdentifier=original_snapshot_identifier, |         SnapshotIdentifier=original_snapshot_identifier, | ||||||
|         ClusterIdentifier=original_cluster_identifier |         ClusterIdentifier=original_cluster_identifier | ||||||
|     ) |     ) | ||||||
|  | 
 | ||||||
|     response = client.restore_from_cluster_snapshot( |     response = client.restore_from_cluster_snapshot( | ||||||
|         ClusterIdentifier=new_cluster_identifier, |         ClusterIdentifier=new_cluster_identifier, | ||||||
|         SnapshotIdentifier=original_snapshot_identifier, |         SnapshotIdentifier=original_snapshot_identifier, | ||||||
| @ -842,7 +920,7 @@ def test_create_cluster_from_snapshot(): | |||||||
|     new_cluster['NodeType'].should.equal('ds2.xlarge') |     new_cluster['NodeType'].should.equal('ds2.xlarge') | ||||||
|     new_cluster['MasterUsername'].should.equal('username') |     new_cluster['MasterUsername'].should.equal('username') | ||||||
|     new_cluster['Endpoint']['Port'].should.equal(1234) |     new_cluster['Endpoint']['Port'].should.equal(1234) | ||||||
| 
 |     new_cluster['EnhancedVpcRouting'].should.equal(True) | ||||||
| 
 | 
 | ||||||
| @mock_redshift | @mock_redshift | ||||||
| def test_create_cluster_from_snapshot_with_waiter(): | def test_create_cluster_from_snapshot_with_waiter(): | ||||||
| @ -857,6 +935,7 @@ def test_create_cluster_from_snapshot_with_waiter(): | |||||||
|         NodeType='ds2.xlarge', |         NodeType='ds2.xlarge', | ||||||
|         MasterUsername='username', |         MasterUsername='username', | ||||||
|         MasterUserPassword='password', |         MasterUserPassword='password', | ||||||
|  |         EnhancedVpcRouting=True | ||||||
|     ) |     ) | ||||||
|     client.create_cluster_snapshot( |     client.create_cluster_snapshot( | ||||||
|         SnapshotIdentifier=original_snapshot_identifier, |         SnapshotIdentifier=original_snapshot_identifier, | ||||||
| @ -883,6 +962,7 @@ def test_create_cluster_from_snapshot_with_waiter(): | |||||||
|     new_cluster = response['Clusters'][0] |     new_cluster = response['Clusters'][0] | ||||||
|     new_cluster['NodeType'].should.equal('ds2.xlarge') |     new_cluster['NodeType'].should.equal('ds2.xlarge') | ||||||
|     new_cluster['MasterUsername'].should.equal('username') |     new_cluster['MasterUsername'].should.equal('username') | ||||||
|  |     new_cluster['EnhancedVpcRouting'].should.equal(True) | ||||||
|     new_cluster['Endpoint']['Port'].should.equal(1234) |     new_cluster['Endpoint']['Port'].should.equal(1234) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user