hetznercloud 1.0.0 → 1.3.1

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/README.md +32 -8
  4. data/config/inflections.rb +12 -3
  5. data/lib/core_ext/send_wrap.rb +11 -4
  6. data/lib/hcloud/concerns/actionable.rb +9 -2
  7. data/lib/hcloud/concerns/concerns.rb +8 -0
  8. data/lib/hcloud/concerns/creatable.rb +3 -2
  9. data/lib/hcloud/concerns/deletable.rb +2 -0
  10. data/lib/hcloud/concerns/meterable.rb +17 -0
  11. data/lib/hcloud/concerns/queryable.rb +4 -0
  12. data/lib/hcloud/concerns/singleton.rb +25 -0
  13. data/lib/hcloud/concerns/updatable.rb +2 -0
  14. data/lib/hcloud/entities/algorithm.rb +7 -0
  15. data/lib/hcloud/entities/certificate_status.rb +9 -0
  16. data/lib/hcloud/entities/floating_ip_price.rb +7 -0
  17. data/lib/hcloud/entities/floating_ip_prices.rb +8 -0
  18. data/lib/hcloud/entities/health_check.rb +12 -0
  19. data/lib/hcloud/entities/health_check_http.rb +13 -0
  20. data/lib/hcloud/entities/health_status.rb +8 -0
  21. data/lib/hcloud/entities/image_price.rb +7 -0
  22. data/lib/hcloud/entities/ipv4.rb +12 -0
  23. data/lib/hcloud/entities/ipv6.rb +12 -0
  24. data/lib/hcloud/entities/label_selector.rb +7 -0
  25. data/lib/hcloud/entities/load_balancer_private_net.rb +8 -0
  26. data/lib/hcloud/entities/load_balancer_public_net.rb +11 -0
  27. data/lib/hcloud/entities/load_balancer_type_price.rb +9 -0
  28. data/lib/hcloud/entities/private_net.rb +10 -0
  29. data/lib/hcloud/entities/public_net.rb +10 -0
  30. data/lib/hcloud/entities/route.rb +8 -0
  31. data/lib/hcloud/entities/server_backup_price.rb +7 -0
  32. data/lib/hcloud/entities/server_type_price.rb +9 -0
  33. data/lib/hcloud/entities/service.rb +16 -0
  34. data/lib/hcloud/entities/service_http.rb +16 -0
  35. data/lib/hcloud/entities/subnet.rb +11 -0
  36. data/lib/hcloud/entities/target.rb +15 -0
  37. data/lib/hcloud/entities/target_ip.rb +7 -0
  38. data/lib/hcloud/entities/target_target.rb +15 -0
  39. data/lib/hcloud/entities/targets.rb +13 -0
  40. data/lib/hcloud/entities/traffic_price.rb +7 -0
  41. data/lib/hcloud/entities/used_by.rb +8 -0
  42. data/lib/hcloud/entities/volume_price.rb +7 -0
  43. data/lib/hcloud/entity.rb +1 -0
  44. data/lib/hcloud/errors.rb +32 -2
  45. data/lib/hcloud/http.rb +12 -4
  46. data/lib/hcloud/resource_type.rb +41 -2
  47. data/lib/hcloud/resources/certificate.rb +131 -0
  48. data/lib/hcloud/resources/firewall.rb +57 -3
  49. data/lib/hcloud/resources/floating_ip.rb +2 -3
  50. data/lib/hcloud/resources/image.rb +1 -1
  51. data/lib/hcloud/resources/load_balancer.rb +107 -0
  52. data/lib/hcloud/resources/load_balancer_type.rb +38 -0
  53. data/lib/hcloud/resources/network.rb +142 -0
  54. data/lib/hcloud/resources/pricing.rb +34 -0
  55. data/lib/hcloud/resources/server.rb +12 -15
  56. data/lib/hcloud/resources/volume.rb +4 -5
  57. data/lib/hcloud/version.rb +2 -2
  58. data/lib/hcloud.rb +0 -2
  59. metadata +38 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75623886cacdbf6d5513f45eb32c0d34ef0c8f0c1adee2bc7e69bf049b9c77ce
4
- data.tar.gz: 8055fc431b7a33ef53c6f30ca9002e36f91e1c723197294bf1cc8c00d8035072
3
+ metadata.gz: 78ef10de0c462ae7e1c5bf47c747d25a110551f817800b70b2aef7f5a045db5c
4
+ data.tar.gz: d9833600b525f01a5879888809a401df07bb7120f2d42db2e43220e0897cbfb5
5
5
  SHA512:
6
- metadata.gz: ccc0bcd9ea354b43cd7b235b788f516a2665066580f44cd25e9d17d6e206680e3cc33786c14c1e47a5948c606588ef517e0a371a6de8537365e8697fea04a16d
7
- data.tar.gz: cce03b3d75507f236152b04b731bd85cf88e15bef217805f6758e1fbf7dc12eb66e36b24717ee01680b16226f20d457b301436ca83d03aa183b6f7945f93dda0
6
+ metadata.gz: 20a46b53f9caa94a730c512208817c3ec7eb871983ade5bdd8acf2c19f77089084a31648c7b10d4d25d7cf3004f440d6732729398836e437838315fb01ec1985
7
+ data.tar.gz: 6cd6709f99a23259d4e82a93285aa415358cdc51dff6489911df5c35a06c6d85005c65eee5a42021bd69a665f33b620196d3657675122bd1c78da0d2d374c869
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## HCloud v1.3.1
4
+
5
+ - Add missing Server#user_data
6
+
7
+ ## HCloud v1.3.0
8
+
9
+ - Implemented Load Balancers
10
+ - Implemented Load Balancer Types
11
+
12
+ ## HCloud v1.2.0
13
+
14
+ - Implemented Networks
15
+ - Implemented Network Actions
16
+ - Implemented Pricing
17
+ - Implemented Certificates
18
+ - Implemented Certificate Actions
19
+
20
+ ## HCloud v1.1.0
21
+
22
+ - Implemented Firewall Actions
23
+
3
24
  ## HCloud v1.0.0
4
25
 
5
26
  Initial release
data/README.md CHANGED
@@ -74,24 +74,24 @@ Not all Hetzner Cloud API endpoints have been implemented yet.
74
74
  | Resource | State |
75
75
  |-----------------------|-----------------------|
76
76
  | Actions | Implemented |
77
- | Certificates | Not implemented |
78
- | Certificate Actions | Not implemented |
77
+ | Certificates | Implemented |
78
+ | Certificate Actions | Implemented |
79
79
  | Datacenters | Implemented |
80
80
  | Firewalls | Implemented |
81
- | Firewall Actions | Not implemented |
81
+ | Firewall Actions | Implemented |
82
82
  | Floating IPs | Implemented |
83
83
  | Floating IP Actions | Implemented |
84
84
  | Images | Implemented |
85
85
  | Image Actions | Implemented |
86
86
  | ISOs | Implemented |
87
- | Load Balancers | Not implemented |
87
+ | Load Balancers | Implemented |
88
88
  | Load Balancer Actions | Not implemented |
89
- | Load Balancer Types | Not implemented |
89
+ | Load Balancer Types | Implemented |
90
90
  | Locations | Implemented |
91
- | Networks | Not implemented |
92
- | Network Actions | Not implemented |
91
+ | Networks | Implemented |
92
+ | Network Actions | Implemented |
93
93
  | Placement Groups | Implemented |
94
- | Pricing | Not implemented |
94
+ | Pricing | Implemented |
95
95
  | Servers | Partially implemented |
96
96
  | Server Actions | Not implemented |
97
97
  | Server Types | Implemented |
@@ -109,6 +109,30 @@ bundle exec rspec
109
109
  bundle exec rspec --tag integration
110
110
  ```
111
111
 
112
+ ## Debugging
113
+
114
+ ### Logging
115
+
116
+ When using the gem in your code, you can pass a `logger:` argument to `HCloud::Client`:
117
+
118
+ ```ruby
119
+ logger = Logger.new("log/http.log")
120
+ logger.level = :debug
121
+
122
+ client = HCloud::Client.new(access_token: "my_access_token", logger: logger)
123
+ ```
124
+
125
+ When executing the test suite, set `LOG_LEVEL` environment variable to `debug` in order to see HTTP requests.
126
+
127
+ ### Endpoint
128
+
129
+ `HCloud::Client` also accepts an alternate endpoint:
130
+
131
+
132
+ ```ruby
133
+ client = HCloud::Client.new(access_token: "my_access_token", endpoint: "https://myproxy/v1")
134
+ ```
135
+
112
136
  ## Releasing
113
137
 
114
138
  To release a new version, update the version number in `lib/hcloud/version.rb`, update the changelog, commit the files and create a git tag starting with `v`, and push it to the repository.
@@ -2,18 +2,27 @@
2
2
 
3
3
  HCloud.loader.inflector.inflect(
4
4
  "dns_pointer" => "DNSPointer",
5
- "hcloud" => "HCloud",
6
- "ssh_key" => "SSHKey",
7
5
  "floating_ip" => "FloatingIP",
6
+ "floating_ip_price" => "FloatingIPPrice",
7
+ "floating_ip_prices" => "FloatingIPPrices",
8
+ "floating_ips" => "FloatingIPs",
9
+ "hcloud" => "HCloud",
10
+ "health_check_http" => "HealthCheckHTTP",
8
11
  "http" => "HTTP",
9
12
  "ip_not_available" => "IPNotAvailable",
13
+ "ipv4" => "IPv4",
14
+ "ipv6" => "IPv6",
10
15
  "iso" => "ISO",
11
16
  "iso_type" => "ISOType",
17
+ "service_http" => "ServiceHTTP",
18
+ "ssh_key" => "SSHKey",
19
+ "target_ip" => "TargetIP",
12
20
  )
13
21
 
14
22
  ActiveSupport::Inflector.inflections(:en) do |inflect|
15
23
  inflect.acronym "DNS"
16
- inflect.acronym "JSON"
24
+ inflect.acronym "HTTP"
17
25
  inflect.acronym "IP"
18
26
  inflect.acronym "ISO"
27
+ inflect.acronym "JSON"
19
28
  end
@@ -2,12 +2,19 @@
2
2
 
3
3
  module CoreExt
4
4
  module SendWrap
5
- # Send a message to self, or all objects contained in self (for enumerables)
5
+ # Send a message to self, or all objects contained in self (for arrays)
6
6
 
7
- # FIXME: { env: "prod" }.send_wrap(:try, :to_h) returns { env: nil }
7
+ # NOTE: { env: "prod" }.send_wrap(:try, :to_h) returns { env: nil }
8
+ # NOTE: ["example.com"].send_wrap(:try, to_h) return [nil]
9
+ # Use a block for the above cases:
10
+ # { env: "prod" }.send_wrap { |o| o.try(:to_h) || o }
8
11
 
9
- def send_wrap(method_name, ...)
10
- is_a?(Array) ? map { |v| v.send(method_name, ...) } : send(method_name, ...)
12
+ def send_wrap(...)
13
+ if is_a?(Array)
14
+ map { |v| block_given? ? yield(v) : v.send(...) }
15
+ else
16
+ block_given? ? yield(self) : send(...)
17
+ end
11
18
  end
12
19
  end
13
20
  end
@@ -19,9 +19,16 @@ module HCloud
19
19
  action_names << name.to_s
20
20
 
21
21
  define_method(name) do |**params|
22
- Action.new client
22
+ raise Errors::MissingIDError unless id
23
+
24
+ response = client
23
25
  .post("/#{resource_name.pluralize}/#{id}/actions/#{name}", params)
24
- .fetch(:action)
26
+
27
+ if response.key?(:actions)
28
+ response[:actions].map { |r| Action.new r }
29
+ else
30
+ Action.new response[:action]
31
+ end
25
32
  end
26
33
  end
27
34
  end
@@ -24,6 +24,14 @@ module HCloud
24
24
  def deletable
25
25
  include Deletable
26
26
  end
27
+
28
+ def meterable
29
+ include Meterable
30
+ end
31
+
32
+ def singleton
33
+ include Singleton
34
+ end
27
35
  end
28
36
  end
29
37
  end
@@ -10,6 +10,7 @@ module HCloud
10
10
  def create
11
11
  assign_attributes client
12
12
  .post("/#{resource_name.pluralize}", creatable_params)
13
+ .tap { |r| r[resource_name.to_sym].merge!(r.slice(:root_password)) }
13
14
  .fetch(resource_name.to_sym)
14
15
  end
15
16
 
@@ -29,9 +30,9 @@ module HCloud
29
30
 
30
31
  attributes
31
32
  .slice(*simple_attributes.map(&:to_s))
32
- .transform_values { |v| v&.send_wrap(:try, :to_h) || v&.send_wrap(:to_s) }
33
+ .transform_values { |v| v&.send_wrap { |o| o.try(:to_h) || o } || v&.send_wrap(:to_s) }
33
34
  .merge(nested_attributes.reduce(&:merge)&.map { |k, v| [k.to_s, Array(v).filter_map { |w| send(k)&.send_wrap(w) }.first] }.to_h)
34
- .compact
35
+ .compact_blank
35
36
  end
36
37
  # rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
37
38
  end
@@ -6,6 +6,8 @@ module HCloud
6
6
 
7
7
  included do
8
8
  def delete
9
+ raise Errors::MissingIDError unless id
10
+
9
11
  client
10
12
  .delete("/#{resource_name.pluralize}/#{id}")
11
13
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ module Meterable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def metrics(type:, from:, to:, step: nil)
9
+ raise Errors::MissingIDError unless id
10
+
11
+ Metrics.new client
12
+ .get("/#{resource_name.pluralize}/#{id}/metrics", type: Array(type).join(","), start: from.iso8601, end: to.iso8601, step: step)
13
+ .fetch(:metrics)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,8 @@ module HCloud
6
6
 
7
7
  included do
8
8
  def reload
9
+ raise Errors::MissingIDError unless id
10
+
9
11
  assign_attributes client
10
12
  .get("/#{resource_name.pluralize}/#{id}")
11
13
  .fetch(resource_name.to_sym)
@@ -16,6 +18,8 @@ module HCloud
16
18
 
17
19
  class_methods do
18
20
  def find(id)
21
+ raise Errors::MissingIDError unless id
22
+
19
23
  new client
20
24
  .get("/#{resource_name.pluralize}/#{id}")
21
25
  .fetch(resource_name.to_sym)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ module Singleton
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def reload
9
+ assign_attributes client
10
+ .get("/#{resource_name}")
11
+ .fetch(resource_name.to_sym)
12
+
13
+ self
14
+ end
15
+ end
16
+
17
+ class_methods do
18
+ def find
19
+ new client
20
+ .get("/#{resource_name}")
21
+ .fetch(resource_name.to_sym)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,6 +6,8 @@ module HCloud
6
6
 
7
7
  included do
8
8
  def update
9
+ raise Errors::MissingIDError unless id
10
+
9
11
  assign_attributes client
10
12
  .put("/#{resource_name.pluralize}/#{id}", updatable_params)
11
13
  .fetch(resource_name.to_sym)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Algorithm < Entity
5
+ attribute :type
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class CertificateStatus < Entity
5
+ attribute :error, :error
6
+ attribute :issuance
7
+ attribute :renewal
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class FloatingIPPrice < Entity
5
+ attribute :price_monthly, :amount
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class FloatingIPPrices < Entity
5
+ attribute :type
6
+ attribute :prices, :price
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class HealthCheck < Entity
5
+ attribute :http, :health_check_http
6
+ attribute :interval, :integer
7
+ attribute :port, :integer
8
+ attribute :protocol
9
+ attribute :retries, :integer
10
+ attribute :timeout, :integer
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class HealthCheckHTTP < Entity
5
+ attribute :domain
6
+ attribute :path
7
+ attribute :response
8
+ attribute :status_code, array: true, default: -> { [] }
9
+ attribute :tls
10
+
11
+ alias tls? tls
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class HealthStatus < Entity
5
+ attribute :listen_port, :integer
6
+ attribute :status
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ImagePrice < Entity
5
+ attribute :price_per_gb_month, :amount
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class IPv4 < Entity
5
+ attribute :blocked, :boolean
6
+ attribute :dns_ptr
7
+ attribute :id, :integer
8
+ attribute :ip
9
+
10
+ alias blocked? blocked
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class IPv6 < Entity
5
+ attribute :blocked, :boolean
6
+ attribute :dns_ptr, :dns_pointer, array: true, default: -> { [] }
7
+ attribute :id, :integer
8
+ attribute :ip
9
+
10
+ alias blocked? blocked
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class LabelSelector < Entity
5
+ attribute :selector
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class LoadBalancerPrivateNet < Entity
5
+ attribute :ip
6
+ attribute :network
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class LoadBalancerPublicNet < Entity
5
+ attribute :enabled, :boolean
6
+ attribute :ipv4, :dns_pointer
7
+ attribute :ipv6, :dns_pointer
8
+
9
+ alias enabled? enabled
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class LoadBalancerTypePrice < Entity
5
+ attribute :id, :integer
6
+ attribute :name
7
+ attribute :prices, :price, array: true, default: -> { [] }
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class PrivateNet < Entity
5
+ attribute :alias_ips, array: true, default: -> { [] }
6
+ attribute :ip
7
+ attribute :mac_address
8
+ attribute :network, :network
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class PublicNet < Entity
5
+ attribute :firewalls, :firewall, array: true, default: -> { [] }
6
+ attribute :floating_ips, :floating_ip, array: true, default: -> { [] }
7
+ attribute :ipv4, :ipv4
8
+ attribute :ipv6, :ipv6
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Route < Entity
5
+ attribute :destination
6
+ attribute :gateway
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServerBackupPrice < Entity
5
+ attribute :percentage
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServerTypePrice < Entity
5
+ attribute :id, :integer
6
+ attribute :name
7
+ attribute :prices, :price, array: true, default: -> { [] }
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Service < Entity
5
+ attribute :listen_port, :integer
6
+ attribute :destination_port, :integer
7
+
8
+ attribute :protocol
9
+ attribute :proxyprotocol, :boolean
10
+
11
+ attribute :health_check, :health_check
12
+ attribute :http, :service_http
13
+
14
+ alias proxyprotocol? proxyprotocol
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServiceHTTP < Entity
5
+ attribute :certificates, :certificate, array: true, default: -> { [] }
6
+
7
+ attribute :cookie_lifetime, :integer
8
+ attribute :cookie_name
9
+
10
+ attribute :redirect_http, :boolean
11
+ attribute :sticky_sessions, :boolean
12
+
13
+ alias redirect_http? redirect_http
14
+ alias sticky_sessions? sticky_sessions
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Subnet < Entity
5
+ attribute :type
6
+ attribute :network_zone
7
+ attribute :gateway
8
+ attribute :ip_range
9
+ attribute :vswitch_id
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Target < Entity
5
+ attribute :type
6
+
7
+ attribute :health_status, :health_status, array: true, default: -> { [] }
8
+
9
+ attribute :server, :server
10
+
11
+ attribute :use_private_ip, :boolean
12
+
13
+ alias use_private_ip? use_private_ip
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class TargetIP < Entity
5
+ attribute :ip
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class TargetTarget < Entity
5
+ attribute :type
6
+
7
+ attribute :health_status, :health_status, array: true, default: -> { [] }
8
+
9
+ attribute :server, :server
10
+
11
+ attribute :use_private_ip, :boolean
12
+
13
+ alias use_private_ip? use_private_ip
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Targets < Target
5
+ attribute :type
6
+
7
+ attribute :ip, :target_ip
8
+
9
+ attribute :label_selector, :label_selector
10
+
11
+ attribute :targets, :target, array: true, default: -> { [] }
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class TrafficPrice < Entity
5
+ attribute :price_per_tb, :amount
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class UsedBy < Entity
5
+ attribute :id, :integer
6
+ attribute :type
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class VolumePrice < Entity
5
+ attribute :price_per_gb_month, :amount
6
+ end
7
+ end
data/lib/hcloud/entity.rb CHANGED
@@ -18,6 +18,7 @@ module HCloud
18
18
  def to_h
19
19
  attributes
20
20
  .transform_values { |v| v.try(:to_h) || v }
21
+ .compact_blank
21
22
  end
22
23
  end
23
24
  end