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,15 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class ServerType
3
- Attributes = {
4
- id: nil,
5
- name: nil,
6
- description: nil,
7
- cores: nil,
8
- memory: nil,
9
- disk: nil,
10
- prices: nil,
11
- storage_type: nil
12
- }.freeze
5
+ require 'hcloud/server_type_resource'
13
6
 
14
7
  include EntryLoader
15
8
  end
@@ -1,37 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class ServerTypeResource < AbstractResource
3
- include Enumerable
4
-
5
- def all
6
- j = Oj.load(request('server_types').run.body)
7
- j['server_types'].map { |x| ServerType.new(x, self, client) }
8
- end
5
+ filter_attributes :name
9
6
 
10
- def find(id)
11
- ServerType.new(
12
- Oj.load(request("server_types/#{id}").run.body)['server_type'],
13
- self,
14
- client
15
- )
16
- end
17
-
18
- def find_by(name:)
19
- x = Oj.load(request('server_types', q: { name: name }).run.body)['server_types']
20
- return nil if x.none?
21
- x.each do |s|
22
- return ServerType.new(s, self, client)
23
- end
24
- end
7
+ bind_to ServerType
25
8
 
26
9
  def [](arg)
27
10
  case arg
28
- when Integer
29
- begin
30
- find(arg)
31
- rescue Error::NotFound
32
- end
33
- when String
34
- find_by(name: arg)
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
35
13
  end
36
14
  end
37
15
  end
@@ -1,23 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class SSHKey
3
- Attributes = {
4
- id: nil,
5
- name: nil,
6
- fingerprint: nil,
7
- public_key: nil
8
- }.freeze
9
- include EntryLoader
5
+ require 'hcloud/ssh_key_resource'
10
6
 
11
- def update(name:)
12
- j = Oj.load(request("ssh_keys/#{id.to_i}",
13
- j: { name: name },
14
- method: :put).run.body)
15
- SSHKey.new(j['ssh_key'], self, client)
16
- end
7
+ include EntryLoader
17
8
 
18
- def destroy
19
- request("ssh_keys/#{id}", method: :delete).run.body
20
- true
21
- end
9
+ updatable :name
10
+ destructible
22
11
  end
23
12
  end
@@ -1,41 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
4
  class SSHKeyResource < AbstractResource
3
- def all
4
- mj('ssh_keys') do |j|
5
- j.flat_map { |x| x['ssh_keys'].map { |x| SSHKey.new(x, self, client) } }
6
- end
7
- end
5
+ filter_attributes :name
8
6
 
9
- def create(name:, public_key:)
10
- j = Oj.load(request('ssh_keys', j: { name: name, public_key: public_key }).run.body)
11
- SSHKey.new(j['ssh_key'], self, client)
12
- end
13
-
14
- def find(id)
15
- SSHKey.new(
16
- Oj.load(request("ssh_keys/#{id}").run.body)['ssh_key'],
17
- self,
18
- client
19
- )
20
- end
21
-
22
- def find_by(name:)
23
- x = Oj.load(request('ssh_keys', q: { name: name }).run.body)['ssh_keys']
24
- return nil if x.none?
25
- x.each do |s|
26
- return SSHKey.new(s, self, client)
7
+ def [](arg)
8
+ case arg
9
+ when Integer then find_by(id: arg)
10
+ when String then find_by(name: arg)
27
11
  end
28
12
  end
29
13
 
30
- def [](arg)
31
- case arg
32
- when Integer
33
- begin
34
- find(arg)
35
- rescue Error::NotFound
36
- end
37
- when String
38
- find_by(name: arg)
14
+ def create(name:, public_key:)
15
+ prepare_request(
16
+ 'ssh_keys', j: COLLECT_ARGS.call(__method__, binding),
17
+ expected_code: 201
18
+ ) do |response|
19
+ SSHKey.new(client, response.parsed_json[:ssh_key])
39
20
  end
40
21
  end
41
22
  end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/hash/indifferent_access'
4
+
5
+ module Hcloud
6
+ module TyphoeusExt
7
+ Context = Struct.new(:client)
8
+
9
+ ATTRIBUTES = %i[
10
+ block autoload_action resource_path
11
+ resource_class expected_code
12
+ ].freeze
13
+
14
+ attr_accessor(*ATTRIBUTES)
15
+
16
+ def self.collect_attributes(kwargs)
17
+ hash = {}
18
+ ATTRIBUTES.each do |key|
19
+ hash[key] = kwargs.delete(key) if kwargs.key?(key)
20
+ end
21
+ hash
22
+ end
23
+
24
+ def attributes=(kwargs)
25
+ kwargs.each do |key, value|
26
+ public_send("#{key}=", value)
27
+ end
28
+ end
29
+
30
+ def parsed_json
31
+ return {} if code == 204
32
+
33
+ @parsed_json ||= begin
34
+ Oj.load(body, symbol_keys: true).tap do |json|
35
+ next unless request.hydra
36
+
37
+ check_for_error(
38
+ e_code: json.to_h.dig(:error, :code),
39
+ e_message: json.to_h.dig(:error, :message)
40
+ )
41
+ end
42
+ end
43
+ rescue StandardError
44
+ raise Error::UnexpectedError, "unable to load body: #{body}"
45
+ end
46
+
47
+ def context
48
+ @context ||= Context.new
49
+ end
50
+
51
+ def check_for_error(e_code: nil, e_message: nil)
52
+ case code
53
+ when 401 then raise(Error::Unauthorized)
54
+ when 0 then raise(Error::ServerError, "Connection error: #{return_code}")
55
+ when 400...600
56
+ raise _error_class(e_code || error_code), e_message || error_message
57
+ end
58
+
59
+ raise Error::UnexpectedError, body if expected_code && expected_code != code
60
+ end
61
+
62
+ def pagination
63
+ @pagination ||= Pagination.new(parsed_json[:meta].to_h[:pagination])
64
+ end
65
+
66
+ def resource_attributes
67
+ _resource = [@resource_path].flatten.compact.map(&:to_s).map(&:to_sym)
68
+ return parsed_json if _resource.empty?
69
+
70
+ parsed_json.dig(*_resource)
71
+ end
72
+
73
+ def [](arg)
74
+ parsed_json[arg]
75
+ end
76
+
77
+ def resource
78
+ action = parsed_json[:action] if autoload_action
79
+ return [Action.new(self, action), block.call(self)].flatten(1) if block && action
80
+ return block.call(self) if block
81
+
82
+ @resource_class.from_response(self, autoload_action: autoload_action)
83
+ end
84
+
85
+ def error_code
86
+ error[:code]
87
+ end
88
+
89
+ def error_message
90
+ error[:message]
91
+ end
92
+
93
+ def error
94
+ parsed_json[:error].to_h
95
+ end
96
+
97
+ def _error_class(code)
98
+ case code
99
+ when 'invalid_input' then Error::InvalidInput
100
+ when 'forbidden' then Error::Forbidden
101
+ when 'locked' then Error::Locked
102
+ when 'not_found' then Error::NotFound
103
+ when 'rate_limit_exceeded' then Error::RateLimitExceeded
104
+ when 'resource_unavailable' then Error::ResourceUnavailable
105
+ when 'service_error' then Error::ServiceError
106
+ when 'uniqueness_error' then Error::UniquenessError
107
+ else
108
+ Error::ServerError
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hcloud
2
- VERSION = '0.1.2'.freeze
4
+ VERSION = '1.0.0'
3
5
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class Volume
5
+ require 'hcloud/volume_resource'
6
+
7
+ include EntryLoader
8
+
9
+ schema(
10
+ created: :time,
11
+ location: Location
12
+ )
13
+
14
+ protectable :delete
15
+ updatable :name
16
+ destructible
17
+
18
+ has_actions
19
+
20
+ def attach(server:, automount:)
21
+ prepare_request('actions/attach', j: COLLECT_ARGS.call(__method__, binding))
22
+ end
23
+
24
+ def detach
25
+ prepare_request('actions/detach', method: :post)
26
+ end
27
+
28
+ def resize(size:)
29
+ prepare_request('actions/resize', j: COLLECT_ARGS.call(__method__, binding))
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class VolumeResource < AbstractResource
5
+ filter_attributes :name
6
+
7
+ def [](arg)
8
+ case arg
9
+ when Integer then find_by(id: arg)
10
+ when String then find_by(name: arg)
11
+ end
12
+ end
13
+
14
+ def create(size:, name:, automount: nil, format: nil, location: nil, server: nil)
15
+ prepare_request(
16
+ 'volumes', j: COLLECT_ARGS.call(__method__, binding),
17
+ expected_code: 201
18
+ ) do |response|
19
+ [
20
+ Action.new(client, response.parsed_json[:action]),
21
+ Volume.new(client, response.parsed_json[:volume]),
22
+ response.parsed_json[:next_actions].map do |action|
23
+ Action.new(client, action)
24
+ end
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hcloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Foerster
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-27 00:00:00.000000000 Z
11
+ date: 2020-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: activesupport
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -28,16 +42,16 @@ dependencies:
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: '1.15'
47
+ version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: '1.15'
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: grape
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +70,16 @@ dependencies:
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +164,7 @@ files:
150
164
  - ".travis.yml"
151
165
  - CHANGELOG.md
152
166
  - Gemfile
167
+ - Gemfile.lock
153
168
  - README.md
154
169
  - Rakefile
155
170
  - bin/console
@@ -172,7 +187,8 @@ files:
172
187
  - lib/hcloud/iso_resource.rb
173
188
  - lib/hcloud/location.rb
174
189
  - lib/hcloud/location_resource.rb
175
- - lib/hcloud/multi_reply.rb
190
+ - lib/hcloud/network.rb
191
+ - lib/hcloud/network_resource.rb
176
192
  - lib/hcloud/pagination.rb
177
193
  - lib/hcloud/server.rb
178
194
  - lib/hcloud/server_resource.rb
@@ -180,7 +196,10 @@ files:
180
196
  - lib/hcloud/server_type_resource.rb
181
197
  - lib/hcloud/ssh_key.rb
182
198
  - lib/hcloud/ssh_key_resource.rb
199
+ - lib/hcloud/typhoeus_ext.rb
183
200
  - lib/hcloud/version.rb
201
+ - lib/hcloud/volume.rb
202
+ - lib/hcloud/volume_resource.rb
184
203
  homepage: https://github.com/tonobo/hcloud
185
204
  licenses: []
186
205
  metadata: {}
@@ -199,8 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
218
  - !ruby/object:Gem::Version
200
219
  version: '0'
201
220
  requirements: []
202
- rubyforge_project:
203
- rubygems_version: 2.5.2.2
221
+ rubygems_version: 3.1.2
204
222
  signing_key:
205
223
  specification_version: 4
206
224
  summary: HetznerCloud native Ruby client
@@ -1,21 +0,0 @@
1
- module Hcloud
2
- class MultiReply
3
- include Enumerable
4
- attr_accessor :cb
5
-
6
- def initialize(j:, pagination: nil)
7
- @j = j
8
- @pagination = pagination
9
- end
10
-
11
- def pagination
12
- @pagination || Pagination.new(@j.first.to_h['meta'].to_h['pagination'], nil, nil)
13
- end
14
-
15
- def each
16
- @cb.call(@j).each do |member|
17
- yield(member)
18
- end
19
- end
20
- end
21
- end