hetznercloud 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/Gemfile +13 -0
  4. data/README.md +76 -32
  5. data/config/inflections.rb +3 -0
  6. data/lib/hcloud/client.rb +4 -3
  7. data/lib/hcloud/collection.rb +4 -2
  8. data/lib/hcloud/concerns/concerns.rb +4 -0
  9. data/lib/hcloud/concerns/labelable.rb +11 -0
  10. data/lib/hcloud/concerns/queryable.rb +2 -0
  11. data/lib/hcloud/entities/primary_ip_prices.rb +8 -0
  12. data/lib/hcloud/entities/private_network.rb +15 -0
  13. data/lib/hcloud/entities/protection.rb +0 -2
  14. data/lib/hcloud/entities/server_protection.rb +11 -0
  15. data/lib/hcloud/http.rb +4 -2
  16. data/lib/hcloud/resource_type.rb +32 -2
  17. data/lib/hcloud/resources/action.rb +5 -6
  18. data/lib/hcloud/resources/certificate.rb +8 -6
  19. data/lib/hcloud/resources/datacenter.rb +1 -1
  20. data/lib/hcloud/resources/firewall.rb +7 -5
  21. data/lib/hcloud/resources/floating_ip.rb +7 -5
  22. data/lib/hcloud/resources/image.rb +6 -7
  23. data/lib/hcloud/resources/iso.rb +1 -1
  24. data/lib/hcloud/resources/load_balancer.rb +7 -5
  25. data/lib/hcloud/resources/load_balancer_type.rb +1 -1
  26. data/lib/hcloud/resources/location.rb +1 -1
  27. data/lib/hcloud/resources/metadata.rb +33 -0
  28. data/lib/hcloud/resources/network.rb +5 -3
  29. data/lib/hcloud/resources/placement_group.rb +7 -5
  30. data/lib/hcloud/resources/pricing.rb +2 -0
  31. data/lib/hcloud/resources/primary_ip.rb +8 -6
  32. data/lib/hcloud/resources/server.rb +9 -7
  33. data/lib/hcloud/resources/server_type.rb +1 -1
  34. data/lib/hcloud/resources/ssh_key.rb +8 -6
  35. data/lib/hcloud/resources/volume.rb +8 -6
  36. data/lib/hcloud/version.rb +1 -1
  37. data/lib/http/mime_type/yaml.rb +23 -0
  38. data/lib/http/rate_limiter.rb +40 -0
  39. metadata +9 -128
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1b9b0de15d2fe2aecdbfa6b00b46df9ec658855ebdafcabebe72f371dd98d50
4
- data.tar.gz: 6c39c3ee93d35767d355e522408d1285ce3777fc841753968ae9c33d0916cc6c
3
+ metadata.gz: 0a4ca2b02a62b66c5fc5024fcfc7d1c0614f29b7008fdb7b7d92ce9839b542c3
4
+ data.tar.gz: 26a182b4a53db2a04731130c5b74ffa6f92eaadf17ae0d69080c64b3a0a71c50
5
5
  SHA512:
6
- metadata.gz: 7a9971d0195c839594b88759d828dc04f98e36d37eab7880d27f4299f8266d2e37676eea3b60399440bed9240e6d39190dba0af75f2d32bfe78c5e42bb160cd5
7
- data.tar.gz: bbecc7998329638d8499d0a33c877cdc5857b2a94c80633672a874f6828cc69f29e67d8e3a618b21db5cd84d87cf66cecd2e2ee3ddcfa16db00f841394f0ea85
6
+ metadata.gz: e57fbe462b9805f2f6615f9ddef3ef9eb1b4498620d54537dc0d73a2000e34df78ed2b8493e12032fdb842cb632887fe1e7df826cffb87f8b630d99fa002c35e
7
+ data.tar.gz: 2ee09e22a6c9d4dafb745ab98f204bd2af649b26eaab35f2a67370250a47fd7ff6c1060e79fe3e785c736c7c9ed5d48725479856dfc1d879147c82a0f32de79d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## HCloud v1.5.0 (2023-02-01)
4
+
5
+ - Add pricing for Primary IPs
6
+ - Add server Metadata resource
7
+ - Add support for rate limits
8
+ - `Action#resources` now returns a list of resources instead of a list of hashes
9
+ - Separate server protection entity from other protection entity (only server protection includes `rebuild`)
10
+ - Add shorthand methods for `.first`, `.last`, `.count`, `.where`, `.sort`, `.each`, and `.empty?` on resource
11
+ - Add `label_selector:` argument to `HCloud::Collection`
12
+
3
13
  ## HCloud v1.4.0 (2023-01-22)
4
14
 
5
15
  - Implemented Primary IPs
data/Gemfile CHANGED
@@ -4,3 +4,16 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in hcloud.gemspec
6
6
  gemspec
7
+
8
+ group :development, :test do
9
+ gem "byebug", require: false
10
+ gem "dotenv", require: false
11
+ gem "ffaker", require: false
12
+ gem "rake", require: false
13
+ gem "rspec", require: false
14
+ gem "rubocop", require: false
15
+ gem "rubocop-performance", require: false
16
+ gem "rubocop-rspec", require: false
17
+ gem "timecop", require: false
18
+ gem "webmock", require: false
19
+ end
data/README.md CHANGED
@@ -69,37 +69,82 @@ It expects you to use it in a sane way.
69
69
 
70
70
  ## Features
71
71
 
72
- Not all Hetzner Cloud API endpoints have been implemented yet.
73
-
74
- | Resource | State |
75
- |-----------------------|-----------------------|
76
- | Actions | Implemented |
77
- | Certificates | Implemented |
78
- | Certificate Actions | Implemented |
79
- | Datacenters | Implemented |
80
- | Firewalls | Implemented |
81
- | Firewall Actions | Implemented |
82
- | Floating IPs | Implemented |
83
- | Floating IP Actions | Implemented |
84
- | Images | Implemented |
85
- | Image Actions | Implemented |
86
- | ISOs | Implemented |
87
- | Load Balancers | Implemented |
88
- | Load Balancer Actions | Not implemented |
89
- | Load Balancer Types | Implemented |
90
- | Locations | Implemented |
91
- | Primary IPs | Implemented |
92
- | Primary IP Actions | Implemented |
93
- | Networks | Implemented |
94
- | Network Actions | Implemented |
95
- | Placement Groups | Implemented |
96
- | Pricing | Implemented |
97
- | Servers | Partially implemented |
98
- | Server Actions | Not implemented |
99
- | Server Types | Implemented |
100
- | SSH Keys | Implemented |
101
- | Volumes | Implemented |
102
- | Volume Actions | Implemented |
72
+ The following table lists the Hetzner Cloud API endpoints that are currently implemented.
73
+
74
+ | Resource | State |
75
+ |----------------------------------------------------------------|-----------------------|
76
+ | [Actions](lib/hcloud/resources/action.rb) | Implemented |
77
+ | [Certificates](lib/hcloud/resources/certificate.rb) | Implemented |
78
+ | [Certificate Actions](lib/hcloud/resources/certificate.rb) | Implemented |
79
+ | [Datacenters](lib/hcloud/resources/datacenter.rb) | Implemented |
80
+ | [Firewalls](lib/hcloud/resources/firewall.rb) | Implemented |
81
+ | [Firewall Actions](lib/hcloud/resources/firewall.rb) | Implemented |
82
+ | [Floating IPs](lib/hcloud/resources/floating_ip.rb) | Implemented |
83
+ | [Floating IP Actions](lib/hcloud/resources/floating_ip.rb) | Implemented |
84
+ | [Images](lib/hcloud/resources/image.rb) | Implemented |
85
+ | [Image Actions](lib/hcloud/resources/image.rb) | Implemented |
86
+ | [ISOs](lib/hcloud/resources/iso.rb) | Implemented |
87
+ | [Load Balancers](lib/hcloud/resources/load_balancer.rb) | Implemented |
88
+ | [Load Balancer Actions](lib/hcloud/resources/load_balancer.rb) | Not implemented |
89
+ | [Load Balancer Types](lib/hcloud/resources/load_balancer.rb) | Implemented |
90
+ | [Locations](lib/hcloud/resources/location.rb) | Implemented |
91
+ | [Primary IPs](lib/hcloud/resources/primary_ip.rb) | Implemented |
92
+ | [Primary IP Actions](lib/hcloud/resources/primary_ip.rb) | Implemented |
93
+ | [Networks](lib/hcloud/resources/network.rb) | Implemented |
94
+ | [Network Actions](lib/hcloud/resources/network.rb) | Implemented |
95
+ | [Placement Groups](lib/hcloud/resources/placement_group.rb) | Implemented |
96
+ | [Pricing](lib/hcloud/resources/pricing.rb) | Implemented |
97
+ | [Servers](lib/hcloud/resources/server.rb) | Partially implemented |
98
+ | [Server Actions](lib/hcloud/resources/server.rb) | Not implemented |
99
+ | [Server Types](lib/hcloud/resources/server_type.rb) | Implemented |
100
+ | [SSH Keys](lib/hcloud/resources/ssh_key.rb) | Implemented |
101
+ | [Volumes](lib/hcloud/resources/volume.rb) | Implemented |
102
+ | [Volume Actions](lib/hcloud/resources/volume.rb) | Implemented |
103
+ | | |
104
+ | [Metadata](lib/hcloud/resources/metadata.rb) | Implemented |
105
+
106
+ ### Pagination
107
+
108
+ Paginated resources are wrapped in a `HCloud::Collection` that automatically fetches the next page when needed.
109
+ The collection acts as a (lazy) enumerator.
110
+ Call `to_a` to fetch all pages and parse all resources.
111
+
112
+ ### Rate limiting
113
+
114
+ From the [documentation](https://docs.hetzner.cloud/#rate-limiting):
115
+
116
+ > The default limit is 3600 requests per hour and per Project.
117
+ > The number of remaining requests increases gradually.
118
+ > For example, when your limit is 3600 requests per hour, the number of remaining requests will increase by 1 every second.
119
+
120
+ The client is able to handle the rate limiting by delaying the requests if necessary and executing them whenever possible.
121
+ To enable this behaviour, pass `rate_limit: true` as argument to `HCloud::Client.new`.
122
+ Client calls will block until possible to execute and then return.
123
+
124
+ ```ruby
125
+ client = HCloud::Client.new(access_token: "my_token", rate_limit: true)
126
+
127
+ # At least one request has to be made to enable the rate limiter
128
+ client.rate_limiter.limit # => nil
129
+ client.rate_limiter.remaining # => nil
130
+ client.rate_limiter.reset # => nil
131
+
132
+ HCloud::Server.create(...)
133
+
134
+ client.rate_limiter.limit # => 3600
135
+ client.rate_limiter.remaining # => 3599
136
+ client.rate_limiter.reset # => 2023-01-01 00:00:00 +0100
137
+
138
+ # Make a bunch of requests
139
+
140
+ client.rate_limiter.remaining # => 0
141
+
142
+ servers = HCloud::Server.all # Will block until remaining requests have regenerated (1 second by default) and then execute
143
+ ssh_keys = HCloud::SSHKey.all # Will block until remaining requests have regenerated (1 second by default) and then execute
144
+ ```
145
+
146
+ Since rate limits are per hour and per project, using multiple clients at the same time will interfere with the rate limiting mechanism.
147
+ To prevent this, wrap client calls in a loop that retries the call after it fails with a `HCloud::RateLimitExceeded` error.
103
148
 
104
149
  ## Testing
105
150
 
@@ -130,7 +175,6 @@ When executing the test suite, set `LOG_LEVEL` environment variable to `debug` i
130
175
 
131
176
  `HCloud::Client` also accepts an alternate endpoint:
132
177
 
133
-
134
178
  ```ruby
135
179
  client = HCloud::Client.new(access_token: "my_access_token", endpoint: "https://myproxy/v1")
136
180
  ```
@@ -15,9 +15,11 @@ HCloud.loader.inflector.inflect(
15
15
  "iso" => "ISO",
16
16
  "iso_type" => "ISOType",
17
17
  "primary_ip" => "PrimaryIP",
18
+ "primary_ip_prices" => "PrimaryIPPrices",
18
19
  "service_http" => "ServiceHTTP",
19
20
  "ssh_key" => "SSHKey",
20
21
  "target_ip" => "TargetIP",
22
+ "yaml" => "YAML",
21
23
  )
22
24
 
23
25
  ActiveSupport::Inflector.inflections(:en) do |inflect|
@@ -28,4 +30,5 @@ ActiveSupport::Inflector.inflections(:en) do |inflect|
28
30
  inflect.acronym "IPv6"
29
31
  inflect.acronym "ISO"
30
32
  inflect.acronym "JSON"
33
+ inflect.acronym "YAML"
31
34
  end
data/lib/hcloud/client.rb CHANGED
@@ -19,12 +19,13 @@ module HCloud
19
19
 
20
20
  self.connection = NilConnection.new
21
21
 
22
- attr_reader :access_token, :endpoint, :logger
22
+ attr_reader :access_token, :endpoint, :logger, :rate_limit
23
23
 
24
- def initialize(access_token:, endpoint: "https://api.hetzner.cloud/v1", logger: Logger.new("/dev/null"))
24
+ def initialize(access_token:, endpoint: "https://api.hetzner.cloud/v1", logger: Logger.new("/dev/null"), rate_limit: false)
25
25
  @access_token = access_token
26
26
  @endpoint = endpoint
27
27
  @logger = logger
28
+ @rate_limit = rate_limit
28
29
  end
29
30
 
30
31
  delegate :get, :put, :post, :delete, to: :http
@@ -32,7 +33,7 @@ module HCloud
32
33
  private
33
34
 
34
35
  def http
35
- @http ||= HTTP.new(access_token, endpoint, logger)
36
+ @http ||= HTTP.new(access_token, endpoint, logger, rate_limit)
36
37
  end
37
38
  end
38
39
  end
@@ -6,7 +6,7 @@ module HCloud
6
6
 
7
7
  attr_accessor :page, :previous_page, :next_page, :last_page, :per_page, :total_entries, :proc
8
8
 
9
- attr_reader :sort_by, :filter_by
9
+ attr_reader :sort_by, :filter_by, :label_selector
10
10
 
11
11
  def initialize(&block)
12
12
  @proc = block
@@ -24,8 +24,9 @@ module HCloud
24
24
  self
25
25
  end
26
26
 
27
- def where(**filter_by)
27
+ def where(label_selector: nil, **filter_by)
28
28
  @filter_by = filter_by
29
+ @label_selector = label_selector
29
30
 
30
31
  self
31
32
  end
@@ -70,6 +71,7 @@ module HCloud
70
71
  page: page,
71
72
  per_page: per_page,
72
73
  sort: sort_by,
74
+ label_selector: label_selector&.map { |k, v| "#{k}=#{v}" }&.join(","),
73
75
  **filter_by,
74
76
  }
75
77
  end
@@ -32,6 +32,10 @@ module HCloud
32
32
  def singleton
33
33
  include Singleton
34
34
  end
35
+
36
+ def labelable
37
+ include Labelable
38
+ end
35
39
  end
36
40
  end
37
41
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ module Labelable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attribute :labels, default: -> { {} }
9
+ end
10
+ end
11
+ end
@@ -17,6 +17,8 @@ module HCloud
17
17
  end
18
18
 
19
19
  class_methods do
20
+ delegate :first, :last, :count, :where, :sort, :each, :empty?, :any?, to: :all
21
+
20
22
  def find(id)
21
23
  raise Errors::MissingIDError unless id
22
24
 
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class PrimaryIPPrices < Entity
5
+ attribute :type
6
+ attribute :prices, :price
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class PrivateNetwork < Entity
5
+ attribute :ip
6
+ attribute :alias_ips, array: true, default: -> { [] }
7
+ attribute :interface_num, :integer
8
+ attribute :mac_address
9
+ attribute :network_id, :integer
10
+ attribute :network_name
11
+ attribute :network
12
+ attribute :subnet
13
+ attribute :gateway
14
+ end
15
+ end
@@ -3,9 +3,7 @@
3
3
  module HCloud
4
4
  class Protection < Entity
5
5
  attribute :delete, :boolean
6
- attribute :rebuild, :boolean
7
6
 
8
7
  alias delete? delete
9
- alias rebuild? rebuild
10
8
  end
11
9
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServerProtection < Entity
5
+ attribute :delete, :boolean
6
+ attribute :rebuild, :boolean
7
+
8
+ alias delete? delete
9
+ alias rebuild? rebuild
10
+ end
11
+ end
data/lib/hcloud/http.rb CHANGED
@@ -4,12 +4,13 @@ require "http"
4
4
 
5
5
  module HCloud
6
6
  class HTTP
7
- attr_reader :access_token, :endpoint, :logger, :timeout
7
+ attr_reader :access_token, :endpoint, :logger, :rate_limit, :timeout
8
8
 
9
- def initialize(access_token, endpoint, logger, timeout = 10)
9
+ def initialize(access_token, endpoint, logger, rate_limit = false, timeout = 10)
10
10
  @access_token = access_token
11
11
  @endpoint = endpoint
12
12
  @logger = logger
13
+ @rate_limit = rate_limit
13
14
  @timeout = timeout
14
15
  end
15
16
 
@@ -80,6 +81,7 @@ module HCloud
80
81
  .headers(accept: "application/json", user_agent: "#{HCloud::NAME}/#{HCloud::VERSION}")
81
82
  .timeout(timeout)
82
83
  .use(logging: { logger: logger })
84
+ .then { |h| rate_limit ? h.use(:rate_limiter) : h }
83
85
  .encoding("utf-8")
84
86
  .auth("Bearer #{access_token}")
85
87
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize
3
4
  module HCloud
4
5
  class ResourceType
5
6
  class_attribute :resource_class_name
@@ -10,7 +11,6 @@ module HCloud
10
11
  @array = array
11
12
  end
12
13
 
13
- # rubocop:disable Metrics/CyclomaticComplexity
14
14
  def cast(value)
15
15
  case value
16
16
  when nil, []
@@ -28,12 +28,13 @@ module HCloud
28
28
  when Hash # Attribute hash
29
29
  resource_class.new(value)
30
30
  when Array # List
31
+ raise ArgumentError, "cannot cast value: #{value} for type #{resource_class_name}" unless array?
32
+
31
33
  value.map { |v| cast(v) }
32
34
  else
33
35
  raise ArgumentError, "cannot cast value: #{value} for type #{resource_class_name}"
34
36
  end
35
37
  end
36
- # rubocop:enable Metrics/CyclomaticComplexity
37
38
 
38
39
  def resource_class
39
40
  @resource_class ||= resource_class_name.constantize
@@ -52,8 +53,32 @@ module HCloud
52
53
  .tap { |klass| HCloud.const_set(:"#{class_name.demodulize}ResourceType", klass) }
53
54
  end
54
55
  # rubocop:enable Naming/MethodName
56
+
57
+ class GenericType < ResourceType
58
+ def cast(value)
59
+ case value
60
+ when nil, []
61
+ array? ? [] : nil
62
+ when HCloud::Resource # Class
63
+ value
64
+ when Hash # Attribute hash
65
+ ActiveModel::Type
66
+ .lookup(value.fetch(:type).to_sym)
67
+ .cast(value.except(:type))
68
+ when Array # List
69
+ raise ArgumentError, "cannot cast value: #{value} for generic type" unless array?
70
+
71
+ value.map { |v| cast(v) }
72
+ else
73
+ raise ArgumentError, "cannot cast value: #{value} for generic type"
74
+ end
75
+ rescue KeyError => e
76
+ raise ArgumentError, "cannot cast value: #{value} for generic type: #{e.message}"
77
+ end
78
+ end
55
79
  end
56
80
  end
81
+ # rubocop:enable Metrics/CyclomaticComplexity,Metrics/AbcSize
57
82
 
58
83
  ActiveModel::Type.register(:action, HCloud::ResourceType.Type("HCloud::Action"))
59
84
  ActiveModel::Type.register(:algorithm, HCloud::ResourceType.Type("HCloud::Algorithm"))
@@ -86,18 +111,23 @@ ActiveModel::Type.register(:load_balancer_public_net, HCloud::ResourceType.Type(
86
111
  ActiveModel::Type.register(:load_balancer_type, HCloud::ResourceType.Type("HCloud::LoadBalancerType"))
87
112
  ActiveModel::Type.register(:load_balancer_type_price, HCloud::ResourceType.Type("HCloud::LoadBalancerTypePrice"))
88
113
  ActiveModel::Type.register(:location, HCloud::ResourceType.Type("HCloud::Location"))
114
+ ActiveModel::Type.register(:metadata, HCloud::ResourceType.Type("HCloud::Metadata"))
89
115
  ActiveModel::Type.register(:network, HCloud::ResourceType.Type("HCloud::Network"))
90
116
  ActiveModel::Type.register(:placement_group, HCloud::ResourceType.Type("HCloud::PlacementGroup"))
91
117
  ActiveModel::Type.register(:price, HCloud::ResourceType.Type("HCloud::Price"))
92
118
  ActiveModel::Type.register(:pricing, HCloud::ResourceType.Type("HCloud::Pricing"))
93
119
  ActiveModel::Type.register(:primary_ip, HCloud::ResourceType.Type("HCloud::PrimaryIP"))
120
+ ActiveModel::Type.register(:primary_ip_prices, HCloud::ResourceType.Type("HCloud::PrimaryIPPrices"))
94
121
  ActiveModel::Type.register(:private_net, HCloud::ResourceType.Type("HCloud::PrivateNet"))
122
+ ActiveModel::Type.register(:private_network, HCloud::ResourceType.Type("HCloud::PrivateNetwork"))
95
123
  ActiveModel::Type.register(:protection, HCloud::ResourceType.Type("HCloud::Protection"))
96
124
  ActiveModel::Type.register(:public_net, HCloud::ResourceType.Type("HCloud::PublicNet"))
125
+ ActiveModel::Type.register(:resource, HCloud::ResourceType::GenericType)
97
126
  ActiveModel::Type.register(:route, HCloud::ResourceType.Type("HCloud::Route"))
98
127
  ActiveModel::Type.register(:rule, HCloud::ResourceType.Type("HCloud::Rule"))
99
128
  ActiveModel::Type.register(:server, HCloud::ResourceType.Type("HCloud::Server"))
100
129
  ActiveModel::Type.register(:server_backup_price, HCloud::ResourceType.Type("HCloud::ServerBackupPrice"))
130
+ ActiveModel::Type.register(:server_protection, HCloud::ResourceType.Type("HCloud::ServerProtection"))
101
131
  ActiveModel::Type.register(:server_type, HCloud::ResourceType.Type("HCloud::ServerType"))
102
132
  ActiveModel::Type.register(:server_type_price, HCloud::ResourceType.Type("HCloud::ServerTypePrice"))
103
133
  ActiveModel::Type.register(:service, HCloud::ResourceType.Type("HCloud::Service"))
@@ -11,18 +11,18 @@ module HCloud
11
11
  #
12
12
  # == Sort actions
13
13
  #
14
- # HCloud::Action.all.sort(command: :desc)
14
+ # HCloud::Action.sort(command: :desc)
15
15
  # # => [#<HCloud::Action id: 1, ...>, ...]
16
16
  #
17
- # HCloud::Action.all.sort(:id, command: :asc)
17
+ # HCloud::Action.sort(:id, command: :asc)
18
18
  # # => [#<HCloud::Action id: 1, ...>, ...]
19
19
  #
20
20
  # == Search actions
21
21
  #
22
- # HCloud::Action.all.where(command: "my_action")
22
+ # HCloud::Action.where(command: "my_action")
23
23
  # # => #<HCloud::Action id: 1, ...>
24
24
  #
25
- # HCloud::Action.all.where(status: "success")
25
+ # HCloud::Action.where(status: "success")
26
26
  # # => #<HCloud::Action id: 1, ...>
27
27
  #
28
28
  # == Find action by ID
@@ -43,7 +43,6 @@ module HCloud
43
43
  attribute :status
44
44
  attribute :error, :error
45
45
 
46
- # TODO: return array of resources
47
- attribute :resources, array: true, default: -> { [] }
46
+ attribute :resources, :resource, array: true, default: -> { [] }
48
47
  end
49
48
  end
@@ -11,18 +11,21 @@ module HCloud
11
11
  #
12
12
  # == Sort certificates
13
13
  #
14
- # HCloud::Certificate.all.sort(name: :desc)
14
+ # HCloud::Certificate.sort(name: :desc)
15
15
  # # => [#<HCloud::Certificate id: 1, ...>, ...]
16
16
  #
17
- # HCloud::Certificate.all.sort(:id, name: :asc)
17
+ # HCloud::Certificate.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::Certificate id: 1, ...>, ...]
19
19
  #
20
20
  # == Search certificates
21
21
  #
22
- # HCloud::Certificate.all.where(name: "my_certificate")
22
+ # HCloud::Certificate.where(name: "my_certificate")
23
23
  # # => #<HCloud::Certificate id: 1, ...>
24
24
  #
25
- # HCloud::Certificate.all.where(type: "uploaded")
25
+ # HCloud::Certificate.where(type: "uploaded")
26
+ # # => #<HCloud::Certificate id: 1, ...>
27
+ #
28
+ # HCloud::Certificate.where(label_selector: { environment: "production" })
26
29
  # # => #<HCloud::Certificate id: 1, ...>
27
30
  #
28
31
  # == Find certificate by ID
@@ -94,6 +97,7 @@ module HCloud
94
97
  creatable
95
98
  updatable
96
99
  deletable
100
+ labelable
97
101
 
98
102
  attribute :id, :integer
99
103
  attribute :name
@@ -116,8 +120,6 @@ module HCloud
116
120
  # TODO: dynamically return resource classes
117
121
  attribute :used_by, :used_by, array: true, default: -> { [] }
118
122
 
119
- attribute :labels, default: -> { {} }
120
-
121
123
  action :retry
122
124
 
123
125
  def creatable_attributes
@@ -11,7 +11,7 @@ module HCloud
11
11
  #
12
12
  # == Search datacenters
13
13
  #
14
- # HCloud::Datacenter.all.where(name: "fsn1-dc8")
14
+ # HCloud::Datacenter.where(name: "fsn1-dc8")
15
15
  # # => #<HCloud::Datacenter id: 2, ...>
16
16
  #
17
17
  # == Find datacenter by ID
@@ -11,15 +11,18 @@ module HCloud
11
11
  #
12
12
  # == Sort firewalls
13
13
  #
14
- # HCloud::Firewall.all.sort(name: :desc)
14
+ # HCloud::Firewall.sort(name: :desc)
15
15
  # # => [#<HCloud::Firewall id: 1, ...>, ...]
16
16
  #
17
- # HCloud::Firewall.all.sort(:id, name: :asc)
17
+ # HCloud::Firewall.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::Firewall id: 1, ...>, ...]
19
19
  #
20
20
  # == Search firewalls
21
21
  #
22
- # HCloud::Firewall.all.where(name: "my_firewall")
22
+ # HCloud::Firewall.where(name: "my_firewall")
23
+ # # => #<HCloud::Firewall id: 1, ...>
24
+ #
25
+ # HCloud::Firewall.where(label_selector: { environment: "production" })
23
26
  # # => #<HCloud::Firewall id: 1, ...>
24
27
  #
25
28
  # == Find firewall by ID
@@ -107,6 +110,7 @@ module HCloud
107
110
  creatable
108
111
  updatable
109
112
  deletable
113
+ labelable
110
114
 
111
115
  attribute :id, :integer
112
116
  attribute :name
@@ -117,8 +121,6 @@ module HCloud
117
121
 
118
122
  attribute :rules, :rule, array: true, default: -> { [] }
119
123
 
120
- attribute :labels, default: -> { {} }
121
-
122
124
  action :apply_to_resources
123
125
  action :remove_from_resources
124
126
  action :set_rules
@@ -11,15 +11,18 @@ module HCloud
11
11
  #
12
12
  # == Sort floating IPs
13
13
  #
14
- # HCloud::FloatingIP.all.sort(id: :asc)
14
+ # HCloud::FloatingIP.sort(id: :asc)
15
15
  # # => [#<HCloud::FloatingIP id: 1, ...>, ...]
16
16
  #
17
- # HCloud::FloatingIP.all.sort(:id, created: :asc)
17
+ # HCloud::FloatingIP.sort(:id, created: :asc)
18
18
  # # => [#<HCloud::FloatingIP id: 1, ...>, ...]
19
19
  #
20
20
  # == Search floating IPs
21
21
  #
22
- # HCloud::FloatingIP.all.where(name: "my_floating_ip")
22
+ # HCloud::FloatingIP.where(name: "my_floating_ip")
23
+ # # => #<HCloud::FloatingIP id: 1, ...>
24
+ #
25
+ # HCloud::FloatingIP.where(label_selector: { environment: "production" })
23
26
  # # => #<HCloud::FloatingIP id: 1, ...>
24
27
  #
25
28
  # == Find floating IP by ID
@@ -104,6 +107,7 @@ module HCloud
104
107
  creatable
105
108
  updatable
106
109
  deletable
110
+ labelable
107
111
 
108
112
  attribute :id, :integer
109
113
  attribute :name
@@ -121,8 +125,6 @@ module HCloud
121
125
 
122
126
  attribute :server, :server
123
127
 
124
- attribute :labels, default: -> { {} }
125
-
126
128
  alias blocked? blocked
127
129
 
128
130
  action :assign
@@ -11,21 +11,21 @@ module HCloud
11
11
  #
12
12
  # == Sort images
13
13
  #
14
- # HCloud::Image.all.sort(name: :desc)
14
+ # HCloud::Image.sort(name: :desc)
15
15
  # # => [#<HCloud::Image id: 1, ...>, ...]
16
16
  #
17
- # HCloud::Image.all.sort(:id, name: :asc)
17
+ # HCloud::Image.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::Image id: 1, ...>, ...]
19
19
  #
20
20
  # == Search images
21
21
  #
22
- # HCloud::Image.all.where(name: "my_image")
22
+ # HCloud::Image.where(name: "my_image")
23
23
  # # => #<HCloud::Image id: 1, ...>
24
24
  #
25
- # HCloud::Image.all.where(status: "available", include_deprecated: false)
25
+ # HCloud::Image.where(status: "available", include_deprecated: false)
26
26
  # # => #<HCloud::Image id: 1, ...>
27
27
  #
28
- # HCloud::Image.all.where(type: "backup", bound_to: 1)
28
+ # HCloud::Image.where(type: "backup", bound_to: 1)
29
29
  # # => #<HCloud::Image id: 1, ...>
30
30
  #
31
31
  # == Find image by ID
@@ -85,6 +85,7 @@ module HCloud
85
85
  queryable
86
86
  updatable
87
87
  deletable
88
+ labelable
88
89
 
89
90
  attribute :id, :integer
90
91
  attribute :name
@@ -113,8 +114,6 @@ module HCloud
113
114
 
114
115
  attribute :rapid_deploy
115
116
 
116
- attribute :labels, default: -> { {} }
117
-
118
117
  action :change_protection
119
118
 
120
119
  def created?
@@ -11,7 +11,7 @@ module HCloud
11
11
  #
12
12
  # == Search ISOs
13
13
  #
14
- # HCloud::ISO.all.where(name: "debian-10.10.0-amd64-netinst.iso")
14
+ # HCloud::ISO.where(name: "debian-10.10.0-amd64-netinst.iso")
15
15
  # # => #<HCloud::ISO id: 7631, ...>
16
16
  #
17
17
  # == Find ISO by ID
@@ -11,15 +11,18 @@ module HCloud
11
11
  #
12
12
  # == Sort load balancers
13
13
  #
14
- # HCloud::LoadBalancer.all.sort(name: :desc)
14
+ # HCloud::LoadBalancer.sort(name: :desc)
15
15
  # # => [#<HCloud::LoadBalancer id: 1, ...>, ...]
16
16
  #
17
- # HCloud::LoadBalancer.all.sort(:id, name: :asc)
17
+ # HCloud::LoadBalancer.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::LoadBalancer id: 1, ...>, ...]
19
19
  #
20
20
  # == Search load balancers
21
21
  #
22
- # HCloud::LoadBalancer.all.where(name: "my_load_balancer")
22
+ # HCloud::LoadBalancer.where(name: "my_load_balancer")
23
+ # # => #<HCloud::LoadBalancer id: 1, ...>
24
+ #
25
+ # HCloud::LoadBalancer.where(label_selector: { environment: "production" })
23
26
  # # => #<HCloud::LoadBalancer id: 1, ...>
24
27
  #
25
28
  # == Find load balancer by ID
@@ -65,6 +68,7 @@ module HCloud
65
68
  updatable
66
69
  deletable
67
70
  meterable
71
+ labelable
68
72
 
69
73
  attribute :id, :integer
70
74
  attribute :name
@@ -94,8 +98,6 @@ module HCloud
94
98
 
95
99
  attribute :protection, :protection
96
100
 
97
- attribute :labels, default: -> { {} }
98
-
99
101
  def creatable_attributes
100
102
  [:name, :labels, :algorithm, :network_zone, :public_interface, :services, :targets, load_balancer_type: [:id, :name], location: [:id, :name], network: [:id, :name]]
101
103
  end
@@ -11,7 +11,7 @@ module HCloud
11
11
  #
12
12
  # == Search load balancer types
13
13
  #
14
- # HCloud::LoadBalancerType.all.where(name: "cx11")
14
+ # HCloud::LoadBalancerType.where(name: "cx11")
15
15
  # # => #<HCloud::LoadBalancerType id: 1, ...>
16
16
  #
17
17
  # == Find load balancer type by ID
@@ -11,7 +11,7 @@ module HCloud
11
11
  #
12
12
  # == Search locations
13
13
  #
14
- # HCloud::Location.all.where(name: "fsn1")
14
+ # HCloud::Location.where(name: "fsn1")
15
15
  # # => #<HCloud::Location id: 1, ...>
16
16
  #
17
17
  # == Find location by ID
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Server metadata.
6
+ #
7
+ # This resource allows a Hetzner server to retrieve metadata about itself.
8
+ # It cannot be used outside of Hetzner servers.
9
+ #
10
+ # == Find metadata
11
+ #
12
+ # HCloud::Metadata.find
13
+ # # => #<HCloud::Metadata ...>
14
+ #
15
+ class Metadata < Resource
16
+ ENDPOINT = "https://169.254.169.254/hetzner/v1/metadata"
17
+
18
+ attribute :hostname
19
+ attribute :instance_id, :integer
20
+ attribute :public_ipv4
21
+ attribute :availability_zone
22
+ attribute :region
23
+
24
+ attribute :private_networks, :private_network, array: true, default: -> { [] }
25
+
26
+ def self.find
27
+ new(::HTTP
28
+ .get(ENDPOINT)
29
+ .parse(:yaml)
30
+ .deep_transform_keys { |key| key.underscore.to_sym })
31
+ end
32
+ end
33
+ end
@@ -11,7 +11,10 @@ module HCloud
11
11
  #
12
12
  # == Search networks
13
13
  #
14
- # HCloud::Network.all.where(name: "my_network")
14
+ # HCloud::Network.where(name: "my_network")
15
+ # # => #<HCloud::Network id: 1, ...>
16
+ #
17
+ # HCloud::Network.where(label_selector: { environment: "production" })
15
18
  # # => #<HCloud::Network id: 1, ...>
16
19
  #
17
20
  # == Find network by ID
@@ -106,6 +109,7 @@ module HCloud
106
109
  creatable
107
110
  updatable
108
111
  deletable
112
+ labelable
109
113
 
110
114
  attribute :id, :integer
111
115
  attribute :name
@@ -121,8 +125,6 @@ module HCloud
121
125
 
122
126
  attribute :protection, :protection
123
127
 
124
- attribute :labels, default: -> { {} }
125
-
126
128
  action :change_protection
127
129
 
128
130
  action :add_route
@@ -11,15 +11,18 @@ module HCloud
11
11
  #
12
12
  # == Sort placement groups
13
13
  #
14
- # HCloud::PlacementGroup.all.sort(name: :desc)
14
+ # HCloud::PlacementGroup.sort(name: :desc)
15
15
  # # => [#<HCloud::PlacementGroup id: 1, ...>, ...]
16
16
  #
17
- # HCloud::PlacementGroup.all.sort(:id, name: :asc)
17
+ # HCloud::PlacementGroup.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::PlacementGroup id: 1, ...>, ...]
19
19
  #
20
20
  # == Search placement groups
21
21
  #
22
- # HCloud::PlacementGroup.all.where(name: "my_placement_group")
22
+ # HCloud::PlacementGroup.where(name: "my_placement_group")
23
+ # # => #<HCloud::PlacementGroup id: 2, ...>
24
+ #
25
+ # HCloud::PlacementGroup.where(label_selector: { environment: "production" })
23
26
  # # => #<HCloud::PlacementGroup id: 2, ...>
24
27
  #
25
28
  # == Find placement group by ID
@@ -55,6 +58,7 @@ module HCloud
55
58
  creatable
56
59
  updatable
57
60
  deletable
61
+ labelable
58
62
 
59
63
  attribute :id, :integer
60
64
  attribute :name
@@ -62,8 +66,6 @@ module HCloud
62
66
 
63
67
  attribute :servers, :server, array: true, default: -> { [] }
64
68
 
65
- attribute :labels, default: -> { {} }
66
-
67
69
  def creatable_attributes
68
70
  [:name, :type, :labels]
69
71
  end
@@ -21,6 +21,8 @@ module HCloud
21
21
 
22
22
  attribute :load_balancer_types, :load_balancer_type_price, array: true, default: -> { [] }
23
23
 
24
+ attribute :primary_ips, :primary_ip_prices, array: true, default: -> { [] }
25
+
24
26
  attribute :server_backup, :server_backup_price
25
27
 
26
28
  attribute :server_types, :server_type_price, array: true, default: -> { [] }
@@ -11,18 +11,21 @@ module HCloud
11
11
  #
12
12
  # == Sort primary IPs
13
13
  #
14
- # HCloud::PrimaryIP.all.sort(id: :asc)
14
+ # HCloud::PrimaryIP.sort(id: :asc)
15
15
  # # => [#<HCloud::PrimaryIP id: 1, ...>, ...]
16
16
  #
17
- # HCloud::PrimaryIP.all.sort(:id, created: :asc)
17
+ # HCloud::PrimaryIP.sort(:id, created: :asc)
18
18
  # # => [#<HCloud::PrimaryIP id: 1, ...>, ...]
19
19
  #
20
20
  # == Search primary IPs
21
21
  #
22
- # HCloud::PrimaryIP.all.where(name: "my_primary_ip")
22
+ # HCloud::PrimaryIP.where(name: "my_primary_ip")
23
23
  # # => #<HCloud::PrimaryIP id: 1, ...>
24
24
  #
25
- # HCloud::PrimaryIP.all.where(ip: "1.2.3.4")
25
+ # HCloud::PrimaryIP.where(ip: "1.2.3.4")
26
+ # # => #<HCloud::PrimaryIP id: 1, ...>
27
+ #
28
+ # HCloud::PrimaryIP.where(label_selector: { environment: "production" })
26
29
  # # => #<HCloud::PrimaryIP id: 1, ...>
27
30
  #
28
31
  # == Find primary IP by ID
@@ -107,6 +110,7 @@ module HCloud
107
110
  creatable
108
111
  updatable
109
112
  deletable
113
+ labelable
110
114
 
111
115
  attribute :id, :integer
112
116
  attribute :name
@@ -125,8 +129,6 @@ module HCloud
125
129
 
126
130
  attribute :protection, :protection
127
131
 
128
- attribute :labels, default: -> { {} }
129
-
130
132
  alias auto_delete? auto_delete
131
133
  alias blocked? blocked
132
134
 
@@ -11,18 +11,21 @@ module HCloud
11
11
  #
12
12
  # == Sort servers
13
13
  #
14
- # HCloud::Server.all.sort(name: :desc)
14
+ # HCloud::Server.sort(name: :desc)
15
15
  # # => [#<HCloud::Server id: 1, ...>, ...]
16
16
  #
17
- # HCloud::Server.all.sort(:id, name: :asc)
17
+ # HCloud::Server.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::Server id: 1, ...>, ...]
19
19
  #
20
20
  # == Search servers
21
21
  #
22
- # HCloud::Server.all.where(name: "my_server")
22
+ # HCloud::Server.where(name: "my_server")
23
23
  # # => #<HCloud::Server id: 1, ...>
24
24
  #
25
- # HCloud::Server.all.where(status: "running")
25
+ # HCloud::Server.where(status: "running")
26
+ # # => #<HCloud::Server id: 1, ...>
27
+ #
28
+ # HCloud::Server.where(label_selector: { environment: "production" })
26
29
  # # => #<HCloud::Server id: 1, ...>
27
30
  #
28
31
  # == Find server by ID
@@ -72,6 +75,7 @@ module HCloud
72
75
  updatable
73
76
  deletable
74
77
  meterable
78
+ labelable
75
79
 
76
80
  attribute :id, :integer
77
81
  attribute :name
@@ -107,7 +111,7 @@ module HCloud
107
111
 
108
112
  attribute :primary_disk_size, :integer
109
113
 
110
- attribute :protection, :protection
114
+ attribute :protection, :server_protection
111
115
 
112
116
  attribute :image, :image
113
117
 
@@ -118,8 +122,6 @@ module HCloud
118
122
 
119
123
  attribute :iso, :iso
120
124
 
121
- attribute :labels, default: -> { {} }
122
-
123
125
  attribute :load_balancers, :load_balancer, array: true, default: -> { [] }
124
126
 
125
127
  attribute :volumes, :volume, array: true, default: -> { [] }
@@ -11,7 +11,7 @@ module HCloud
11
11
  #
12
12
  # == Search server types
13
13
  #
14
- # HCloud::ServerType.all.where(name: "cx11")
14
+ # HCloud::ServerType.where(name: "cx11")
15
15
  # # => #<HCloud::ServerType id: 1, ...>
16
16
  #
17
17
  # == Find server type by ID
@@ -11,18 +11,21 @@ module HCloud
11
11
  #
12
12
  # == Sort SSH keys
13
13
  #
14
- # HCloud::SSHKey.all.sort(name: :desc)
14
+ # HCloud::SSHKey.sort(name: :desc)
15
15
  # # => [#<HCloud::SSHKey id: 1, ...>, ...]
16
16
  #
17
- # HCloud::SSHKey.all.sort(:id, name: :asc)
17
+ # HCloud::SSHKey.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::SSHKey id: 1, ...>, ...]
19
19
  #
20
20
  # == Search SSH keys
21
21
  #
22
- # HCloud::SSHKey.all.where(name: "cx11")
22
+ # HCloud::SSHKey.where(name: "cx11")
23
23
  # # => #<HCloud::SSHKey id: 1, ...>
24
24
  #
25
- # HCloud::SSHKey.all.where(fingerprint: "B6:6C:CD:DA:A2:24:43:39:98:80:0F:F5:51:17:7E")
25
+ # HCloud::SSHKey.where(fingerprint: "B6:6C:CD:DA:A2:24:43:39:98:80:0F:F5:51:17:7E")
26
+ # # => #<HCloud::SSHKey id: 1, ...>
27
+ #
28
+ # HCloud::SSHKey.where(label_selector: { environment: "production" })
26
29
  # # => #<HCloud::SSHKey id: 1, ...>
27
30
  #
28
31
  # == Find SSH key by ID
@@ -58,14 +61,13 @@ module HCloud
58
61
  creatable
59
62
  updatable
60
63
  deletable
64
+ labelable
61
65
 
62
66
  attribute :id, :integer
63
67
  attribute :name
64
68
  attribute :public_key
65
69
  attribute :fingerprint
66
70
 
67
- attribute :labels, default: -> { {} }
68
-
69
71
  def creatable_attributes
70
72
  [:name, :public_key, :labels]
71
73
  end
@@ -11,18 +11,21 @@ module HCloud
11
11
  #
12
12
  # == Sort volumes
13
13
  #
14
- # HCloud::Volume.all.sort(name: :desc)
14
+ # HCloud::Volume.sort(name: :desc)
15
15
  # # => [#<HCloud::Volume id: 1, ...>, ...]
16
16
  #
17
- # HCloud::Volume.all.sort(:id, name: :asc)
17
+ # HCloud::Volume.sort(:id, name: :asc)
18
18
  # # => [#<HCloud::Volume id: 1, ...>, ...]
19
19
  #
20
20
  # == Search volumes
21
21
  #
22
- # HCloud::Volume.all.where(name: "my_volume")
22
+ # HCloud::Volume.where(name: "my_volume")
23
23
  # # => #<HCloud::Volume id: 1, ...>
24
24
  #
25
- # HCloud::Volume.all.where(status: "available")
25
+ # HCloud::Volume.where(status: "available")
26
+ # # => #<HCloud::Volume id: 1, ...>
27
+ #
28
+ # HCloud::Volume.where(label_selector: { environment: "production" })
26
29
  # # => #<HCloud::Volume id: 1, ...>
27
30
  #
28
31
  # == Find volume by ID
@@ -107,6 +110,7 @@ module HCloud
107
110
  creatable
108
111
  updatable
109
112
  deletable
113
+ labelable
110
114
 
111
115
  attribute :id, :integer
112
116
  attribute :name
@@ -124,8 +128,6 @@ module HCloud
124
128
 
125
129
  attribute :server, :server
126
130
 
127
- attribute :labels, default: -> { {} }
128
-
129
131
  alias automount? automount
130
132
 
131
133
  action :attach
@@ -3,7 +3,7 @@
3
3
  module HCloud
4
4
  module Version
5
5
  MAJOR = 1
6
- MINOR = 4
6
+ MINOR = 5
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module HTTP
6
+ module MimeType
7
+ class YAML < Adapter
8
+ def encode(obj)
9
+ return obj.to_yaml if obj.respond_to?(:to_yaml)
10
+
11
+ ::YAML.dump(obj)
12
+ end
13
+
14
+ # Decodes JSON
15
+ def decode(str)
16
+ ::YAML.safe_load(str)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ HTTP::MimeType.register_adapter "application/x-yaml", HTTP::MimeType::YAML
23
+ HTTP::MimeType.register_alias "application/x-yaml", :yaml
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTTP
4
+ class RateLimiter < Feature
5
+ attr_reader :limit, :remaining, :reset, :at, :rate
6
+
7
+ def initialize(...)
8
+ super
9
+
10
+ @limit = Float::INFINITY
11
+ @remaining = Float::INFINITY
12
+ @reset = Time.at(0)
13
+ @at = Time.at(0)
14
+ @rate = 1
15
+ end
16
+
17
+ def wrap_request(request)
18
+ sleep rate while remaining.zero? && (at + rate).future?
19
+
20
+ request
21
+ end
22
+
23
+ def wrap_response(response)
24
+ # Extract rate limits
25
+ @limit = response["RateLimit-Limit"].to_i
26
+ @remaining = response["RateLimit-Remaining"].to_i
27
+ @reset = Time.at(response["RateLimit-Reset"].to_i)
28
+
29
+ # Extract request date
30
+ @at = Time.parse(response.headers["Date"])
31
+
32
+ # Calculate remaining increment rate
33
+ @rate = 3600 / limit
34
+
35
+ response
36
+ end
37
+ end
38
+ end
39
+
40
+ HTTP::Options.register_feature(:rate_limiter, HTTP::RateLimiter)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hetznercloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Dejonckheere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-22 00:00:00.000000000 Z
11
+ date: 2023-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -66,132 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: byebug
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: dotenv
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: ffaker
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: rake
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rspec
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: rubocop-performance
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: rubocop-rspec
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: webmock
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
69
  description: Native Ruby integration with the Hetzner Cloud API
196
70
  email:
197
71
  - florian@floriandejonckheere.be
@@ -213,6 +87,7 @@ files:
213
87
  - lib/hcloud/concerns/concerns.rb
214
88
  - lib/hcloud/concerns/creatable.rb
215
89
  - lib/hcloud/concerns/deletable.rb
90
+ - lib/hcloud/concerns/labelable.rb
216
91
  - lib/hcloud/concerns/meterable.rb
217
92
  - lib/hcloud/concerns/queryable.rb
218
93
  - lib/hcloud/concerns/singleton.rb
@@ -240,12 +115,15 @@ files:
240
115
  - lib/hcloud/entities/load_balancer_type_price.rb
241
116
  - lib/hcloud/entities/metrics.rb
242
117
  - lib/hcloud/entities/price.rb
118
+ - lib/hcloud/entities/primary_ip_prices.rb
243
119
  - lib/hcloud/entities/private_net.rb
120
+ - lib/hcloud/entities/private_network.rb
244
121
  - lib/hcloud/entities/protection.rb
245
122
  - lib/hcloud/entities/public_net.rb
246
123
  - lib/hcloud/entities/route.rb
247
124
  - lib/hcloud/entities/rule.rb
248
125
  - lib/hcloud/entities/server_backup_price.rb
126
+ - lib/hcloud/entities/server_protection.rb
249
127
  - lib/hcloud/entities/server_type_price.rb
250
128
  - lib/hcloud/entities/service.rb
251
129
  - lib/hcloud/entities/service_http.rb
@@ -272,6 +150,7 @@ files:
272
150
  - lib/hcloud/resources/load_balancer.rb
273
151
  - lib/hcloud/resources/load_balancer_type.rb
274
152
  - lib/hcloud/resources/location.rb
153
+ - lib/hcloud/resources/metadata.rb
275
154
  - lib/hcloud/resources/network.rb
276
155
  - lib/hcloud/resources/placement_group.rb
277
156
  - lib/hcloud/resources/pricing.rb
@@ -281,6 +160,8 @@ files:
281
160
  - lib/hcloud/resources/ssh_key.rb
282
161
  - lib/hcloud/resources/volume.rb
283
162
  - lib/hcloud/version.rb
163
+ - lib/http/mime_type/yaml.rb
164
+ - lib/http/rate_limiter.rb
284
165
  homepage: https://github.com/floriandejonckheere/hcloud
285
166
  licenses:
286
167
  - MIT