hetznercloud 1.4.0 → 1.5.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -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/errors.rb +1 -0
  16. data/lib/hcloud/http.rb +4 -2
  17. data/lib/hcloud/resource_type.rb +32 -2
  18. data/lib/hcloud/resources/action.rb +5 -6
  19. data/lib/hcloud/resources/certificate.rb +8 -6
  20. data/lib/hcloud/resources/datacenter.rb +1 -1
  21. data/lib/hcloud/resources/firewall.rb +7 -5
  22. data/lib/hcloud/resources/floating_ip.rb +7 -5
  23. data/lib/hcloud/resources/image.rb +6 -7
  24. data/lib/hcloud/resources/iso.rb +1 -1
  25. data/lib/hcloud/resources/load_balancer.rb +7 -5
  26. data/lib/hcloud/resources/load_balancer_type.rb +1 -1
  27. data/lib/hcloud/resources/location.rb +1 -1
  28. data/lib/hcloud/resources/metadata.rb +33 -0
  29. data/lib/hcloud/resources/network.rb +5 -3
  30. data/lib/hcloud/resources/placement_group.rb +7 -5
  31. data/lib/hcloud/resources/pricing.rb +2 -0
  32. data/lib/hcloud/resources/primary_ip.rb +8 -6
  33. data/lib/hcloud/resources/server.rb +9 -7
  34. data/lib/hcloud/resources/server_type.rb +2 -1
  35. data/lib/hcloud/resources/ssh_key.rb +8 -6
  36. data/lib/hcloud/resources/volume.rb +8 -6
  37. data/lib/hcloud/version.rb +2 -2
  38. data/lib/http/mime_type/yaml.rb +23 -0
  39. data/lib/http/rate_limiter.rb +40 -0
  40. 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: 3e5950847db8b1e523a027c3197efebbef0dbcf3cdece53d46817e8d22ebf90c
4
+ data.tar.gz: 0a142f83f2ea3ffbc104501082ac72a26986d46ace0964c70a147be945bf73fd
5
5
  SHA512:
6
- metadata.gz: 7a9971d0195c839594b88759d828dc04f98e36d37eab7880d27f4299f8266d2e37676eea3b60399440bed9240e6d39190dba0af75f2d32bfe78c5e42bb160cd5
7
- data.tar.gz: bbecc7998329638d8499d0a33c877cdc5857b2a94c80633672a874f6828cc69f29e67d8e3a618b21db5cd84d87cf66cecd2e2ee3ddcfa16db00f841394f0ea85
6
+ metadata.gz: a4de38d5d298b9b55611fac064b6bd5f6f0acff82e0286cae05195546a7d8e5b9d99bacdb58a7a03affec4bc22979baf59dfc7a54aca8107936ad22422ce0ab9
7
+ data.tar.gz: 1ff509622967a9c449e5db033090e3a599160fd7c3859acc32544793c2a6e0365821be729673ff75f85074188a3ce69abc11d37bafaec8254a134453d7c7e5e3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## HCloud v1.5.1 (2023-04-20)
4
+
5
+ - Add `Unavailable` error class
6
+ - Add `architecture` attribute to `ServerType`
7
+
8
+ ## HCloud v1.5.0 (2023-02-01)
9
+
10
+ - Add pricing for Primary IPs
11
+ - Add server Metadata resource
12
+ - Add support for rate limits
13
+ - `Action#resources` now returns a list of resources instead of a list of hashes
14
+ - Separate server protection entity from other protection entity (only server protection includes `rebuild`)
15
+ - Add shorthand methods for `.first`, `.last`, `.count`, `.where`, `.sort`, `.each`, and `.empty?` on resource
16
+ - Add `label_selector:` argument to `HCloud::Collection`
17
+
3
18
  ## HCloud v1.4.0 (2023-01-22)
4
19
 
5
20
  - 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/errors.rb CHANGED
@@ -66,6 +66,7 @@ module HCloud
66
66
  class TargetAlreadyDefined < Error; end
67
67
  class TokenReadonly < Error; end
68
68
  class Unauthorized < Error; end
69
+ class Unavailable < Error; end
69
70
  class UniquenessError < Error; end
70
71
  class UnsupportedError < Error; end
71
72
 
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?