droplet_kit 2.1.0 → 2.2.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -4
  3. data/CHANGELOG.md +6 -0
  4. data/README.md +70 -1
  5. data/droplet_kit.gemspec +1 -1
  6. data/lib/droplet_kit.rb +11 -0
  7. data/lib/droplet_kit/client.rb +1 -0
  8. data/lib/droplet_kit/mappings/domain_record_mapping.rb +1 -0
  9. data/lib/droplet_kit/mappings/firewall_inbound_rule_mapping.rb +16 -0
  10. data/lib/droplet_kit/mappings/firewall_mapping.rb +25 -0
  11. data/lib/droplet_kit/mappings/firewall_outbound_rule_mapping.rb +16 -0
  12. data/lib/droplet_kit/mappings/firewall_pending_change_mapping.rb +16 -0
  13. data/lib/droplet_kit/mappings/firewall_rule_mapping.rb +14 -0
  14. data/lib/droplet_kit/mappings/tag_mapping.rb +1 -1
  15. data/lib/droplet_kit/models/domain_record.rb +1 -0
  16. data/lib/droplet_kit/models/firewall.rb +13 -0
  17. data/lib/droplet_kit/models/firewall_inbound_rule.rb +7 -0
  18. data/lib/droplet_kit/models/firewall_outbound_rule.rb +7 -0
  19. data/lib/droplet_kit/models/firewall_pending_change.rb +7 -0
  20. data/lib/droplet_kit/models/firewall_rule.rb +6 -0
  21. data/lib/droplet_kit/resources/firewall_resource.rb +85 -0
  22. data/lib/droplet_kit/resources/tag_resource.rb +0 -5
  23. data/lib/droplet_kit/version.rb +1 -1
  24. data/spec/fixtures/domain_records/all.json +5 -0
  25. data/spec/fixtures/domain_records/create.json +1 -0
  26. data/spec/fixtures/domain_records/find.json +1 -0
  27. data/spec/fixtures/domain_records/update.json +1 -0
  28. data/spec/fixtures/firewalls/all.json +67 -0
  29. data/spec/fixtures/firewalls/find.json +61 -0
  30. data/spec/lib/droplet_kit/resources/domain_record_resource_spec.rb +5 -1
  31. data/spec/lib/droplet_kit/resources/firewall_resource_spec.rb +265 -0
  32. data/spec/lib/droplet_kit/resources/tag_resource_spec.rb +0 -14
  33. data/spec/support/shared_examples/paginated_endpoint.rb +4 -2
  34. data/spec/support/shared_examples/unprocessable_entity.rb +11 -0
  35. metadata +24 -7
  36. data/spec/support/shared_examples/unsuccessful_create.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 025077918c4a61f739d58486166607209439b129
4
- data.tar.gz: c66125a6ac2909c842b79242e3c818c0e5228287
3
+ metadata.gz: 9321808dc6ae64cb77eb86c4411a41a3eb6592f9
4
+ data.tar.gz: 83ad4999326aa114fb3a05832ae08ed31c4bd86a
5
5
  SHA512:
6
- metadata.gz: 6198f8fc7be8f537cbbbd8996253c877748428ada7078c680f4f95598d3e2d7dbcd8aebb99da5623927c7d8dbaec30ff2dc6f6a2eb7c814c2bd2d6a2029c4e57
7
- data.tar.gz: f84a6955aae3e753dcba901b31527bde4048e887779be627b77a68b6a0e3b49801e71b4b3624d3d7043c4c59640af27cae4cf512d2a516ff5a7c38025ae736c8
6
+ metadata.gz: 036ef5cb5972947986806e9e194ac470d03684e32597702d3ac866b65b51dd39e7761fbc0b1b93862fbf795b3b3c46fa2b5dc1d2622461731c7e639a57db50a9
7
+ data.tar.gz: 0add3525b382329e513187b96e3ed6b1c3c7bad1485c24c327553a126de270781ec4e40c513b12e8c34d68d7dc903d6d477a31cb585279fd8620235584354909
@@ -6,15 +6,16 @@ before_install:
6
6
 
7
7
  rvm:
8
8
  - "2.0.0"
9
- - "2.1.5"
10
- - "2.2.2"
11
- - "2.3.0"
9
+ - "2.1.10"
10
+ - "2.2.7"
11
+ - "2.3.4"
12
+ - "2.4.1"
12
13
 
13
14
  matrix:
14
15
  exclude:
15
16
  - rvm: "2.0.0"
16
17
  env: ACTIVESUPPORT_VERSION=5
17
- - rvm: "2.1.5"
18
+ - rvm: "2.1.10"
18
19
  env: ACTIVESUPPORT_VERSION=5
19
20
 
20
21
  env:
@@ -1,3 +1,9 @@
1
+ ### Version 2.2.0
2
+ * Added Firewall resource.
3
+ * Added support for updating TTLs for DomainRecord resource.
4
+ * Added support of all Rails 5 releases.
5
+ * Added depreciation for Tag resource rename.
6
+
1
7
  ### Version 2.1.0
2
8
  * Added monitoring to the Droplet resource.
3
9
  * Added LoadBalancer resource.
data/README.md CHANGED
@@ -162,7 +162,8 @@ client.domain_records #=> DropletKit::DomainRecordResource
162
162
  domain_record = DropletKit::DomainRecord.new(
163
163
  type: 'CNAME',
164
164
  name: 'www',
165
- data: '@'
165
+ data: '@',
166
+ ttl: 1800
166
167
  )
167
168
  ```
168
169
 
@@ -174,6 +175,58 @@ Actions supported:
174
175
  * `client.domain_records.delete(for_domain: 'for_domain', id: 'id')`
175
176
  * `client.domain_records.update(domain_record, for_domain: 'for_domain', id: 'id')`
176
177
 
178
+ ## Firewall resource
179
+
180
+ ```ruby
181
+ client = DropletKit::Client.new(access_token: 'TOKEN')
182
+ client.firewalls #=> DropletKit::FirewallResource
183
+
184
+ inbound_rule = DropletKit::FirewallInboundRule.new(
185
+ protocol: 'icmp',
186
+ ports: '0',
187
+ sources: {
188
+ tags: ['frontend', 'backend'],
189
+ load_balancer_uids: ['d2d3920a-9d45-41b0-b018-d15e18ec60a4']
190
+ }
191
+ )
192
+
193
+ outbound_rule = DropletKit::FirewallOutboundRule.new(
194
+ protocol: 'icmp',
195
+ ports: '0',
196
+ destinations: {
197
+ addresses: ["127.0.0.0"],
198
+ droplet_ids: [456, 789]
199
+ }
200
+ )
201
+
202
+ firewall = DropletKit::Firewall.new(
203
+ name: 'firewall',
204
+ inbound_rules: [
205
+ inbound_rule
206
+ ],
207
+ outbound_rules: [
208
+ outbound_rule
209
+ ],
210
+ droplet_ids: [123],
211
+ tags: ['backend']
212
+ )
213
+ ```
214
+
215
+ Actions supported:
216
+
217
+ * `client.firewalls.find(id: 'id')`
218
+ * `client.firewalls.create(firewall)`
219
+ * `client.firewalls.update(firewall, id: 'id')`
220
+ * `client.firewalls.all()`
221
+ * `client.firewalls.all_by_droplet(droplet_id: 'id')`
222
+ * `client.firewalls.delete(id: 'id')`
223
+ * `client.firewalls.add_droplets([droplet.id], id: 'id')`
224
+ * `client.firewalls.remove_droplets([droplet.id], id: 'id')`
225
+ * `client.firewalls.add_tags([tag.name], id: 'id')`
226
+ * `client.firewalls.remove_tags([tag.name], id: 'id')`
227
+ * `client.firewalls.add_rules(inbound_rules: [inbound_rule], outbound_rules: [outbound_rule], id: 'id')`
228
+ * `client.firewalls.remove_rules(inbound_rules: [inbound_rule], outbound_rules: [outbound_rule], id: 'id')`
229
+
177
230
 
178
231
  ## Image resource
179
232
 
@@ -272,6 +325,22 @@ Actions supported:
272
325
  * `client.ssh_keys.delete(id: 'id')`
273
326
  * `client.ssh_keys.update(ssh_key, id: 'id')`
274
327
 
328
+ ## Tag resource
329
+
330
+ ```ruby
331
+ client = DropletKit::Client.new(access_token: 'TOKEN')
332
+ client.tags #=> DropletKit::TagResource
333
+ ```
334
+
335
+ Actions supported:
336
+
337
+ * `client.tags.all()`
338
+ * `client.tags.find(name: 'name')`
339
+ * `client.tags.create(tag)
340
+ * `client.tags.delete(name: 'name')`
341
+ * `client.tags.tag_resources(name: 'name', resources: [{ resource_id => 'droplet_id', resource_type: 'droplet' }])`
342
+ * `client.tags.untag_resources(name 'name', resources: [{ resource_id => 'droplet_id', resource_type: 'droplet' }])`
343
+
275
344
  ## Account resource
276
345
 
277
346
  ```ruby
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'virtus', '~> 1.0.3'
24
24
  spec.add_dependency "resource_kit", '~> 0.1.5'
25
25
  spec.add_dependency "kartograph", '~> 0.2.3'
26
- spec.add_dependency "activesupport", '> 3.0', '< 5.1'
26
+ spec.add_dependency "activesupport", '> 3.0', '< 6'
27
27
  spec.add_dependency "faraday", '~> 0.9.1'
28
28
 
29
29
  spec.add_development_dependency "bundler", ">= 1.11.0"
@@ -33,6 +33,11 @@ module DropletKit
33
33
  autoload :HealthCheck, 'droplet_kit/models/health_check'
34
34
  autoload :ForwardingRule, 'droplet_kit/models/forwarding_rule'
35
35
  autoload :Certificate, 'droplet_kit/models/certificate'
36
+ autoload :Firewall, 'droplet_kit/models/firewall'
37
+ autoload :FirewallRule, 'droplet_kit/models/firewall_rule'
38
+ autoload :FirewallInboundRule, 'droplet_kit/models/firewall_inbound_rule'
39
+ autoload :FirewallOutboundRule, 'droplet_kit/models/firewall_outbound_rule'
40
+ autoload :FirewallPendingChange, 'droplet_kit/models/firewall_pending_change'
36
41
 
37
42
  # Resources
38
43
  autoload :DropletResource, 'droplet_kit/resources/droplet_resource'
@@ -55,6 +60,7 @@ module DropletKit
55
60
  autoload :SnapshotResource, 'droplet_kit/resources/snapshot_resource'
56
61
  autoload :LoadBalancerResource, 'droplet_kit/resources/load_balancer_resource'
57
62
  autoload :CertificateResource, 'droplet_kit/resources/certificate_resource'
63
+ autoload :FirewallResource, 'droplet_kit/resources/firewall_resource'
58
64
 
59
65
  # JSON Maps
60
66
  autoload :DropletMapping, 'droplet_kit/mappings/droplet_mapping'
@@ -83,6 +89,11 @@ module DropletKit
83
89
  autoload :HealthCheckMapping, 'droplet_kit/mappings/health_check_mapping'
84
90
  autoload :ForwardingRuleMapping, 'droplet_kit/mappings/forwarding_rule_mapping'
85
91
  autoload :CertificateMapping, 'droplet_kit/mappings/certificate_mapping'
92
+ autoload :FirewallMapping, 'droplet_kit/mappings/firewall_mapping'
93
+ autoload :FirewallRuleMapping, 'droplet_kit/mappings/firewall_rule_mapping'
94
+ autoload :FirewallInboundRuleMapping, 'droplet_kit/mappings/firewall_inbound_rule_mapping'
95
+ autoload :FirewallOutboundRuleMapping, 'droplet_kit/mappings/firewall_outbound_rule_mapping'
96
+ autoload :FirewallPendingChangeMapping, 'droplet_kit/mappings/firewall_pending_change_mapping'
86
97
 
87
98
  # Utils
88
99
  autoload :PaginatedResource, 'droplet_kit/paginated_resource'
@@ -24,6 +24,7 @@ module DropletKit
24
24
  domains: DomainResource,
25
25
  domain_records: DomainRecordResource,
26
26
  droplet_actions: DropletActionResource,
27
+ firewalls: FirewallResource,
27
28
  images: ImageResource,
28
29
  image_actions: ImageActionResource,
29
30
  load_balancers: LoadBalancerResource,
@@ -12,6 +12,7 @@ module DropletKit
12
12
  property :data, scopes: [:read, :create, :update]
13
13
  property :priority, scopes: [:read, :create, :update]
14
14
  property :port, scopes: [:read, :create, :update]
15
+ property :ttl, scopes: [:read, :create, :update]
15
16
  property :weight, scopes: [:read, :create, :update]
16
17
  end
17
18
  end
@@ -0,0 +1,16 @@
1
+ module DropletKit
2
+ class FirewallInboundRuleMapping
3
+ include Kartograph::DSL
4
+
5
+ kartograph do
6
+ mapping FirewallInboundRule
7
+ root_key plural: 'inbound_rules', scopes: [:read, :create, :update]
8
+
9
+ scoped :read, :create, :update do
10
+ property :protocol
11
+ property :ports
12
+ property :sources
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module DropletKit
2
+ class FirewallMapping
3
+ include Kartograph::DSL
4
+
5
+ kartograph do
6
+ mapping Firewall
7
+ root_key singular: 'firewall', plural: 'firewalls', scopes: [:read]
8
+
9
+ scoped :read do
10
+ property :id
11
+ property :status
12
+ property :created_at
13
+ property :pending_changes, plural: true, include: FirewallPendingChangeMapping
14
+ end
15
+
16
+ scoped :read, :create, :update do
17
+ property :name
18
+ property :inbound_rules, plural: true, include: FirewallInboundRuleMapping
19
+ property :outbound_rules, plural: true, include: FirewallOutboundRuleMapping
20
+ property :droplet_ids
21
+ property :tags
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module DropletKit
2
+ class FirewallOutboundRuleMapping
3
+ include Kartograph::DSL
4
+
5
+ kartograph do
6
+ mapping FirewallOutboundRule
7
+ root_key plural: 'outbound_rules', scopes: [:read, :create, :update]
8
+
9
+ scoped :read, :create, :update do
10
+ property :protocol
11
+ property :ports
12
+ property :destinations
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module DropletKit
2
+ class FirewallPendingChangeMapping
3
+ include Kartograph::DSL
4
+
5
+ kartograph do
6
+ mapping FirewallPendingChange
7
+ root_key plural: 'pending_changes', scopes: [:read]
8
+
9
+ scoped :read do
10
+ property :droplet_id
11
+ property :removing
12
+ property :status
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module DropletKit
2
+ class FirewallRuleMapping
3
+ include Kartograph::DSL
4
+
5
+ kartograph do
6
+ mapping FirewallRule
7
+
8
+ scoped :create, :update do
9
+ property :inbound_rules, plural: true, include: FirewallInboundRuleMapping
10
+ property :outbound_rules, plural: true, include: FirewallOutboundRuleMapping
11
+ end
12
+ end
13
+ end
14
+ end
@@ -6,7 +6,7 @@ module DropletKit
6
6
  mapping Tag
7
7
  root_key plural: 'tags', singular: 'tag', scopes: [:read]
8
8
 
9
- scoped :read, :create, :update do
9
+ scoped :read, :create do
10
10
  property :name
11
11
  end
12
12
 
@@ -6,6 +6,7 @@ module DropletKit
6
6
  attribute :data
7
7
  attribute :priority
8
8
  attribute :port
9
+ attribute :ttl
9
10
  attribute :weight
10
11
  end
11
12
  end
@@ -0,0 +1,13 @@
1
+ module DropletKit
2
+ class Firewall < BaseModel
3
+ attribute :id
4
+ attribute :name
5
+ attribute :status
6
+ attribute :created_at
7
+ attribute :inbound_rules
8
+ attribute :outbound_rules
9
+ attribute :droplet_ids
10
+ attribute :tags
11
+ attribute :pending_changes
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module DropletKit
2
+ class FirewallInboundRule < BaseModel
3
+ attribute :protocol
4
+ attribute :ports
5
+ attribute :sources
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module DropletKit
2
+ class FirewallOutboundRule < BaseModel
3
+ attribute :protocol
4
+ attribute :ports
5
+ attribute :destinations
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module DropletKit
2
+ class FirewallPendingChange < BaseModel
3
+ attribute :droplet_id
4
+ attribute :removing
5
+ attribute :status
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module DropletKit
2
+ class FirewallRule < BaseModel
3
+ attribute :inbound_rules
4
+ attribute :outbound_rules
5
+ end
6
+ end
@@ -0,0 +1,85 @@
1
+ module DropletKit
2
+ class FirewallResource < ResourceKit::Resource
3
+ include ErrorHandlingResourcable
4
+
5
+ resources do
6
+ action :find, 'GET /v2/firewalls/:id' do
7
+ handler(200) { |response| FirewallMapping.extract_single(response.body, :read) }
8
+ end
9
+
10
+ action :create, 'POST /v2/firewalls' do
11
+ body { |firewall| FirewallMapping.representation_for(:create, firewall) }
12
+ handler(202) { |response| FirewallMapping.extract_single(response.body, :read) }
13
+ handler(422) { |response| ErrorMapping.fail_with(FailedCreate, response.body) }
14
+ end
15
+
16
+ action :update, 'PUT /v2/firewalls/:id' do
17
+ body { |firewall| FirewallMapping.representation_for(:update, firewall) }
18
+ handler(200) { |response| FirewallMapping.extract_single(response.body, :read) }
19
+ handler(422) { |response| ErrorMapping.fail_with(FailedUpdate, response.body) }
20
+ end
21
+
22
+ action :all, 'GET /v2/firewalls' do
23
+ query_keys :per_page, :page
24
+ handler(200) { |response| FirewallMapping.extract_collection(response.body, :read) }
25
+ end
26
+
27
+ action :all_by_droplet, 'GET /v2/droplets/:droplet_id/firewalls' do
28
+ query_keys :per_page, :page
29
+ handler(200) { |response| FirewallMapping.extract_collection(response.body, :read) }
30
+ end
31
+
32
+ action :delete, 'DELETE /v2/firewalls/:id' do
33
+ handler(204) { |_| true }
34
+ end
35
+
36
+ action :add_droplets, 'POST /v2/firewalls/:id/droplets' do
37
+ body { |droplet_ids| { droplet_ids: droplet_ids }.to_json }
38
+ handler(204) { |_| true }
39
+ end
40
+
41
+ action :remove_droplets, 'DELETE /v2/firewalls/:id/droplets' do
42
+ body { |droplet_ids| { droplet_ids: droplet_ids }.to_json }
43
+ handler(204) { |_| true }
44
+ end
45
+
46
+ action :add_tags, 'POST /v2/firewalls/:id/tags' do
47
+ body { |tags| { tags: tags}.to_json }
48
+ handler(204) { |_| true }
49
+ end
50
+
51
+ action :remove_tags, 'DELETE /v2/firewalls/:id/tags' do
52
+ body { |tags| { tags: tags}.to_json }
53
+ handler(204) { |_| true }
54
+ end
55
+
56
+ action :add_rules, 'POST /v2/firewalls/:id/rules' do
57
+ body do |rules|
58
+ DropletKit::FirewallRuleMapping
59
+ .representation_for(:create,
60
+ FirewallRule.new(inbound_rules: rules[:inbound_rules],
61
+ outbound_rules: rules[:outbound_rules]))
62
+ end
63
+ handler(204) { |_| true }
64
+ end
65
+
66
+ action :remove_rules, 'DELETE /v2/firewalls/:id/rules' do
67
+ body do |rules|
68
+ DropletKit::FirewallRuleMapping
69
+ .representation_for(:update,
70
+ FirewallRule.new(inbound_rules: rules[:inbound_rules],
71
+ outbound_rules: rules[:outbound_rules]))
72
+ end
73
+ handler(204) { |_| true }
74
+ end
75
+ end
76
+
77
+ def all(*args)
78
+ PaginatedResource.new(action(:all), self, *args)
79
+ end
80
+
81
+ def all_by_droplet(*args)
82
+ PaginatedResource.new(action(:all_by_droplet), self, *args)
83
+ end
84
+ end
85
+ end
@@ -18,11 +18,6 @@ module DropletKit
18
18
  handler(422) { |response| ErrorMapping.fail_with(FailedCreate, response.body) }
19
19
  end
20
20
 
21
- action :update, 'PUT /v2/tags/:name' do
22
- body { |object| TagMapping.representation_for(:update, object) }
23
- handler(200) { |response| TagMapping.extract_single(response.body, :read) }
24
- end
25
-
26
21
  action :delete, 'DELETE /v2/tags/:name' do
27
22
  handler(204) { |_| true }
28
23
  handler(422) { |response| ErrorMapping.fail_with(FailedCreate, response.body) }
@@ -1,3 +1,3 @@
1
1
  module DropletKit
2
- VERSION = "2.1.0"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -7,6 +7,7 @@
7
7
  "data": "8.8.8.8",
8
8
  "priority": null,
9
9
  "port": null,
10
+ "ttl": 1800,
10
11
  "weight": null
11
12
  },
12
13
  {
@@ -16,6 +17,7 @@
16
17
  "data": "NS1.DIGITALOCEAN.COM.",
17
18
  "priority": null,
18
19
  "port": null,
20
+ "ttl": 1800,
19
21
  "weight": null
20
22
  },
21
23
  {
@@ -25,6 +27,7 @@
25
27
  "data": "NS2.DIGITALOCEAN.COM.",
26
28
  "priority": null,
27
29
  "port": null,
30
+ "ttl": 1800,
28
31
  "weight": null
29
32
  },
30
33
  {
@@ -34,6 +37,7 @@
34
37
  "data": "NS3.DIGITALOCEAN.COM.",
35
38
  "priority": null,
36
39
  "port": null,
40
+ "ttl": 1800,
37
41
  "weight": null
38
42
  },
39
43
  {
@@ -43,6 +47,7 @@
43
47
  "data": "@",
44
48
  "priority": null,
45
49
  "port": null,
50
+ "ttl": 1800,
46
51
  "weight": null
47
52
  }
48
53
  ],
@@ -6,6 +6,7 @@
6
6
  "data": "@",
7
7
  "priority": null,
8
8
  "port": null,
9
+ "ttl": 90,
9
10
  "weight": null
10
11
  }
11
12
  }
@@ -6,6 +6,7 @@
6
6
  "data": "@",
7
7
  "priority": null,
8
8
  "port": null,
9
+ "ttl": 1800,
9
10
  "weight": null
10
11
  }
11
12
  }
@@ -6,6 +6,7 @@
6
6
  "data": "@",
7
7
  "priority": null,
8
8
  "port": null,
9
+ "ttl": 1800,
9
10
  "weight": null
10
11
  }
11
12
  }
@@ -0,0 +1,67 @@
1
+ {
2
+ "firewalls": [
3
+ {
4
+ "id": "11d87802-df17-4f8f-a691-58e408570c12",
5
+ "name": "firewall",
6
+ "status": "succeeded",
7
+ "inbound_rules": [
8
+ {
9
+ "protocol": "icmp",
10
+ "ports": "0",
11
+ "sources": {
12
+ "load_balancer_uids": [
13
+ "d2d3920a-9d45-41b0-b018-d15e18ec60a4"
14
+ ],
15
+ "tags": [
16
+ "backend"
17
+ ]
18
+ }
19
+ },
20
+ {
21
+ "protocol": "tcp",
22
+ "ports": "8000-9000",
23
+ "sources": {
24
+ "addresses": [
25
+ "0.0.0.0/0"
26
+ ]
27
+ }
28
+ }
29
+ ],
30
+ "outbound_rules": [
31
+ {
32
+ "protocol": "icmp",
33
+ "ports": "0",
34
+ "destinations": {
35
+ "tags": [
36
+ "backend"
37
+ ]
38
+ }
39
+ },
40
+ {
41
+ "protocol": "tcp",
42
+ "ports": "8000-9000",
43
+ "destinations": {
44
+ "addresses": [
45
+ "127.0.0.0"
46
+ ],
47
+ "droplet_ids": [
48
+ 345
49
+ ]
50
+ }
51
+ }
52
+ ],
53
+ "created_at": "2017-05-30T16:25:21Z",
54
+ "droplet_ids": [
55
+ 123
56
+ ],
57
+ "tags": [
58
+ "backend"
59
+ ],
60
+ "pending_changes": []
61
+ }
62
+ ],
63
+ "links": {},
64
+ "meta": {
65
+ "total": 1
66
+ }
67
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "firewall": {
3
+ "id": "11d87802-df17-4f8f-a691-58e408570c12",
4
+ "name": "firewall",
5
+ "status": "succeeded",
6
+ "inbound_rules": [
7
+ {
8
+ "protocol": "icmp",
9
+ "ports": "0",
10
+ "sources": {
11
+ "load_balancer_uids": [
12
+ "d2d3920a-9d45-41b0-b018-d15e18ec60a4"
13
+ ],
14
+ "tags": [
15
+ "backend"
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "protocol": "tcp",
21
+ "ports": "8000-9000",
22
+ "sources": {
23
+ "addresses": [
24
+ "0.0.0.0/0"
25
+ ]
26
+ }
27
+ }
28
+ ],
29
+ "outbound_rules": [
30
+ {
31
+ "protocol": "icmp",
32
+ "ports": "0",
33
+ "destinations": {
34
+ "tags": [
35
+ "backend"
36
+ ]
37
+ }
38
+ },
39
+ {
40
+ "protocol": "tcp",
41
+ "ports": "8000-9000",
42
+ "destinations": {
43
+ "addresses": [
44
+ "127.0.0.0"
45
+ ],
46
+ "droplet_ids": [
47
+ 345
48
+ ]
49
+ }
50
+ }
51
+ ],
52
+ "created_at": "2017-05-30T16:25:21Z",
53
+ "droplet_ids": [
54
+ 123
55
+ ],
56
+ "tags": [
57
+ "backend"
58
+ ],
59
+ "pending_changes": []
60
+ }
61
+ }
@@ -29,12 +29,14 @@ RSpec.describe DropletKit::DomainRecordResource do
29
29
  domain_record = DropletKit::DomainRecord.new(
30
30
  type: 'CNAME',
31
31
  name: 'www',
32
- data: '@'
32
+ data: '@',
33
+ ttl: 90
33
34
  )
34
35
  as_hash = DropletKit::DomainRecordMapping.hash_for(:create, domain_record)
35
36
  expect(as_hash['type']).to eq('CNAME')
36
37
  expect(as_hash['name']).to eq('www')
37
38
  expect(as_hash['data']).to eq('@')
39
+ expect(as_hash['ttl']).to eq(90)
38
40
 
39
41
  as_json = DropletKit::DomainRecordMapping.representation_for(:create, domain_record)
40
42
  stub_do_api('/v2/domains/example.com/records', :post).with(body: as_json).to_return(body: response, status: 201)
@@ -44,6 +46,7 @@ RSpec.describe DropletKit::DomainRecordResource do
44
46
  expect(created_domain_record.name).to eq('www')
45
47
  expect(created_domain_record.type).to eq('CNAME')
46
48
  expect(created_domain_record.data).to eq('@')
49
+ expect(created_domain_record.ttl).to eq(90)
47
50
  end
48
51
  end
49
52
 
@@ -90,6 +93,7 @@ RSpec.describe DropletKit::DomainRecordResource do
90
93
  expect(updated_domain_record.name).to eq('lol')
91
94
  expect(updated_domain_record.type).to eq('CNAME')
92
95
  expect(updated_domain_record.data).to eq('@')
96
+ expect(updated_domain_record.ttl).to eq(1800)
93
97
  end
94
98
  end
95
99
  end
@@ -0,0 +1,265 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe DropletKit::FirewallResource do
4
+ include_context 'resources'
5
+
6
+ let(:firewall_fixture_path) { 'firewalls/find' }
7
+ let(:base_path) { '/v2/firewalls' }
8
+ let(:firewall_id) { '11d87802-df17-4f8f-a691-58e408570c12' }
9
+ let(:firewall) do
10
+ DropletKit::Firewall.new(
11
+ name: 'firewall',
12
+ inbound_rules: [
13
+ DropletKit::FirewallInboundRule.new(
14
+ protocol: 'icmp',
15
+ ports: '0',
16
+ sources: {
17
+ tags: ['backend'],
18
+ load_balancer_uids: ['d2d3920a-9d45-41b0-b018-d15e18ec60a4']
19
+ }
20
+ ),
21
+ DropletKit::FirewallInboundRule.new(
22
+ protocol: 'tcp',
23
+ ports: '8000-9000',
24
+ sources: {
25
+ addresses: ['0.0.0.0/0']
26
+ }
27
+ )
28
+ ],
29
+ outbound_rules: [
30
+ DropletKit::FirewallOutboundRule.new(
31
+ protocol: 'icmp',
32
+ ports: '0',
33
+ destinations: {
34
+ tags: ['backend']
35
+ }
36
+ ),
37
+ DropletKit::FirewallOutboundRule.new(
38
+ protocol: 'tcp',
39
+ ports: '8000-9000',
40
+ destinations: {
41
+ addresses: ['127.0.0.0']
42
+ }
43
+ )
44
+ ],
45
+ droplet_ids: [123],
46
+ tags: ['backend'])
47
+ end
48
+
49
+ subject(:resource) { described_class.new(connection: connection) }
50
+
51
+ RSpec::Matchers.define :match_firewall_fixture do
52
+ match do |firewall|
53
+ expect(firewall.id).to eq('11d87802-df17-4f8f-a691-58e408570c12')
54
+ expect(firewall.name).to eq('firewall')
55
+ expect(firewall.status).to eq('succeeded')
56
+ expect(firewall.created_at).to eq('2017-05-30T16:25:21Z')
57
+ expect(firewall.inbound_rules.count).to eq(2)
58
+ expect(firewall.inbound_rules.first.attributes)
59
+ .to match(a_hash_including(protocol: 'icmp', ports: '0',
60
+ sources: { 'load_balancer_uids' => ['d2d3920a-9d45-41b0-b018-d15e18ec60a4'],
61
+ 'tags' => ['backend'] }))
62
+ expect(firewall.inbound_rules.last.attributes)
63
+ .to match(a_hash_including(protocol: 'tcp', ports: '8000-9000',
64
+ sources: { 'addresses' => ['0.0.0.0/0'] }))
65
+ expect(firewall.outbound_rules.count).to eq(2)
66
+ expect(firewall.outbound_rules.first.attributes)
67
+ .to match(a_hash_including(protocol: 'icmp', ports: '0',
68
+ destinations: { 'tags' => ['backend'] }))
69
+ expect(firewall.outbound_rules.last.attributes)
70
+ .to match(a_hash_including(protocol: 'tcp', ports: '8000-9000',
71
+ destinations: { 'addresses' => ['127.0.0.0'],
72
+ 'droplet_ids' => [345] }))
73
+ expect(firewall.droplet_ids).to match_array([123])
74
+ expect(firewall.tags).to match_array(['backend'])
75
+ expect(firewall.pending_changes).to be_empty
76
+ end
77
+ end
78
+
79
+ describe '#find' do
80
+ it 'returns firewall' do
81
+ stub_do_api(File.join(base_path, firewall_id), :get).to_return(body: api_fixture(firewall_fixture_path))
82
+ firewall = resource.find(id: firewall_id)
83
+
84
+ expect(firewall).to match_firewall_fixture
85
+ end
86
+ end
87
+
88
+ describe '#create' do
89
+ let(:path) { base_path }
90
+
91
+ it 'returns created firewall' do
92
+ json_body = DropletKit::FirewallMapping.representation_for(:create, firewall)
93
+ stub_do_api(path, :post).with(body: json_body).to_return(body: api_fixture(firewall_fixture_path), status: 202)
94
+
95
+ expect(resource.create(firewall)).to match_firewall_fixture
96
+ end
97
+
98
+ it_behaves_like 'an action that handles invalid parameters' do
99
+ let(:action) { 'create' }
100
+ let(:arguments) { DropletKit::Firewall.new }
101
+ end
102
+ end
103
+
104
+ describe '#update' do
105
+ let(:path) { base_path }
106
+
107
+ it 'returns updated firewall' do
108
+ json_body = DropletKit::FirewallMapping.representation_for(:update, firewall)
109
+ stub_do_api(File.join(base_path, firewall_id), :put).with(body: json_body).to_return(body: api_fixture(firewall_fixture_path), status: 200)
110
+
111
+ expect(resource.update(firewall, id: firewall_id)).to match_firewall_fixture
112
+ end
113
+
114
+ it_behaves_like 'an action that handles invalid parameters' do
115
+ let(:verb) { :put }
116
+ let(:exception) { DropletKit::FailedUpdate }
117
+ let(:action) { 'update' }
118
+ let(:arguments) { DropletKit::Firewall.new }
119
+ end
120
+ end
121
+
122
+ describe '#all' do
123
+ let(:firewalls_fixture_path) { 'firewalls/all' }
124
+
125
+ it 'returns all firewalls' do
126
+ stub_do_api(base_path, :get).to_return(body: api_fixture(firewalls_fixture_path))
127
+ firewalls = resource.all
128
+
129
+ expect(firewalls).to all(be_kind_of(DropletKit::Firewall))
130
+ expect(firewalls.first).to match_firewall_fixture
131
+ end
132
+
133
+ it_behaves_like 'a paginated index' do
134
+ let(:fixture_path) { firewalls_fixture_path }
135
+ let(:api_path) { base_path }
136
+ end
137
+ end
138
+
139
+ describe '#all_by_droplet' do
140
+ let(:droplet_id) { 123 }
141
+ let(:all_by_droplet_path) { "/v2/droplets/#{droplet_id}/firewalls" }
142
+ let(:firewalls_fixture_path) { 'firewalls/all' }
143
+
144
+ it 'returns all firewalls for a provided droplet' do
145
+ stub_do_api(all_by_droplet_path, :get).to_return(body: api_fixture(firewalls_fixture_path))
146
+ firewalls = resource.all_by_droplet(droplet_id: droplet_id)
147
+
148
+ expect(firewalls).to all(be_kind_of(DropletKit::Firewall))
149
+ expect(firewalls.first).to match_firewall_fixture
150
+ end
151
+
152
+ it_behaves_like 'a paginated index' do
153
+ let(:fixture_path) { firewalls_fixture_path }
154
+ let(:action) { :all_by_droplet }
155
+ let(:parameters) { { droplet_id: droplet_id } }
156
+ let(:api_path) { all_by_droplet_path }
157
+ end
158
+ end
159
+
160
+ describe '#delete' do
161
+ it 'sends request to delete given firewall' do
162
+ request = stub_do_api(File.join(base_path, firewall_id), :delete)
163
+ resource.delete(id: firewall_id)
164
+
165
+ expect(request).to have_been_made
166
+ end
167
+ end
168
+
169
+ context 'droplets' do
170
+ let(:droplet_id_1) { 1 }
171
+ let(:droplet_id_2) { 2 }
172
+
173
+ describe '#add_droplets' do
174
+ it 'sends request to add droplets for a given firewall' do
175
+ request = stub_do_api(File.join(base_path, firewall_id, 'droplets'), :post).with(body: { droplet_ids: [droplet_id_1, droplet_id_2] }.to_json)
176
+ resource.add_droplets([droplet_id_1, droplet_id_2], id: firewall_id)
177
+
178
+ expect(request).to have_been_made
179
+ end
180
+ end
181
+
182
+ describe '#remove_droplets' do
183
+ it 'sends request to remove droplets from a given firewall' do
184
+ request = stub_do_api(File.join(base_path, firewall_id, 'droplets'), :delete).with(body: { droplet_ids: [droplet_id_1, droplet_id_2]}.to_json)
185
+ resource.remove_droplets([droplet_id_1, droplet_id_2], id: firewall_id)
186
+
187
+ expect(request).to have_been_made
188
+ end
189
+ end
190
+ end
191
+
192
+ context 'tags' do
193
+ let(:frontend_tag) { 'frontend' }
194
+ let(:backend_tag) { 'backend' }
195
+
196
+ describe '#add_tags' do
197
+ it 'sends request to add tags for a given firewall' do
198
+ request = stub_do_api(File.join(base_path, firewall_id, 'tags'), :post).with(body: { tags: [frontend_tag, backend_tag] }.to_json)
199
+ resource.add_tags([frontend_tag, backend_tag], id: firewall_id)
200
+
201
+ expect(request).to have_been_made
202
+ end
203
+ end
204
+
205
+ describe '#remove_tags' do
206
+ it 'sends request to remove tags from a given firewall' do
207
+ request = stub_do_api(File.join(base_path, firewall_id, 'tags'), :delete).with(body: { tags: [frontend_tag, backend_tag]}.to_json)
208
+ resource.remove_tags([frontend_tag, backend_tag], id: firewall_id)
209
+
210
+ expect(request).to have_been_made
211
+ end
212
+ end
213
+ end
214
+
215
+ context 'rules' do
216
+ let(:inbound_rule) do
217
+ DropletKit::FirewallInboundRule.new(
218
+ protocol: 'tcp',
219
+ ports: '22',
220
+ sources: {
221
+ addresses: ['127.0.0.0'],
222
+ tags: ['frontend', 'backend']
223
+ }
224
+ )
225
+ end
226
+
227
+ let(:outbound_rule) do
228
+ DropletKit::FirewallOutboundRule.new(
229
+ protocol: 'tcp',
230
+ ports: '8080',
231
+ destinations: {
232
+ droplet_ids: [123, 456],
233
+ load_balancer_uids: ['lb-uuid']
234
+ }
235
+ )
236
+ end
237
+
238
+ let(:rules) do
239
+ DropletKit::FirewallRule.new(
240
+ inbound_rules: [inbound_rule],
241
+ outbound_rules: [outbound_rule]
242
+ )
243
+ end
244
+
245
+ describe '#add_rules' do
246
+ it 'sends request to add rules for a given firewall' do
247
+ json_body = DropletKit::FirewallRuleMapping.representation_for(:create, rules)
248
+ request = stub_do_api(File.join(base_path, firewall_id, 'rules'), :post).with(body: json_body)
249
+ resource.add_rules(inbound_rules: [inbound_rule], outbound_rules: [outbound_rule], id: firewall_id)
250
+
251
+ expect(request).to have_been_made
252
+ end
253
+ end
254
+
255
+ describe '#remove_rules' do
256
+ it 'sends request to remove rules from a given firewall' do
257
+ json_body = DropletKit::FirewallRuleMapping.representation_for(:update, rules)
258
+ request = stub_do_api(File.join(base_path, firewall_id, 'rules'), :delete).with(body: json_body)
259
+ resource.remove_rules(inbound_rules: [inbound_rule], outbound_rules: [outbound_rule], id: firewall_id)
260
+
261
+ expect(request).to have_been_made
262
+ end
263
+ end
264
+ end
265
+ end
@@ -67,20 +67,6 @@ describe DropletKit::TagResource do
67
67
  end
68
68
  end
69
69
 
70
- describe '#update' do
71
- it 'updateds a tag' do
72
- tag = DropletKit::Tag.new(name: 'old-testing-1')
73
- tag.name = 'testing-1'
74
-
75
- request = stub_do_api('/v2/tags/old-testing-1', :put)
76
- .with(body: DropletKit::TagMapping.representation_for(:update, tag))
77
- .to_return(body: api_fixture('tags/find'))
78
-
79
- tag = resource.update(tag, name: 'old-testing-1')
80
- expect(tag.name).to eq('testing-1')
81
- end
82
- end
83
-
84
70
  describe '#delete' do
85
71
  it 'deletes a tag' do
86
72
  request = stub_do_api('/v2/tags/testing-1', :delete)
@@ -4,11 +4,13 @@ shared_examples_for 'a paginated index' do
4
4
  let(:fixture_path) { }
5
5
  let(:api_path) { }
6
6
  let(:parameters) { {} }
7
+ let(:action) { :all }
7
8
 
8
9
  it 'returns a paginated resource' do
9
10
  fixture = api_fixture(fixture_path)
10
11
  stub_do_api(api_path, :get).to_return(body: fixture)
11
- response = resource.all({page: 1, per_page: 1}.merge(parameters))
12
+ response = resource.send(action, {page: 1, per_page: 1}.merge(parameters))
13
+
12
14
  expect(response).to be_kind_of(DropletKit::PaginatedResource)
13
15
  end
14
- end
16
+ end
@@ -0,0 +1,11 @@
1
+ shared_examples_for 'an action that handles invalid parameters' do
2
+ let(:verb) { :post }
3
+ let(:exception) { DropletKit::FailedCreate }
4
+
5
+ it 'raises an exception with the message attached' do
6
+ response_body = { id: :unprocessable_entity, message: 'Something is not right' }
7
+ stub_do_api(path, verb).to_return(body: response_body.to_json, status: 422)
8
+
9
+ expect { resource.send(action, arguments) }.to raise_exception(exception).with_message(response_body[:message])
10
+ end
11
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: droplet_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Ross
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-13 00:00:00.000000000 Z
11
+ date: 2017-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: virtus
@@ -61,7 +61,7 @@ dependencies:
61
61
  version: '3.0'
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
- version: '5.1'
64
+ version: '6'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,7 +71,7 @@ dependencies:
71
71
  version: '3.0'
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
- version: '5.1'
74
+ version: '6'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: faraday
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -211,6 +211,11 @@ files:
211
211
  - lib/droplet_kit/mappings/droplet_mapping.rb
212
212
  - lib/droplet_kit/mappings/droplet_upgrade_mapping.rb
213
213
  - lib/droplet_kit/mappings/error_mapping.rb
214
+ - lib/droplet_kit/mappings/firewall_inbound_rule_mapping.rb
215
+ - lib/droplet_kit/mappings/firewall_mapping.rb
216
+ - lib/droplet_kit/mappings/firewall_outbound_rule_mapping.rb
217
+ - lib/droplet_kit/mappings/firewall_pending_change_mapping.rb
218
+ - lib/droplet_kit/mappings/firewall_rule_mapping.rb
214
219
  - lib/droplet_kit/mappings/floating_ip_mapping.rb
215
220
  - lib/droplet_kit/mappings/forwarding_rule_mapping.rb
216
221
  - lib/droplet_kit/mappings/health_check_mapping.rb
@@ -236,6 +241,11 @@ files:
236
241
  - lib/droplet_kit/models/domain_record.rb
237
242
  - lib/droplet_kit/models/droplet.rb
238
243
  - lib/droplet_kit/models/droplet_upgrade.rb
244
+ - lib/droplet_kit/models/firewall.rb
245
+ - lib/droplet_kit/models/firewall_inbound_rule.rb
246
+ - lib/droplet_kit/models/firewall_outbound_rule.rb
247
+ - lib/droplet_kit/models/firewall_pending_change.rb
248
+ - lib/droplet_kit/models/firewall_rule.rb
239
249
  - lib/droplet_kit/models/floating_ip.rb
240
250
  - lib/droplet_kit/models/forwarding_rule.rb
241
251
  - lib/droplet_kit/models/health_check.rb
@@ -264,6 +274,7 @@ files:
264
274
  - lib/droplet_kit/resources/droplet_action_resource.rb
265
275
  - lib/droplet_kit/resources/droplet_resource.rb
266
276
  - lib/droplet_kit/resources/droplet_upgrade_resource.rb
277
+ - lib/droplet_kit/resources/firewall_resource.rb
267
278
  - lib/droplet_kit/resources/floating_ip_action_resource.rb
268
279
  - lib/droplet_kit/resources/floating_ip_resource.rb
269
280
  - lib/droplet_kit/resources/image_action_resource.rb
@@ -318,6 +329,8 @@ files:
318
329
  - spec/fixtures/droplets/list_backups.json
319
330
  - spec/fixtures/droplets/list_kernels.json
320
331
  - spec/fixtures/droplets/list_snapshots.json
332
+ - spec/fixtures/firewalls/all.json
333
+ - spec/fixtures/firewalls/find.json
321
334
  - spec/fixtures/floating_ip_actions/all.json
322
335
  - spec/fixtures/floating_ip_actions/assign.json
323
336
  - spec/fixtures/floating_ip_actions/find.json
@@ -371,6 +384,7 @@ files:
371
384
  - spec/lib/droplet_kit/resources/droplet_action_resource_spec.rb
372
385
  - spec/lib/droplet_kit/resources/droplet_resource_spec.rb
373
386
  - spec/lib/droplet_kit/resources/droplet_upgrade_resource_spec.rb
387
+ - spec/lib/droplet_kit/resources/firewall_resource_spec.rb
374
388
  - spec/lib/droplet_kit/resources/floating_ip_action_resource_spec.rb
375
389
  - spec/lib/droplet_kit/resources/floating_ip_resource_spec.rb
376
390
  - spec/lib/droplet_kit/resources/image_action_resource_spec.rb
@@ -389,7 +403,7 @@ files:
389
403
  - spec/support/resource_context.rb
390
404
  - spec/support/shared_examples/common_errors.rb
391
405
  - spec/support/shared_examples/paginated_endpoint.rb
392
- - spec/support/shared_examples/unsuccessful_create.rb
406
+ - spec/support/shared_examples/unprocessable_entity.rb
393
407
  homepage: https://github.com/digitalocean/droplet_kit
394
408
  licenses:
395
409
  - MIT
@@ -410,7 +424,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
410
424
  version: '0'
411
425
  requirements: []
412
426
  rubyforge_project:
413
- rubygems_version: 2.5.1
427
+ rubygems_version: 2.6.8
414
428
  signing_key:
415
429
  specification_version: 4
416
430
  summary: Droplet Kit is the official Ruby library for DigitalOcean's API
@@ -455,6 +469,8 @@ test_files:
455
469
  - spec/fixtures/droplets/list_backups.json
456
470
  - spec/fixtures/droplets/list_kernels.json
457
471
  - spec/fixtures/droplets/list_snapshots.json
472
+ - spec/fixtures/firewalls/all.json
473
+ - spec/fixtures/firewalls/find.json
458
474
  - spec/fixtures/floating_ip_actions/all.json
459
475
  - spec/fixtures/floating_ip_actions/assign.json
460
476
  - spec/fixtures/floating_ip_actions/find.json
@@ -508,6 +524,7 @@ test_files:
508
524
  - spec/lib/droplet_kit/resources/droplet_action_resource_spec.rb
509
525
  - spec/lib/droplet_kit/resources/droplet_resource_spec.rb
510
526
  - spec/lib/droplet_kit/resources/droplet_upgrade_resource_spec.rb
527
+ - spec/lib/droplet_kit/resources/firewall_resource_spec.rb
511
528
  - spec/lib/droplet_kit/resources/floating_ip_action_resource_spec.rb
512
529
  - spec/lib/droplet_kit/resources/floating_ip_resource_spec.rb
513
530
  - spec/lib/droplet_kit/resources/image_action_resource_spec.rb
@@ -526,4 +543,4 @@ test_files:
526
543
  - spec/support/resource_context.rb
527
544
  - spec/support/shared_examples/common_errors.rb
528
545
  - spec/support/shared_examples/paginated_endpoint.rb
529
- - spec/support/shared_examples/unsuccessful_create.rb
546
+ - spec/support/shared_examples/unprocessable_entity.rb
@@ -1,8 +0,0 @@
1
- shared_examples_for 'an action that handles invalid parameters' do
2
- it 'raises a FailedCreate exception with the message attached' do
3
- response_body = { id: :unprocessable_entity, message: 'Something is not right' }
4
- stub_do_api(path, :post).to_return(body: response_body.to_json, status: 422)
5
-
6
- expect { resource.send(action, arguments) }.to raise_exception(DropletKit::FailedCreate).with_message(response_body[:message])
7
- end
8
- end