droplet_kit 2.0.1 → 2.1.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +7 -0
  4. data/README.md +46 -12
  5. data/droplet_kit.gemspec +2 -1
  6. data/lib/droplet_kit.rb +12 -0
  7. data/lib/droplet_kit/client.rb +2 -0
  8. data/lib/droplet_kit/mappings/certificate_mapping.rb +25 -0
  9. data/lib/droplet_kit/mappings/droplet_mapping.rb +1 -0
  10. data/lib/droplet_kit/mappings/forwarding_rule_mapping.rb +19 -0
  11. data/lib/droplet_kit/mappings/health_check_mapping.rb +19 -0
  12. data/lib/droplet_kit/mappings/image_mapping.rb +5 -1
  13. data/lib/droplet_kit/mappings/load_balancer_mapping.rb +33 -0
  14. data/lib/droplet_kit/mappings/sticky_session_mapping.rb +15 -0
  15. data/lib/droplet_kit/models/certificate.rb +12 -0
  16. data/lib/droplet_kit/models/droplet.rb +1 -0
  17. data/lib/droplet_kit/models/forwarding_rule.rb +10 -0
  18. data/lib/droplet_kit/models/health_check.rb +11 -0
  19. data/lib/droplet_kit/models/image.rb +42 -0
  20. data/lib/droplet_kit/models/load_balancer.rb +17 -0
  21. data/lib/droplet_kit/models/sticky_session.rb +7 -0
  22. data/lib/droplet_kit/resources/certificate_resource.rb +30 -0
  23. data/lib/droplet_kit/resources/droplet_action_resource.rb +2 -2
  24. data/lib/droplet_kit/resources/load_balancer_resource.rb +56 -0
  25. data/lib/droplet_kit/version.rb +1 -1
  26. data/spec/fixtures/certificates/all.json +16 -0
  27. data/spec/fixtures/certificates/find.json +9 -0
  28. data/spec/fixtures/images/find.json +4 -2
  29. data/spec/fixtures/load_balancers/all.json +129 -0
  30. data/spec/fixtures/load_balancers/find.json +59 -0
  31. data/spec/lib/droplet_kit/resources/certificate_resource_spec.rb +90 -0
  32. data/spec/lib/droplet_kit/resources/droplet_action_resource_spec.rb +4 -4
  33. data/spec/lib/droplet_kit/resources/droplet_resource_spec.rb +2 -0
  34. data/spec/lib/droplet_kit/resources/image_resource_spec.rb +5 -1
  35. data/spec/lib/droplet_kit/resources/load_balancer_resource_spec.rb +213 -0
  36. data/spec/spec_helper.rb +1 -3
  37. metadata +41 -3
@@ -0,0 +1,7 @@
1
+ module DropletKit
2
+ class StickySession < BaseModel
3
+ attribute :type
4
+ attribute :cookie_name
5
+ attribute :cookie_ttl_seconds
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ module DropletKit
2
+ class CertificateResource < ResourceKit::Resource
3
+ include ErrorHandlingResourcable
4
+
5
+ resources do
6
+ action :find, 'GET /v2/certificates/:id' do
7
+ handler(200) { |response| CertificateMapping.extract_single(response.body, :read) }
8
+ end
9
+
10
+ action :all, 'GET /v2/certificates' do
11
+ query_keys :per_page, :page
12
+ handler(200) { |response| CertificateMapping.extract_collection(response.body, :read) }
13
+ end
14
+
15
+ action :create, 'POST /v2/certificates' do
16
+ body { |certificate| CertificateMapping.representation_for(:create, certificate) }
17
+ handler(201) { |response| CertificateMapping.extract_single(response.body, :read) }
18
+ handler(422) { |response| ErrorMapping.fail_with(FailedCreate, response.body) }
19
+ end
20
+
21
+ action :delete, 'DELETE /v2/certificates/:id' do
22
+ handler(204) { |_| true }
23
+ end
24
+ end
25
+
26
+ def all(*args)
27
+ PaginatedResource.new(action(:all), self, *args)
28
+ end
29
+ end
30
+ end
@@ -20,7 +20,7 @@ module DropletKit
20
20
  end
21
21
 
22
22
  action :action_for_tag, 'POST /v2/droplets/actions' do
23
- query_keys :tag
23
+ query_keys :tag_name
24
24
  body { |hash| hash.to_json }
25
25
  handler(201, 200) { |response| ActionMapping.extract_single(response.body, :read) }
26
26
  end
@@ -34,7 +34,7 @@ module DropletKit
34
34
 
35
35
  TAG_ACTIONS.each do |action_name|
36
36
  action "#{action_name}_for_tag".to_sym, 'POST /v2/droplets/actions' do
37
- query_keys :tag
37
+ query_keys :tag_name
38
38
  body { |_| { type: action_name }.to_json }
39
39
  handler(201, 200) { |response| ActionMapping.extract_collection(response.body, :read) }
40
40
  end
@@ -0,0 +1,56 @@
1
+ module DropletKit
2
+ class LoadBalancerResource < ResourceKit::Resource
3
+ include ErrorHandlingResourcable
4
+
5
+ resources do
6
+ action :find, 'GET /v2/load_balancers/:id' do
7
+ handler(200) { |response| LoadBalancerMapping.extract_single(response.body, :read) }
8
+ end
9
+
10
+ action :all, 'GET /v2/load_balancers' do
11
+ query_keys :per_page, :page
12
+ handler(200) { |response| LoadBalancerMapping.extract_collection(response.body, :read) }
13
+ end
14
+
15
+ action :create, 'POST /v2/load_balancers' do
16
+ body { |load_balancer| LoadBalancerMapping.representation_for(:create, load_balancer) }
17
+ handler(202) { |response| LoadBalancerMapping.extract_single(response.body, :read) }
18
+ handler(422) { |response| ErrorMapping.fail_with(FailedCreate, response.body) }
19
+ end
20
+
21
+ action :update, 'PUT /v2/load_balancers/:id' do
22
+ body {|load_balancer| LoadBalancerMapping.representation_for(:update, load_balancer) }
23
+ handler(200) { |response| LoadBalancerMapping.extract_single(response.body, :read) }
24
+ handler(422) { |response| ErrorMapping.fail_with(FailedUpdate, response.body) }
25
+ end
26
+
27
+ action :delete, 'DELETE /v2/load_balancers/:id' do
28
+ handler(204) { |_| true }
29
+ end
30
+
31
+ action :add_droplets, 'POST /v2/load_balancers/:id/droplets' do
32
+ body { |droplet_ids| { droplet_ids: droplet_ids }.to_json }
33
+ handler(204) { |_| true }
34
+ end
35
+
36
+ action :remove_droplets, 'DELETE /v2/load_balancers/:id/droplets' do
37
+ body { |droplet_ids| { droplet_ids: droplet_ids }.to_json }
38
+ handler(204) { |_| true }
39
+ end
40
+
41
+ action :add_forwarding_rules, 'POST /v2/load_balancers/:id/forwarding_rules' do
42
+ body { |forwarding_rules| ForwardingRuleMapping.represent_collection_for(:create, forwarding_rules) }
43
+ handler(204) { |_| true }
44
+ end
45
+
46
+ action :remove_forwarding_rules, 'DELETE /v2/load_balancers/:id/forwarding_rules' do
47
+ body { |forwarding_rules| ForwardingRuleMapping.represent_collection_for(:update, forwarding_rules) }
48
+ handler(204) { |_| true }
49
+ end
50
+ end
51
+
52
+ def all(*args)
53
+ PaginatedResource.new(action(:all), self, *args)
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,3 @@
1
1
  module DropletKit
2
- VERSION = "2.0.1"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -0,0 +1,16 @@
1
+ {
2
+ "certificates": [
3
+ {
4
+ "id": "892071a0-bb95-49bc-8021-3afd67a210bf",
5
+ "name": "web-cert-01",
6
+ "not_after": "2017-02-22T00:23:00Z",
7
+ "sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
8
+ "created_at": "2017-02-08T16:02:37Z"
9
+ }
10
+ ],
11
+ "links": {
12
+ },
13
+ "meta": {
14
+ "total": 1
15
+ }
16
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "certificate": {
3
+ "id": "892071a0-bb95-49bc-8021-3afd67a210bf",
4
+ "name": "web-cert-01",
5
+ "not_after": "2017-02-22T00:23:00Z",
6
+ "sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
7
+ "created_at": "2017-02-08T16:02:37Z"
8
+ }
9
+ }
@@ -9,6 +9,8 @@
9
9
  "region--1"
10
10
  ],
11
11
  "created_at": "2014-07-29T14:35:41Z",
12
- "type": "snapshot"
12
+ "min_disk_size": 20,
13
+ "type": "snapshot",
14
+ "size_gigabytes":0.43
13
15
  }
14
- }
16
+ }
@@ -0,0 +1,129 @@
1
+ {
2
+ "load_balancers": [
3
+ {
4
+ "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6",
5
+ "name": "example-lb-01",
6
+ "ip": "104.131.186.241",
7
+ "algorithm": "round_robin",
8
+ "status": "active",
9
+ "created_at": "2017-02-01T22:22:58Z",
10
+ "forwarding_rules": [
11
+ {
12
+ "entry_protocol": "http",
13
+ "entry_port": 80,
14
+ "target_protocol": "http",
15
+ "target_port": 80,
16
+ "certificate_id": "",
17
+ "tls_passthrough": false
18
+ },
19
+ {
20
+ "entry_protocol": "https",
21
+ "entry_port": 444,
22
+ "target_protocol": "https",
23
+ "target_port": 443,
24
+ "certificate_id": "my-cert",
25
+ "tls_passthrough": true
26
+ }
27
+ ],
28
+ "health_check": {
29
+ "protocol": "http",
30
+ "port": 80,
31
+ "path": "/",
32
+ "check_interval_seconds": 10,
33
+ "response_timeout_seconds": 5,
34
+ "healthy_threshold": 5,
35
+ "unhealthy_threshold": 3
36
+ },
37
+ "sticky_sessions": {
38
+ "type": "cookies",
39
+ "cookie_name": "DO-LB",
40
+ "cookie_ttl_seconds": 5
41
+ },
42
+ "region": {
43
+ "name": "New York 3",
44
+ "slug": "nyc3",
45
+ "sizes": [
46
+ "512mb"
47
+ ],
48
+ "features": [
49
+ "private_networking"
50
+ ],
51
+ "available": true
52
+ },
53
+ "tag": "",
54
+ "droplet_ids": [
55
+ 3164444,
56
+ 3164445
57
+ ],
58
+ "redirect_http_to_https": false
59
+ },
60
+ {
61
+ "id": "3de7ac8b-495b-4884-9a69-1050c6793cd6",
62
+ "name": "example-lb-02",
63
+ "ip": "104.131.186.242",
64
+ "algorithm": "round_robin",
65
+ "status": "active",
66
+ "created_at": "2017-02-01T22:22:58Z",
67
+ "forwarding_rules": [
68
+ {
69
+ "entry_protocol": "http",
70
+ "entry_port": 80,
71
+ "target_protocol": "http",
72
+ "target_port": 80,
73
+ "certificate_id": "",
74
+ "tls_passthrough": false
75
+ }
76
+ ],
77
+ "health_check": {
78
+ "protocol": "http",
79
+ "port": 80,
80
+ "path": "/",
81
+ "check_interval_seconds": 10,
82
+ "response_timeout_seconds": 5,
83
+ "healthy_threshold": 5,
84
+ "unhealthy_threshold": 3
85
+ },
86
+ "sticky_sessions": {
87
+ "type": "cookies",
88
+ "cookie_name": "DO-LB",
89
+ "cookie_ttl_seconds": 5
90
+ },
91
+ "region": {
92
+ "name": "New York 3",
93
+ "slug": "nyc3",
94
+ "sizes": [
95
+ "512mb",
96
+ "1gb",
97
+ "2gb",
98
+ "4gb",
99
+ "8gb",
100
+ "16gb",
101
+ "m-16gb",
102
+ "32gb",
103
+ "m-32gb",
104
+ "48gb",
105
+ "m-64gb",
106
+ "64gb",
107
+ "m-128gb",
108
+ "m-224gb"
109
+ ],
110
+ "features": [
111
+ "private_networking",
112
+ "backups",
113
+ "ipv6",
114
+ "metadata",
115
+ "install_agent"
116
+ ],
117
+ "available": true
118
+ },
119
+ "tag": "",
120
+ "droplet_ids": [],
121
+ "redirect_http_to_https": true
122
+ }
123
+ ],
124
+ "links": {
125
+ },
126
+ "meta": {
127
+ "total": 1
128
+ }
129
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "load_balancer": {
3
+ "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6",
4
+ "name": "example-lb-01",
5
+ "ip": "104.131.186.241",
6
+ "algorithm": "round_robin",
7
+ "status": "active",
8
+ "created_at": "2017-02-01T22:22:58Z",
9
+ "forwarding_rules": [
10
+ {
11
+ "entry_protocol": "http",
12
+ "entry_port": 80,
13
+ "target_protocol": "http",
14
+ "target_port": 80,
15
+ "certificate_id": "",
16
+ "tls_passthrough": false
17
+ },
18
+ {
19
+ "entry_protocol": "https",
20
+ "entry_port": 444,
21
+ "target_protocol": "https",
22
+ "target_port": 443,
23
+ "certificate_id": "my-cert",
24
+ "tls_passthrough": true
25
+ }
26
+ ],
27
+ "health_check": {
28
+ "protocol": "http",
29
+ "port": 80,
30
+ "path": "/",
31
+ "check_interval_seconds": 10,
32
+ "response_timeout_seconds": 5,
33
+ "healthy_threshold": 5,
34
+ "unhealthy_threshold": 3
35
+ },
36
+ "sticky_sessions": {
37
+ "type": "cookies",
38
+ "cookie_name": "DO-LB",
39
+ "cookie_ttl_seconds": 5
40
+ },
41
+ "region": {
42
+ "name": "New York 3",
43
+ "slug": "nyc3",
44
+ "sizes": [
45
+ "512mb"
46
+ ],
47
+ "features": [
48
+ "private_networking"
49
+ ],
50
+ "available": true
51
+ },
52
+ "tag": "",
53
+ "droplet_ids": [
54
+ 3164444,
55
+ 3164445
56
+ ],
57
+ "redirect_http_to_https": false
58
+ }
59
+ }
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe DropletKit::CertificateResource do
4
+ include_context 'resources'
5
+
6
+ let(:certificate_fixture_path) { 'certificates/find' }
7
+ let(:base_path) { '/v2/certificates'}
8
+ let(:certificate_id) { '892071a0-bb95-49bc-8021-3afd67a210bf' }
9
+ subject(:resource) { described_class.new(connection: connection) }
10
+
11
+ RSpec::Matchers.define :match_certificate_fixture do
12
+ match do |certificate|
13
+ expect(certificate.id).to eq('892071a0-bb95-49bc-8021-3afd67a210bf')
14
+ expect(certificate.name).to eq('web-cert-01')
15
+ expect(certificate.not_after).to eq('2017-02-22T00:23:00Z')
16
+ expect(certificate.sha1_fingerprint).to eq('dfcc9f57d86bf58e321c2c6c31c7a971be244ac7')
17
+ expect(certificate.created_at).to eq('2017-02-08T16:02:37Z')
18
+ end
19
+ end
20
+
21
+ describe '#find' do
22
+ let(:certificate) do
23
+ DropletKit::Certificate.new(
24
+ id: '892071a0-bb95-49bc-8021-3afd67a210bf',
25
+ name: 'web-cert-01',
26
+ not_after: '2017-02-22T00:23:00Z',
27
+ sha1_fingerprint: 'dfcc9f57d86bf58e321c2c6c31c7a971be244ac7',
28
+ created_at: '2017-02-08T16:02:37Z'
29
+ )
30
+ end
31
+
32
+ it 'returns certificate' do
33
+ stub_do_api(File.join(base_path, certificate_id), :get).to_return(body: api_fixture(certificate_fixture_path))
34
+ certificate = resource.find(id: certificate_id)
35
+
36
+ expect(certificate).to match_certificate_fixture
37
+ end
38
+ end
39
+
40
+ describe '#all' do
41
+ let(:certificates_fixture_path) { 'certificates/all' }
42
+
43
+ it 'returns all of the certificates' do
44
+ stub_do_api(base_path, :get).to_return(body: api_fixture(certificates_fixture_path))
45
+ certificates = resource.all
46
+
47
+ expect(certificates).to all(be_kind_of(DropletKit::Certificate))
48
+ expect(certificates.first).to match_certificate_fixture
49
+ end
50
+
51
+ it_behaves_like 'a paginated index' do
52
+ let(:fixture_path) { certificates_fixture_path }
53
+ let(:api_path) { base_path }
54
+ end
55
+ end
56
+
57
+ describe '#create' do
58
+ let(:path) { base_path }
59
+
60
+ let(:certificate) do
61
+ DropletKit::Certificate.new(
62
+ name: 'web-cert-01',
63
+ private_key: '-----BEGIN PRIVATE KEY-----',
64
+ leaf_certificate: '-----BEGIN CERTIFICATE-----',
65
+ certificate_chain: '-----BEGIN CERTIFICATE-----'
66
+ )
67
+ end
68
+
69
+ it 'returns created certificate' do
70
+ json_body = DropletKit::CertificateMapping.representation_for(:create, certificate)
71
+ stub_do_api(path, :post).with(body: json_body).to_return(body: api_fixture(certificate_fixture_path), status: 201)
72
+
73
+ expect(resource.create(certificate)).to match_certificate_fixture
74
+ end
75
+
76
+ it_behaves_like 'an action that handles invalid parameters' do
77
+ let(:action) { 'create' }
78
+ let(:arguments) { DropletKit::Certificate.new }
79
+ end
80
+ end
81
+
82
+ describe '#delete' do
83
+ it 'sends a delete request for the certificate' do
84
+ request = stub_do_api(File.join(base_path, certificate_id), :delete)
85
+ resource.delete(id: certificate_id)
86
+
87
+ expect(request).to have_been_made
88
+ end
89
+ end
90
+ end
@@ -30,10 +30,10 @@ RSpec.describe DropletKit::DropletActionResource do
30
30
 
31
31
  it 'performs the action' do
32
32
  request = stub_do_api(path, :post).with(
33
- body: { tag: 'test-tag', type: action, param_1: 1, param_2: 2 }.to_json
33
+ body: { tag_name: 'test-tag', type: action, param_1: 1, param_2: 2 }.to_json
34
34
  ).to_return(body: fixture, status: 201)
35
35
 
36
- resource.action_for_tag(tag: 'test-tag', type: action, param_1: 1, param_2: 2)
36
+ resource.action_for_tag(tag_name: 'test-tag', type: action, param_1: 1, param_2: 2)
37
37
  expect(request).to have_been_made
38
38
  end
39
39
  end
@@ -64,7 +64,7 @@ RSpec.describe DropletKit::DropletActionResource do
64
64
  described_class::TAG_ACTIONS.each do |action_name|
65
65
  describe "Batch Action #{action_name}" do
66
66
  let(:action) { "#{action_name}_for_tag" }
67
- let(:path) { "/v2/droplets/actions?tag=testing-1" }
67
+ let(:path) { "/v2/droplets/actions?tag_name=testing-1" }
68
68
  let(:fixture) do
69
69
  single_action = DropletKit::ActionMapping.extract_single(api_fixture("droplet_actions/#{action_name}"), :read)
70
70
 
@@ -76,7 +76,7 @@ RSpec.describe DropletKit::DropletActionResource do
76
76
  body: { type: action_name }.to_json
77
77
  ).to_return(body: fixture, status: 201)
78
78
 
79
- returned_actions = resource.send(action, tag: 'testing-1')
79
+ returned_actions = resource.send(action, tag_name: 'testing-1')
80
80
 
81
81
  expect(request).to have_been_made
82
82
  expect(returned_actions.first.type).to eq(action_name)