hcloud 0.1.2 → 1.0.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 (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