hcloud 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +24 -9
  4. data/.rubocop_todo.yml +18 -121
  5. data/.travis.yml +3 -3
  6. data/CHANGELOG.md +13 -0
  7. data/Gemfile +3 -0
  8. data/Gemfile.lock +143 -0
  9. data/README.md +34 -1
  10. data/Rakefile +2 -0
  11. data/bin/console +1 -0
  12. data/hcloud.gemspec +5 -3
  13. data/lib/hcloud.rb +31 -5
  14. data/lib/hcloud/abstract_resource.rb +162 -55
  15. data/lib/hcloud/action.rb +8 -10
  16. data/lib/hcloud/action_resource.rb +3 -29
  17. data/lib/hcloud/client.rb +66 -28
  18. data/lib/hcloud/datacenter.rb +7 -7
  19. data/lib/hcloud/datacenter_resource.rb +6 -31
  20. data/lib/hcloud/entry_loader.rb +181 -20
  21. data/lib/hcloud/errors.rb +2 -0
  22. data/lib/hcloud/floating_ip.rb +18 -29
  23. data/lib/hcloud/floating_ip_resource.rb +15 -30
  24. data/lib/hcloud/image.rb +12 -32
  25. data/lib/hcloud/image_resource.rb +7 -38
  26. data/lib/hcloud/iso.rb +4 -1
  27. data/lib/hcloud/iso_resource.rb +7 -28
  28. data/lib/hcloud/location.rb +3 -9
  29. data/lib/hcloud/location_resource.rb +6 -27
  30. data/lib/hcloud/network.rb +33 -0
  31. data/lib/hcloud/network_resource.rb +25 -0
  32. data/lib/hcloud/pagination.rb +2 -9
  33. data/lib/hcloud/server.rb +37 -70
  34. data/lib/hcloud/server_resource.rb +16 -36
  35. data/lib/hcloud/server_type.rb +3 -10
  36. data/lib/hcloud/server_type_resource.rb +6 -28
  37. data/lib/hcloud/ssh_key.rb +6 -17
  38. data/lib/hcloud/ssh_key_resource.rb +13 -32
  39. data/lib/hcloud/typhoeus_ext.rb +112 -0
  40. data/lib/hcloud/version.rb +3 -1
  41. data/lib/hcloud/volume.rb +32 -0
  42. data/lib/hcloud/volume_resource.rb +29 -0
  43. metadata +31 -13
  44. data/lib/hcloud/multi_reply.rb +0 -21
@@ -1,46 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class ImageResource < AbstractResource
3
- def all
4
- mj('images') do |j|
5
- j.flat_map { |x| x['images'].map { |x| Image.new(x, self, client) } }
6
- end
7
- end
5
+ filter_attributes :type, :bound_to, :name
6
+
7
+ bind_to Image
8
8
 
9
9
  def [](arg)
10
10
  case arg
11
- when Integer
12
- begin
13
- find(arg)
14
- rescue Error::NotFound
15
- end
16
- when String
17
- find_by(name: arg)
18
- end
19
- end
20
-
21
- def find(id)
22
- Image.new(
23
- Oj.load(request("images/#{id.to_i}").run.body)['image'],
24
- self,
25
- client
26
- )
27
- end
28
-
29
- def where(sort: nil, type: nil, bound_to: nil, name: nil)
30
- query = {}
31
- method(:where).parameters.inject(query) do |r, x|
32
- (var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
33
- end
34
- mj('images', q: query) do |j|
35
- j.flat_map { |x| x['images'].map { |x| Image.new(x, self, client) } }
36
- end
37
- end
38
-
39
- def find_by(name:)
40
- j = Oj.load(request('images', q: { name: name }).run.body)['images']
41
- return if j.none?
42
- j.each do |x|
43
- return Image.new(x, self, client)
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
44
13
  end
45
14
  end
46
15
  end
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class Iso
3
5
  Attributes = {
4
6
  id: nil,
5
7
  name: nil,
6
8
  description: nil,
7
- type: nil
9
+ type: nil,
10
+ deprecated: :time
8
11
  }.freeze
9
12
 
10
13
  include EntryLoader
@@ -1,36 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class IsoResource < AbstractResource
3
- def all
4
- mj('isos') do |j|
5
- j.flat_map { |x| x['isos'].map { |x| Iso.new(x, self, client) } }
6
- end
7
- end
5
+ filter_attributes :name
6
+
7
+ bind_to Iso
8
8
 
9
9
  def [](arg)
10
10
  case arg
11
- when Integer
12
- begin
13
- find(arg)
14
- rescue Error::NotFound
15
- end
16
- when String
17
- find_by(name: arg)
18
- end
19
- end
20
-
21
- def find(id)
22
- Iso.new(
23
- Oj.load(request("isos/#{id.to_i}").run.body)['iso'],
24
- self,
25
- client
26
- )
27
- end
28
-
29
- def find_by(name:)
30
- j = Oj.load(request('isos', q: { name: name }).run.body)['isos']
31
- return if j.none?
32
- j.each do |x|
33
- return Iso.new(x, self, client)
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
34
13
  end
35
14
  end
36
15
  end
@@ -1,14 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class Location
3
- Attributes = {
4
- id: nil,
5
- name: nil,
6
- description: nil,
7
- country: nil,
8
- city: nil,
9
- longitude: nil,
10
- latitude: nil
11
- }.freeze
5
+ require 'hcloud/location_resource'
12
6
 
13
7
  include EntryLoader
14
8
  end
@@ -1,36 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class LocationResource < AbstractResource
3
- def all
4
- mj('locations') do |j|
5
- j.flat_map { |x| x['locations'].map { |x| Location.new(x, self, client) } }
6
- end
7
- end
5
+ filter_attributes :name
8
6
 
9
- def find(id)
10
- Location.new(
11
- Oj.load(request("locations/#{id}").run.body)['location'],
12
- self,
13
- client
14
- )
15
- end
16
-
17
- def find_by(name:)
18
- x = Oj.load(request('locations', q: { name: name }).run.body)['locations']
19
- return nil if x.none?
20
- x.each do |s|
21
- return Location.new(s, self, client)
22
- end
23
- end
7
+ bind_to Location
24
8
 
25
9
  def [](arg)
26
10
  case arg
27
- when Integer
28
- begin
29
- find(arg)
30
- rescue Error::NotFound
31
- end
32
- when String
33
- find_by(name: arg)
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
34
13
  end
35
14
  end
36
15
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class Network
5
+ include EntryLoader
6
+
7
+ schema(
8
+ created: :time
9
+ )
10
+
11
+ protectable :delete
12
+ updatable :name
13
+ destructible
14
+
15
+ has_actions
16
+
17
+ def add_subnet(type:, ip_range: nil, network_zone:)
18
+ prepare_request('actions/add_subnet', j: COLLECT_ARGS.call(__method__, binding))
19
+ end
20
+
21
+ def del_subnet(ip_range:)
22
+ prepare_request('actions/del_subnet', j: COLLECT_ARGS.call(__method__, binding))
23
+ end
24
+
25
+ def add_route(destination:, gateway:)
26
+ prepare_request('actions/add_route', j: COLLECT_ARGS.call(__method__, binding))
27
+ end
28
+
29
+ def del_route(destination:, gateway:)
30
+ prepare_request('actions/del_route', j: COLLECT_ARGS.call(__method__, binding))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class NetworkResource < AbstractResource
5
+ filter_attributes :name
6
+
7
+ bind_to Network
8
+
9
+ def [](arg)
10
+ case arg
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
13
+ end
14
+ end
15
+
16
+ def create(name:, ip_range:, subnets: nil, routes: nil)
17
+ prepare_request(
18
+ 'networks', j: COLLECT_ARGS.call(__method__, binding),
19
+ expected_code: 201
20
+ ) do |response|
21
+ Network.new(client, response.parsed_json[:network])
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,14 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class Pagination
3
- Attributes = {
4
- page: nil,
5
- per_page: nil,
6
- previous_page: nil,
7
- next_page: nil,
8
- last_page: nil,
9
- total_entries: nil
10
- }.freeze
11
-
12
5
  include EntryLoader
13
6
  end
14
7
  end
@@ -1,109 +1,76 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class Server
3
- Attributes = {
4
- id: nil,
5
- name: nil,
6
- status: nil,
5
+ require 'hcloud/server_resource'
6
+
7
+ include EntryLoader
8
+
9
+ schema(
7
10
  created: :time,
8
- public_net: nil,
9
11
  server_type: ServerType,
10
12
  datacenter: Datacenter,
11
- image: Image,
12
- iso: nil,
13
- rescue_enabled: nil,
14
- locked: nil,
15
- backup_window: nil,
16
- outgoing_traffic: nil,
17
- ingoing_traffic: nil,
18
- included_traffic: nil
19
- }.freeze
20
-
21
- include EntryLoader
13
+ image: Image
14
+ )
22
15
 
23
- def update(name:)
24
- Server.new(
25
- Oj.load(request(base_path, j: { name: name }, method: :put).run.body)['server'],
26
- parent,
27
- client
28
- )
29
- end
16
+ protectable :delete, :rebuild
17
+ updatable :name
18
+ destructible
30
19
 
31
- def destroy
32
- action(request(base_path, method: :delete))[0]
33
- end
20
+ has_actions
34
21
 
35
22
  def enable_rescue(type: 'linux64', ssh_keys: [])
36
- query = {}
37
- method(:enable_rescue).parameters.inject(query) do |r, x|
38
- (var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
39
- end
40
- a, j = action(request(base_path('actions/enable_rescue'), j: query))
41
- [a, j['root_password']]
23
+ query = COLLECT_ARGS.call(__method__, binding)
24
+ prepare_request('actions/enable_rescue', j: query) { |j| j[:root_password] }
42
25
  end
43
26
 
44
27
  def reset_password
45
- a, j = action(request(base_path('actions/reset_password'), method: :post))
46
- [a, j['root_password']]
28
+ prepare_request('actions/reset_password', method: :post) { |j| j[:root_password] }
47
29
  end
48
30
 
49
31
  def create_image(description: nil, type: nil)
50
- query = {}
51
- method(:create_image).parameters.inject(query) do |r, x|
52
- (var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
53
- end
54
- a, j = action(request(base_path('actions/create_image'), j: query))
55
- [a, Image.new(j['image'], parent, client)]
32
+ query = COLLECT_ARGS.call(__method__, binding)
33
+ prepare_request('actions/create_image', j: query) { |j| Image.new(client, j[:image]) }
56
34
  end
57
35
 
58
36
  def rebuild(image:)
59
- a, j = action(request(base_path('actions/rebuild'), j: { image: image }))
60
- [a, j['root_password']]
37
+ prepare_request('actions/rebuild', j: { image: image }) { |j| j[:root_password] }
61
38
  end
62
39
 
63
40
  def change_type(server_type:, upgrade_disk: nil)
64
- query = {}
65
- method(:change_type).parameters.inject(query) do |r, x|
66
- (var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
67
- end
68
- action(request(base_path('actions/change_type'), j: query))[0]
41
+ prepare_request('actions/change_type', j: COLLECT_ARGS.call(__method__, binding))
69
42
  end
70
43
 
71
- def enable_backup(backup_window:)
72
- action(request(base_path('actions/enable_backup'),
73
- j: { backup_window: backup_window }))[0]
44
+ # Specifying a backup window is not supported anymore. We keep this method
45
+ # to ensure backwards compatibility, but ignore the argument if provided.
46
+ def enable_backup(**_kwargs)
47
+ prepare_request('actions/enable_backup', method: :post)
74
48
  end
75
49
 
76
50
  def attach_iso(iso:)
77
- action(request(base_path('actions/attach_iso'),
78
- j: { iso: iso }))[0]
51
+ prepare_request('actions/attach_iso', j: { iso: iso })
52
+ end
53
+
54
+ def attach_to_network(network:, ip: nil, alias_ips: nil)
55
+ prepare_request('actions/attach_to_network', j: COLLECT_ARGS.call(__method__, binding))
56
+ end
57
+
58
+ def detach_from_network(network:)
59
+ prepare_request('actions/detach_from_network', j: { network: network })
79
60
  end
80
61
 
81
62
  %w[
82
63
  poweron poweroff shutdown reboot reset
83
64
  disable_rescue disable_backup detach_iso
65
+ request_console
84
66
  ].each do |action|
85
67
  define_method(action) do
86
- action(request(base_path("actions/#{action}"), method: :post))[0]
68
+ prepare_request("actions/#{action}", method: :post)
87
69
  end
88
70
  end
89
71
 
90
- def actions
91
- ActionResource.new(client: client, parent: self, base_path: base_path)
92
- end
93
-
94
- private
95
-
96
- def action(request)
97
- j = Oj.load(request.run.body)
98
- [
99
- Action.new(j['action'], parent, client),
100
- j
101
- ]
102
- end
103
-
104
- def base_path(ext = nil)
105
- return ["servers/#{id}", ext].compact.join('/') unless id.nil?
106
- raise ResourcePathError, 'Unable to build resource path. Id is nil.'
72
+ def request_console
73
+ prepare_request('actions/request_console', method: :post) { |j| [j[:wss_url], j[:password]] }
107
74
  end
108
75
  end
109
76
  end
@@ -1,5 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class ServerResource < AbstractResource
5
+ filter_attributes :status, :name
6
+
7
+ bind_to Server
8
+
3
9
  def create(name:,
4
10
  server_type:,
5
11
  datacenter: nil,
@@ -7,48 +13,22 @@ module Hcloud
7
13
  start_after_create: nil,
8
14
  image:,
9
15
  ssh_keys: [],
16
+ networks: [],
10
17
  user_data: nil)
11
- query = {}
12
- method(:create).parameters.inject(query) do |r, x|
13
- (var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
14
- end
15
- j = Oj.load(request('servers', j: query, code: 200).run.body)
16
- [
17
- Action.new(j['action'], self, client),
18
- Server.new(j['server'], self, client),
19
- j['root_password']
20
- ]
21
- end
22
-
23
- def all
24
- mj('servers') do |j|
25
- j.flat_map { |x| x['servers'].map { |x| Server.new(x, self, client) } }
18
+ prepare_request('servers', j: COLLECT_ARGS.call(__method__, binding),
19
+ expected_code: 201) do |response|
20
+ [
21
+ Action.new(client, response.parsed_json[:action]),
22
+ Server.new(client, response.parsed_json[:server]),
23
+ response.parsed_json[:root_password]
24
+ ]
26
25
  end
27
26
  end
28
27
 
29
- def find(id)
30
- Server.new(
31
- Oj.load(request("servers/#{id.to_i}").run.body)['server'], self, client
32
- )
33
- end
34
-
35
28
  def [](arg)
36
29
  case arg
37
- when Integer
38
- begin
39
- find(arg)
40
- rescue Error::NotFound
41
- end
42
- when String
43
- find_by(name: arg)
44
- end
45
- end
46
-
47
- def find_by(name:)
48
- x = Oj.load(request('servers', q: { name: name }).run.body)['servers']
49
- return nil if x.none?
50
- x.each do |s|
51
- return Server.new(s, self, client)
30
+ when Integer then find_by(id: arg)
31
+ when String then find_by(name: arg)
52
32
  end
53
33
  end
54
34
  end