hetznercloud 1.4.0 → 1.5.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 (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