cfn-bridge 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -0
  3. data/lib/cloud_formation/bridge/cli.rb +4 -0
  4. data/lib/cloud_formation/bridge/executor.rb +10 -1
  5. data/lib/cloud_formation/bridge/names.rb +10 -0
  6. data/lib/cloud_formation/bridge/request.rb +7 -1
  7. data/lib/cloud_formation/bridge/resources/base.rb +14 -3
  8. data/lib/cloud_formation/bridge/resources/base_elasti_cache_resource.rb +58 -0
  9. data/lib/cloud_formation/bridge/resources/elasti_cache_node_urls.rb +35 -0
  10. data/lib/cloud_formation/bridge/resources/elasti_cache_replica_cluster.rb +66 -0
  11. data/lib/cloud_formation/bridge/resources/elasti_cache_replication_group.rb +67 -0
  12. data/lib/cloud_formation/bridge/util.rb +6 -0
  13. data/lib/cloud_formation/bridge/version.rb +1 -1
  14. data/spec/files/create-cache-node-urls-message.json +12 -0
  15. data/spec/files/create-redis-cache-node-urls-message.json +12 -0
  16. data/spec/files/create-replica-cluster-message.json +13 -0
  17. data/spec/files/create-replication-group-message.json +14 -0
  18. data/spec/files/delete-replica-cluster-message.json +14 -0
  19. data/spec/files/delete-replication-group-message.json +15 -0
  20. data/spec/files/describe-cache-cluster-primary.json +57 -0
  21. data/spec/files/describe-cache-cluster-replica-done.json +68 -0
  22. data/spec/files/describe-cache-cluster-replica.json +46 -0
  23. data/spec/files/describe-memcached-cluster.json +73 -0
  24. data/spec/files/describe-replication-group-primary-and-replica.json +49 -0
  25. data/spec/files/describe-replication-group-primary-only.json +38 -0
  26. data/spec/files/outputs-formation.json +0 -4
  27. data/spec/files/sample-replica-cluster.json +51 -0
  28. data/spec/files/sample-replication-group.json +34 -0
  29. data/spec/lib/cloud_formation/bridge/executor_spec.rb +1 -1
  30. data/spec/lib/cloud_formation/bridge/request_spec.rb +17 -5
  31. data/spec/lib/cloud_formation/bridge/resources/elasti_cache_node_urls_spec.rb +61 -0
  32. data/spec/lib/cloud_formation/bridge/resources/elasti_cache_replica_cluster_spec.rb +67 -0
  33. data/spec/lib/cloud_formation/bridge/resources/elasti_cache_replication_group_spec.rb +65 -0
  34. data/spec/support/file_support.rb +6 -0
  35. metadata +40 -2
@@ -0,0 +1,68 @@
1
+ {
2
+ "cache_clusters": [
3
+ {
4
+ "cache_security_groups": [
5
+ {
6
+ "cache_security_group_name": "redis-group",
7
+ "status": "active"
8
+ }
9
+ ],
10
+ "cache_nodes": [
11
+ {
12
+ "parameter_group_status": "in-sync",
13
+ "cache_node_status": "available",
14
+ "cache_node_create_time": "2014-09-10 02:25:13 UTC",
15
+ "cache_node_id": "0001",
16
+ "customer_availability_zone": "us-east-1a",
17
+ "endpoint": {
18
+ "port": 6379,
19
+ "address": "dev-redis-replica.mzufvw.0001.use1.cache.amazonaws.com"
20
+ }
21
+ },
22
+ {
23
+ "parameter_group_status": "in-sync",
24
+ "cache_node_status": "available",
25
+ "cache_node_create_time": "2014-09-10 02:25:13 UTC",
26
+ "cache_node_id": "0001",
27
+ "customer_availability_zone": "us-east-1a",
28
+ "endpoint": {
29
+ "port": 6379,
30
+ "address": "dev-redis-replica.mzufvw.0002.use1.cache.amazonaws.com"
31
+ }
32
+ }
33
+ ],
34
+ "security_groups": [
35
+
36
+ ],
37
+ "cache_cluster_id": "dev-redis-replica",
38
+ "cache_parameter_group": {
39
+ "cache_node_ids_to_reboot": [
40
+
41
+ ],
42
+ "cache_parameter_group_name": "default.redis2.8",
43
+ "parameter_apply_status": "in-sync"
44
+ },
45
+ "cache_cluster_status": "available",
46
+ "replication_group_id": "dev-redis-rep-group",
47
+ "cache_node_type": "cache.m1.small",
48
+ "engine": "redis",
49
+ "pending_modified_values": {
50
+ "cache_node_ids_to_remove": [
51
+
52
+ ]
53
+ },
54
+ "preferred_availability_zone": "us-east-1a",
55
+ "cache_cluster_create_time": "2014-09-10 02:25:13 UTC",
56
+ "engine_version": "2.8.6",
57
+ "auto_minor_version_upgrade": true,
58
+ "preferred_maintenance_window": "thu:10:00-thu:11:00",
59
+ "client_download_landing_page": "https://console.aws.amazon.com/elasticache/home#client-download:",
60
+ "snapshot_retention_limit": 0,
61
+ "num_cache_nodes": 1,
62
+ "snapshot_window": "09:00-10:00"
63
+ }
64
+ ],
65
+ "response_metadata": {
66
+ "request_id": "3913b189-3892-11e4-8c6b-f3805709d592"
67
+ }
68
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "cache_clusters": [
3
+ {
4
+ "cache_security_groups": [
5
+ {
6
+ "cache_security_group_name": "redis-group",
7
+ "status": "active"
8
+ }
9
+ ],
10
+ "cache_nodes": [
11
+
12
+ ],
13
+ "security_groups": [
14
+
15
+ ],
16
+ "cache_cluster_id": "dev-redis-replica",
17
+ "cache_parameter_group": {
18
+ "cache_node_ids_to_reboot": [
19
+
20
+ ],
21
+ "parameter_apply_status": "in-sync",
22
+ "cache_parameter_group_name": "default.redis2.8"
23
+ },
24
+ "cache_cluster_status": "creating",
25
+ "replication_group_id": "dev-redis-rep-group",
26
+ "cache_node_type": "cache.m1.small",
27
+ "engine": "redis",
28
+ "pending_modified_values": {
29
+ "cache_node_ids_to_remove": [
30
+
31
+ ]
32
+ },
33
+ "preferred_availability_zone": "us-east-1a",
34
+ "engine_version": "2.8.6",
35
+ "auto_minor_version_upgrade": true,
36
+ "preferred_maintenance_window": "thu:10:00-thu:11:00",
37
+ "client_download_landing_page": "https://console.aws.amazon.com/elasticache/home#client-download:",
38
+ "snapshot_retention_limit": 0,
39
+ "num_cache_nodes": 1,
40
+ "snapshot_window": "09:00-10:00"
41
+ }
42
+ ],
43
+ "response_metadata": {
44
+ "request_id": "3d98e0e9-3891-11e4-8fa2-cfebce712279"
45
+ }
46
+ }
@@ -0,0 +1,73 @@
1
+ { "cache_clusters": [
2
+ {
3
+ "auto_minor_version_upgrade": true,
4
+ "cache_cluster_create_time": "2013-05-28 07:42:19 UTC",
5
+ "cache_cluster_id": "somecache",
6
+ "cache_cluster_status": "available",
7
+ "cache_node_type": "cache.t1.micro",
8
+ "cache_nodes": [
9
+ {
10
+ "cache_node_create_time": "2013-05-28 07:42:19 UTC",
11
+ "cache_node_id": "0001",
12
+ "cache_node_status": "available",
13
+ "customer_availability_zone": "us-east-1a",
14
+ "endpoint": {
15
+ "address": "somecache.tgbhomz.0001.use1.cache.amazonaws.com",
16
+ "port": 11211
17
+ },
18
+ "parameter_group_status": "in-sync"
19
+ },
20
+ {
21
+ "cache_node_create_time": "2013-05-28 07:42:19 UTC",
22
+ "cache_node_id": "0002",
23
+ "cache_node_status": "available",
24
+ "customer_availability_zone": "us-east-1a",
25
+ "endpoint": {
26
+ "address": "somecache.tgbhomz.0002.use1.cache.amazonaws.com",
27
+ "port": 11211
28
+ },
29
+ "parameter_group_status": "in-sync"
30
+ },
31
+ {
32
+ "cache_node_create_time": "2013-05-28 07:42:19 UTC",
33
+ "cache_node_id": "0003",
34
+ "cache_node_status": "available",
35
+ "customer_availability_zone": "us-east-1a",
36
+ "endpoint": {
37
+ "address": "somecache.tgbhomz.0003.use1.cache.amazonaws.com",
38
+ "port": 11211
39
+ },
40
+ "parameter_group_status": "in-sync"
41
+ }
42
+ ],
43
+ "cache_parameter_group": {
44
+ "cache_node_ids_to_reboot": [ ],
45
+ "cache_parameter_group_name": "default.memcached1.4",
46
+ "parameter_apply_status": "in-sync"
47
+ },
48
+ "cache_security_groups": [
49
+ {
50
+ "cache_security_group_name": "cache_security_group",
51
+ "status": "active"
52
+ }
53
+ ],
54
+ "client_download_landing_page": "https://console.aws.amazon.com/elasticache/home#client-download:",
55
+ "configuration_endpoint": {
56
+ "address": "somecache.tgbhomz.cfg.use1.cache.amazonaws.com",
57
+ "port": 11211
58
+ },
59
+ "engine": "memcached",
60
+ "engine_version": "1.4.14",
61
+ "num_cache_nodes": 3,
62
+ "pending_modified_values": {
63
+ "cache_node_ids_to_remove": [ ]
64
+ },
65
+ "preferred_availability_zone": "us-east-1a",
66
+ "preferred_maintenance_window": "sun:07:30-sun:08:30",
67
+ "security_groups": [ ]
68
+ }
69
+ ],
70
+ "response_metadata": {
71
+ "request_id": "585fd79c-3dd2-11e4-bf11-4b077bcebe02"
72
+ }
73
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "replication_groups": [
3
+ {
4
+ "member_clusters": [
5
+ "red-re-1uptio9f2ytdi",
6
+ "rn-redisclu-a7392cba"
7
+ ],
8
+ "node_groups": [
9
+ {
10
+ "node_group_members": [
11
+ {
12
+ "cache_cluster_id": "red-re-1uptio9f2ytdi",
13
+ "read_endpoint": {
14
+ "port": 6379,
15
+ "address": "red-re-1uptio9f2ytdi.mzufvw.0001.use1.cache.amazonaws.com"
16
+ },
17
+ "preferred_availability_zone": "us-east-1c",
18
+ "cache_node_id": "0001",
19
+ "current_role": "primary"
20
+ },
21
+ {
22
+ "cache_cluster_id": "rn-redisclu-a7392cba",
23
+ "read_endpoint": {
24
+ "port": 6379,
25
+ "address": "rn-redisclu-a7392cba.mzufvw.0001.use1.cache.amazonaws.com"
26
+ },
27
+ "preferred_availability_zone": "us-east-1a",
28
+ "cache_node_id": "0001",
29
+ "current_role": "replica"
30
+ }
31
+ ],
32
+ "primary_endpoint": {
33
+ "port": 6379,
34
+ "address": "rg-redisclu-2ffb4776.mzufvw.ng.0001.use1.cache.amazonaws.com"
35
+ },
36
+ "node_group_id": "0001",
37
+ "status": "available"
38
+ }
39
+ ],
40
+ "replication_group_id": "rg-redisclu-2ffb4776",
41
+ "status": "available",
42
+ "description": "Sample replication group for the redis instances",
43
+ "pending_modified_values": null
44
+ }
45
+ ],
46
+ "response_metadata": {
47
+ "request_id": "d9700c9d-3891-11e4-9cb8-252ab83f5b14"
48
+ }
49
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "replication_groups": [
3
+ {
4
+ "member_clusters": [
5
+ "cluster-id-here"
6
+ ],
7
+ "node_groups": [
8
+ {
9
+ "node_group_members": [
10
+ {
11
+ "cache_cluster_id": "cluster-id-here",
12
+ "read_endpoint": {
13
+ "port": 6379,
14
+ "address": "cluster-id-here.mzufvw.0001.use1.cache.amazonaws.com"
15
+ },
16
+ "preferred_availability_zone": "us-east-1c",
17
+ "cache_node_id": "0001",
18
+ "current_role": "primary"
19
+ }
20
+ ],
21
+ "node_group_id": "0001",
22
+ "primary_endpoint": {
23
+ "port": 6379,
24
+ "address": "cluster-id-here.mzufvw.ng.0001.use1.cache.amazonaws.com"
25
+ },
26
+ "status": "available"
27
+ }
28
+ ],
29
+ "replication_group_id": "dev-redis-rep",
30
+ "status": "available",
31
+ "pending_modified_values": null,
32
+ "description": "Sample replication group for the redis instances"
33
+ }
34
+ ],
35
+ "response_metadata": {
36
+ "request_id": "a4a0eaab-3891-11e4-8cb6-9f87081a8ee3"
37
+ }
38
+ }
@@ -8,10 +8,6 @@
8
8
  "Description": "SNS topic that will be used",
9
9
  "Type": "String"
10
10
  },
11
- "EntryQueue": {
12
- "Description": "The queue to be polled",
13
- "Type": "String"
14
- },
15
11
  "Name": {
16
12
  "Description": "The CFN name to be loaded",
17
13
  "Type": "String"
@@ -0,0 +1,51 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Description": "AWS CloudFormation template for standing a redis cluster.",
4
+
5
+ "Parameters": {
6
+ "EntryTopic": {
7
+ "Description": "SNS topic that will be used no notify custom resource creation",
8
+ "Type": "String"
9
+ }
10
+ },
11
+
12
+ "Resources": {
13
+ "RedisClusterReplicationGroup": {
14
+ "Type": "Custom::ElastiCacheReplicationGroup",
15
+ "Properties": {
16
+ "ServiceToken": {
17
+ "Ref": "EntryTopic"
18
+ },
19
+ "ClusterId": "cluster-id-here",
20
+ "ReplicationGroupId": "dev-redis-rep-group",
21
+ "Description": "Sample replication group for the redis instances"
22
+ }
23
+ },
24
+ "RedisReplicaCluster": {
25
+ "Type": "Custom::ElastiCacheReplicaCluster",
26
+ "Properties": {
27
+ "ServiceToken": {
28
+ "Ref": "EntryTopic"
29
+ },
30
+ "ReplicaClusterId": "dev-redis-replica",
31
+ "ReplicationGroupId": {
32
+ "Fn::GetAtt": ["RedisClusterReplicationGroup", "ReplicationGroupId"]
33
+ }
34
+ }
35
+ }
36
+ },
37
+
38
+ "Outputs": {
39
+ "ReplicationGroupId": {
40
+ "Value": {
41
+ "Fn::GetAtt": ["RedisClusterReplicationGroup", "ReplicationGroupId"]
42
+ }
43
+ },
44
+ "ReplicaClusterURLs": {
45
+ "Value": {
46
+ "Fn::GetAtt": [ "RedisReplicaCluster", "NodeURLs" ]
47
+ }
48
+ }
49
+ }
50
+
51
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Description": "AWS CloudFormation template for standing a redis cluster.",
4
+
5
+ "Parameters": {
6
+ "EntryTopic": {
7
+ "Description": "SNS topic that will be used no notify custom resource creation",
8
+ "Type": "String"
9
+ }
10
+ },
11
+
12
+ "Resources": {
13
+ "RedisClusterReplicationGroup": {
14
+ "Type": "Custom::ElastiCacheReplicationGroup",
15
+ "Properties": {
16
+ "ServiceToken": {
17
+ "Ref": "EntryTopic"
18
+ },
19
+ "ClusterId": "cluster-id-here",
20
+ "ReplicationGroupId" : "dev-redis-rep",
21
+ "Description": "Sample replication group for the redis instances"
22
+ }
23
+ }
24
+ },
25
+
26
+ "Outputs": {
27
+ "ReplicaURLs": {
28
+ "Value": {
29
+ "Fn::GetAtt": ["RedisClusterReplicationGroup", "ReplicationGroupId"]
30
+ }
31
+ }
32
+ }
33
+
34
+ }
@@ -54,7 +54,7 @@ describe CloudFormation::Bridge::Executor do
54
54
  message = "This should not have been called"
55
55
  expect(custom_resource).to receive(:create).and_raise(ArgumentError.new(message))
56
56
 
57
- expect(request).to receive(:fail!).with(message)
57
+ expect(request).to receive(:fail!).with("ArgumentError - #{message}")
58
58
 
59
59
  executor = CloudFormation::Bridge::Executor.new(registry)
60
60
  executor.execute(request)
@@ -63,11 +63,11 @@ describe CloudFormation::Bridge::Request do
63
63
  response = request.build_response
64
64
 
65
65
  expect(response).to include(
66
- FIELDS::STATUS => RESULTS::SUCCESS,
67
- FIELDS::STACK_ID => request.stack_id,
68
- FIELDS::REQUEST_ID => request.request_id,
69
- FIELDS::LOGICAL_RESOURCE_ID => request.logical_resource_id,
70
- )
66
+ FIELDS::STATUS => RESULTS::SUCCESS,
67
+ FIELDS::STACK_ID => request.stack_id,
68
+ FIELDS::REQUEST_ID => request.request_id,
69
+ FIELDS::LOGICAL_RESOURCE_ID => request.logical_resource_id,
70
+ )
71
71
 
72
72
  expect(response[FIELDS::PHYSICAL_RESOURCE_ID]).not_to be_empty
73
73
  end
@@ -102,6 +102,18 @@ describe CloudFormation::Bridge::Request do
102
102
  request.succeed!(base)
103
103
  end
104
104
 
105
+ it "ignores the provided response if it is not a hash" do
106
+ expect(CloudFormation::Bridge::HttpBridge).to receive(:put) do |url, options|
107
+ expect(url).to eq(request.request_url)
108
+
109
+ expected_response = request.build_response
110
+ expected_response.delete(FIELDS::PHYSICAL_RESOURCE_ID)
111
+
112
+ expect(options).to include(expected_response)
113
+ end
114
+ request.succeed!(true)
115
+ end
116
+
105
117
  end
106
118
 
107
119
  context 'when failing' do
@@ -0,0 +1,61 @@
1
+ require 'cloud_formation/bridge/names'
2
+ require 'cloud_formation/bridge/request'
3
+ require 'cloud_formation/bridge/resources/elasti_cache_node_urls'
4
+
5
+ describe CloudFormation::Bridge::Resources::ElastiCacheNodeUrls do
6
+
7
+ FIELDS = CloudFormation::Bridge::Names::FIELDS
8
+ ELASTI_CACHE = CloudFormation::Bridge::Names::ELASTI_CACHE
9
+
10
+ include FileSupport
11
+
12
+ context '#create' do
13
+
14
+ it 'produces the node URLs for a memcached cluster' do
15
+ cluster_id = "samplecache"
16
+
17
+ expect(subject.client).to receive(:describe_cache_clusters).
18
+ with(cache_cluster_id: cluster_id,
19
+ show_cache_node_info: true).twice.and_return(parse_json("describe-memcached-cluster"))
20
+
21
+ request = CloudFormation::Bridge::Request.new(parse_json("create-cache-node-urls-message", false))
22
+
23
+ outputs = subject.create(request)
24
+
25
+ expect(outputs).to eq(
26
+ {
27
+ FIELDS::DATA => {
28
+ ELASTI_CACHE::REPLICA_CLUSTER_ID => cluster_id,
29
+ ELASTI_CACHE::NODE_URLS => "somecache.tgbhomz.cfg.use1.cache.amazonaws.com:11211",
30
+ },
31
+ FIELDS::PHYSICAL_RESOURCE_ID => cluster_id,
32
+ }
33
+ )
34
+
35
+ end
36
+
37
+ it 'produces the node URLs for a redis cluster' do
38
+ cluster_id = "dev-redis-replica"
39
+ expect(subject.client).to receive(:describe_cache_clusters).
40
+ with(cache_cluster_id: cluster_id,
41
+ show_cache_node_info: true).twice.and_return(parse_json("describe-cache-cluster-replica-done"))
42
+
43
+ request = CloudFormation::Bridge::Request.new(parse_json("create-redis-cache-node-urls-message", false))
44
+
45
+ outputs = subject.create(request)
46
+
47
+ expect(outputs).to eq(
48
+ {
49
+ FIELDS::DATA => {
50
+ ELASTI_CACHE::REPLICA_CLUSTER_ID => cluster_id,
51
+ ELASTI_CACHE::NODE_URLS => "dev-redis-replica.mzufvw.0001.use1.cache.amazonaws.com:6379,dev-redis-replica.mzufvw.0002.use1.cache.amazonaws.com:6379",
52
+ },
53
+ FIELDS::PHYSICAL_RESOURCE_ID => cluster_id,
54
+ }
55
+ )
56
+
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,67 @@
1
+ require 'cloud_formation/bridge/names'
2
+ require 'cloud_formation/bridge/resources/elasti_cache_replica_cluster'
3
+
4
+ describe CloudFormation::Bridge::Resources::ElastiCacheReplicaCluster do
5
+
6
+ FIELDS = CloudFormation::Bridge::Names::FIELDS
7
+ ELASTI_CACHE = CloudFormation::Bridge::Names::ELASTI_CACHE
8
+
9
+ include FileSupport
10
+
11
+ let(:creating) { parse_json("describe-cache-cluster-replica") }
12
+ let(:available) { parse_json("describe-cache-cluster-replica-done") }
13
+ let(:replication_group_id) { "dev-redis-rep-group" }
14
+ let(:replica_cluster_id) { "dev-redis-replica" }
15
+
16
+ context '#create' do
17
+
18
+ let(:request) { CloudFormation::Bridge::Request.new(parse_json("create-replica-cluster-message", false)) }
19
+
20
+ it 'creates the cluster' do
21
+ expect(subject.client).to receive(:create_cache_cluster).
22
+ with(cache_cluster_id: replica_cluster_id, replication_group_id: replication_group_id)
23
+ expect(subject.client).to receive(:describe_cache_clusters).
24
+ with(cache_cluster_id: replica_cluster_id,
25
+ show_cache_node_info: true).twice.and_return(available)
26
+
27
+ outputs = subject.create(request)
28
+
29
+ expect(outputs).to eq(
30
+ {
31
+ FIELDS::DATA => {
32
+ ELASTI_CACHE::REPLICA_CLUSTER_ID => replica_cluster_id,
33
+ ELASTI_CACHE::NODE_URLS => "dev-redis-replica.mzufvw.0001.use1.cache.amazonaws.com:6379,dev-redis-replica.mzufvw.0002.use1.cache.amazonaws.com:6379",
34
+ },
35
+ FIELDS::PHYSICAL_RESOURCE_ID => replica_cluster_id,
36
+ }
37
+ )
38
+ end
39
+
40
+ end
41
+
42
+ context '#delete' do
43
+
44
+ let(:request) { CloudFormation::Bridge::Request.new(parse_json("delete-replica-cluster-message", false)) }
45
+
46
+ it 'deletes the cluster' do
47
+ expect(subject.client).to receive(:delete_cache_cluster).with(cache_cluster_id: replica_cluster_id)
48
+
49
+ count = 0
50
+
51
+ expect(subject.client).to receive(:describe_cache_clusters).
52
+ with(cache_cluster_id: replica_cluster_id,
53
+ show_cache_node_info: true).at_least(:once) do
54
+ if count == 0
55
+ count += 1
56
+ available
57
+ else
58
+ raise AWS::ElastiCache::Errors::CacheClusterNotFound
59
+ end
60
+ end
61
+
62
+ subject.delete(request)
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,65 @@
1
+ require 'cloud_formation/bridge/request'
2
+ require 'cloud_formation/bridge/names'
3
+ require 'cloud_formation/bridge/resources/elasti_cache_replication_group'
4
+
5
+ describe CloudFormation::Bridge::Resources::ElastiCacheReplicationGroup do
6
+
7
+ include FileSupport
8
+
9
+ FIELDS = CloudFormation::Bridge::Names::FIELDS
10
+ ELASTI_CACHE = CloudFormation::Bridge::Names::ELASTI_CACHE
11
+
12
+ let(:replication_group_id) { "dev-redis-rep" }
13
+
14
+ def stub_describe_replication_group
15
+ expect(subject.client).to receive(:describe_replication_groups).
16
+ with(replication_group_id: replication_group_id).
17
+ and_return(parse_json("describe-replication-group-primary-only"))
18
+ end
19
+
20
+ context "#create" do
21
+
22
+ let(:request) { CloudFormation::Bridge::Request.new(parse_json("create-replication-group-message", false)) }
23
+
24
+ it 'creates the replication group' do
25
+ expect(subject.client).to receive(:create_replication_group).with(
26
+ replication_group_id: replication_group_id,
27
+ primary_cluster_id: "cluster-id-here",
28
+ replication_group_description: "Sample replication group for the redis instances",
29
+ )
30
+
31
+ stub_describe_replication_group
32
+
33
+ outputs = subject.create(request)
34
+
35
+ expect(outputs).to eq(
36
+ FIELDS::DATA => {
37
+ ELASTI_CACHE::REPLICATION_GROUP_ID => replication_group_id,
38
+ },
39
+ FIELDS::PHYSICAL_RESOURCE_ID => replication_group_id,
40
+ )
41
+ end
42
+
43
+ end
44
+
45
+ context "#delete" do
46
+
47
+ let(:request) { CloudFormation::Bridge::Request.new(parse_json("delete-replication-group-message", false)) }
48
+
49
+ it 'should delete the group' do
50
+ stub_describe_replication_group
51
+ expect(subject.client).to receive(:delete_replication_group).with(
52
+ replication_group_id: replication_group_id,
53
+ retain_primary_cluster: true,
54
+ )
55
+ subject.delete(request)
56
+ end
57
+
58
+ it 'should ignore if the replication group does not exist' do
59
+ expect(subject).to receive(:replication_group_available?).and_raise(AWS::ElastiCache::Errors::ReplicationGroupNotFoundFault)
60
+ expect { subject.delete(request) }.not_to raise_error
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -1,7 +1,13 @@
1
+ require 'json'
2
+
1
3
  module FileSupport
2
4
 
3
5
  def read_file(name)
4
6
  IO.read(File.join(File.dirname(__FILE__), '..', 'files', name))
5
7
  end
6
8
 
9
+ def parse_json(name, symbolize_names = true)
10
+ JSON.parse(read_file("#{name}.json"), symbolize_names: symbolize_names)
11
+ end
12
+
7
13
  end