hetznercloud 1.0.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/README.md +32 -8
  4. data/config/inflections.rb +12 -3
  5. data/lib/core_ext/send_wrap.rb +11 -4
  6. data/lib/hcloud/concerns/actionable.rb +9 -2
  7. data/lib/hcloud/concerns/concerns.rb +8 -0
  8. data/lib/hcloud/concerns/creatable.rb +3 -2
  9. data/lib/hcloud/concerns/deletable.rb +2 -0
  10. data/lib/hcloud/concerns/meterable.rb +17 -0
  11. data/lib/hcloud/concerns/queryable.rb +4 -0
  12. data/lib/hcloud/concerns/singleton.rb +25 -0
  13. data/lib/hcloud/concerns/updatable.rb +2 -0
  14. data/lib/hcloud/entities/algorithm.rb +7 -0
  15. data/lib/hcloud/entities/certificate_status.rb +9 -0
  16. data/lib/hcloud/entities/floating_ip_price.rb +7 -0
  17. data/lib/hcloud/entities/floating_ip_prices.rb +8 -0
  18. data/lib/hcloud/entities/health_check.rb +12 -0
  19. data/lib/hcloud/entities/health_check_http.rb +13 -0
  20. data/lib/hcloud/entities/health_status.rb +8 -0
  21. data/lib/hcloud/entities/image_price.rb +7 -0
  22. data/lib/hcloud/entities/ipv4.rb +12 -0
  23. data/lib/hcloud/entities/ipv6.rb +12 -0
  24. data/lib/hcloud/entities/label_selector.rb +7 -0
  25. data/lib/hcloud/entities/load_balancer_private_net.rb +8 -0
  26. data/lib/hcloud/entities/load_balancer_public_net.rb +11 -0
  27. data/lib/hcloud/entities/load_balancer_type_price.rb +9 -0
  28. data/lib/hcloud/entities/private_net.rb +10 -0
  29. data/lib/hcloud/entities/public_net.rb +10 -0
  30. data/lib/hcloud/entities/route.rb +8 -0
  31. data/lib/hcloud/entities/server_backup_price.rb +7 -0
  32. data/lib/hcloud/entities/server_type_price.rb +9 -0
  33. data/lib/hcloud/entities/service.rb +16 -0
  34. data/lib/hcloud/entities/service_http.rb +16 -0
  35. data/lib/hcloud/entities/subnet.rb +11 -0
  36. data/lib/hcloud/entities/target.rb +15 -0
  37. data/lib/hcloud/entities/target_ip.rb +7 -0
  38. data/lib/hcloud/entities/target_target.rb +15 -0
  39. data/lib/hcloud/entities/targets.rb +13 -0
  40. data/lib/hcloud/entities/traffic_price.rb +7 -0
  41. data/lib/hcloud/entities/used_by.rb +8 -0
  42. data/lib/hcloud/entities/volume_price.rb +7 -0
  43. data/lib/hcloud/entity.rb +1 -0
  44. data/lib/hcloud/errors.rb +32 -2
  45. data/lib/hcloud/http.rb +12 -4
  46. data/lib/hcloud/resource_type.rb +41 -2
  47. data/lib/hcloud/resources/certificate.rb +131 -0
  48. data/lib/hcloud/resources/firewall.rb +57 -3
  49. data/lib/hcloud/resources/floating_ip.rb +2 -3
  50. data/lib/hcloud/resources/image.rb +1 -1
  51. data/lib/hcloud/resources/load_balancer.rb +107 -0
  52. data/lib/hcloud/resources/load_balancer_type.rb +38 -0
  53. data/lib/hcloud/resources/network.rb +142 -0
  54. data/lib/hcloud/resources/pricing.rb +34 -0
  55. data/lib/hcloud/resources/server.rb +12 -15
  56. data/lib/hcloud/resources/volume.rb +4 -5
  57. data/lib/hcloud/version.rb +2 -2
  58. data/lib/hcloud.rb +0 -2
  59. metadata +38 -16
data/lib/hcloud/errors.rb CHANGED
@@ -2,15 +2,39 @@
2
2
 
3
3
  module HCloud
4
4
  module Errors
5
+ class Error < StandardError
6
+ attr_reader :data
7
+
8
+ def initialize(data = {})
9
+ @data = data
10
+
11
+ super [data[:message], full_messages&.join("\n")].compact.join("\n\n")
12
+ end
13
+
14
+ def full_messages
15
+ return unless data[:details]
16
+
17
+ data[:details][:fields].flat_map do |field|
18
+ Array(field.fetch(:messages, data[:message])).map do |detail|
19
+ "#{field[:name]} #{detail}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+
5
25
  class ActionFailed < Error; end
26
+ class CloudResourceIPNotAllowed < Error; end
6
27
  class Conflict < Error; end
7
- class Error < StandardError; end
28
+ class FirewallAlreadyApplied < Error; end
29
+ class FirewallAlreadyRemoved < Error; end
8
30
  class FirewallResourceNotFound < Error; end
9
31
  class Forbidden < Error; end
10
32
  class IPNotAvailable < Error; end
33
+ class IPNotOwned < Error; end
11
34
  class IncompatibleNetworkType < Error; end
12
35
  class InvalidInput < Error; end
13
36
  class JSONError < Error; end
37
+ class LoadBalancerNotAttachedToNetwork < Error; end
14
38
  class Locked < Error; end
15
39
  class Maintenance < Error; end
16
40
  class NetworksOverlap < Error; end
@@ -21,16 +45,22 @@ module HCloud
21
45
  class PlacementError < Error; end
22
46
  class Protected < Error; end
23
47
  class RateLimitExceeded < Error; end
48
+ class ResourceInUse < Error; end
24
49
  class ResourceLimitExceeded < Error; end
25
50
  class ResourceUnavailable < Error; end
26
- class ResourceInUse < Error; end
51
+ class RobotUnavailable < Error; end
27
52
  class ServerAlreadyAdded < Error; end
28
53
  class ServerAlreadyAttached < Error; end
29
54
  class ServerError < Error; end
55
+ class ServerNotAttachedToNetwork < Error; end
30
56
  class ServiceError < Error; end
57
+ class SourcePortAlreadyUsed < Error; end
58
+ class TargetAlreadyDefined < Error; end
31
59
  class TokenReadonly < Error; end
32
60
  class Unauthorized < Error; end
33
61
  class UniquenessError < Error; end
34
62
  class UnsupportedError < Error; end
63
+
64
+ class MissingIDError < Error; end
35
65
  end
36
66
  end
data/lib/hcloud/http.rb CHANGED
@@ -17,39 +17,45 @@ module HCloud
17
17
  response = http
18
18
  .get(url_for(path), params: transform_params(params))
19
19
 
20
+ raise Errors::ServerError, response if response.status.server_error?
21
+
20
22
  data = response
21
23
  .parse(:json)
22
24
  .deep_symbolize_keys
23
25
 
24
26
  return data if response.status.success?
25
27
 
26
- raise Errors.const_get(data.dig(:error, :code).camelize), data.dig(:error, :message)
28
+ raise Errors.const_get(data.dig(:error, :code).camelize), data[:error]
27
29
  end
28
30
 
29
31
  def put(path, body = {})
30
32
  response = http
31
33
  .put(url_for(path), json: body)
32
34
 
35
+ raise Errors::ServerError, response if response.status.server_error?
36
+
33
37
  data = response
34
38
  .parse(:json)
35
39
  .deep_symbolize_keys
36
40
 
37
41
  return data if response.status.success?
38
42
 
39
- raise Errors.const_get(data.dig(:error, :code).camelize), data.dig(:error, :message)
43
+ raise Errors.const_get(data.dig(:error, :code).camelize), data[:error]
40
44
  end
41
45
 
42
46
  def post(path, body = {})
43
47
  response = http
44
48
  .post(url_for(path), json: body)
45
49
 
50
+ raise Errors::ServerError, response if response.status.server_error?
51
+
46
52
  data = response
47
53
  .parse(:json)
48
54
  .deep_symbolize_keys
49
55
 
50
56
  return data if response.status.success?
51
57
 
52
- raise Errors.const_get(data.dig(:error, :code).camelize), data.dig(:error, :message)
58
+ raise Errors.const_get(data.dig(:error, :code).camelize), data[:error]
53
59
  end
54
60
 
55
61
  def delete(path)
@@ -58,11 +64,13 @@ module HCloud
58
64
 
59
65
  return if response.status.success?
60
66
 
67
+ raise Errors::ServerError, response if response.status.server_error?
68
+
61
69
  data = response
62
70
  .parse(:json)
63
71
  .deep_symbolize_keys
64
72
 
65
- raise Errors.const_get(data.dig(:error, :code).camelize), data.dig(:error, :message)
73
+ raise Errors.const_get(data.dig(:error, :code).camelize), data[:error]
66
74
  end
67
75
 
68
76
  private
@@ -19,8 +19,12 @@ module HCloud
19
19
  value
20
20
  when Integer # ID
21
21
  resource_class.new(id: value)
22
- when String # Name
23
- resource_class.new(name: value)
22
+ when String # Name or Type
23
+ if resource_class.attribute_names.include?("name")
24
+ resource_class.new(name: value)
25
+ else
26
+ resource_class.new(type: value)
27
+ end
24
28
  when Hash # Attribute hash
25
29
  resource_class.new(value)
26
30
  when Array # List
@@ -40,6 +44,8 @@ module HCloud
40
44
  def assert_valid_value(_); end
41
45
 
42
46
  # rubocop:disable Naming/MethodName
47
+ # Limitation: resource types cannot be nested, because the types
48
+ # are registered as soon as possible, and the modules may not exist yet.
43
49
  def self.Type(class_name)
44
50
  Class
45
51
  .new(ResourceType) { self.resource_class_name = class_name }
@@ -50,24 +56,57 @@ module HCloud
50
56
  end
51
57
 
52
58
  ActiveModel::Type.register(:action, HCloud::ResourceType.Type("HCloud::Action"))
59
+ ActiveModel::Type.register(:algorithm, HCloud::ResourceType.Type("HCloud::Algorithm"))
53
60
  ActiveModel::Type.register(:amount, HCloud::ResourceType.Type("HCloud::Amount"))
54
61
  ActiveModel::Type.register(:applied_to, HCloud::ResourceType.Type("HCloud::AppliedTo"))
55
62
  ActiveModel::Type.register(:applied_to_resource, HCloud::ResourceType.Type("HCloud::AppliedToResource"))
56
63
  ActiveModel::Type.register(:apply_to, HCloud::ResourceType.Type("HCloud::ApplyTo"))
64
+ ActiveModel::Type.register(:certificate, HCloud::ResourceType.Type("HCloud::Certificate"))
65
+ ActiveModel::Type.register(:certificate_status, HCloud::ResourceType.Type("HCloud::CertificateStatus"))
57
66
  ActiveModel::Type.register(:datacenter, HCloud::ResourceType.Type("HCloud::Datacenter"))
58
67
  ActiveModel::Type.register(:datacenter_server_type, HCloud::ResourceType.Type("HCloud::DatacenterServerType"))
59
68
  ActiveModel::Type.register(:dns_pointer, HCloud::ResourceType.Type("HCloud::DNSPointer"))
60
69
  ActiveModel::Type.register(:error, HCloud::ResourceType.Type("HCloud::Error"))
61
70
  ActiveModel::Type.register(:firewall, HCloud::ResourceType.Type("HCloud::Firewall"))
62
71
  ActiveModel::Type.register(:floating_ip, HCloud::ResourceType.Type("HCloud::FloatingIP"))
72
+ ActiveModel::Type.register(:floating_ip_price, HCloud::ResourceType.Type("HCloud::FloatingIPPrice"))
73
+ ActiveModel::Type.register(:floating_ip_prices, HCloud::ResourceType.Type("HCloud::FloatingIPPrices"))
74
+ ActiveModel::Type.register(:health_check, HCloud::ResourceType.Type("HCloud::HealthCheck"))
75
+ ActiveModel::Type.register(:health_check_http, HCloud::ResourceType.Type("HCloud::HealthCheckHTTP"))
76
+ ActiveModel::Type.register(:health_status, HCloud::ResourceType.Type("HCloud::HealthStatus"))
63
77
  ActiveModel::Type.register(:image, HCloud::ResourceType.Type("HCloud::Image"))
78
+ ActiveModel::Type.register(:image_price, HCloud::ResourceType.Type("HCloud::ImagePrice"))
79
+ ActiveModel::Type.register(:ipv4, HCloud::ResourceType.Type("HCloud::IPv4"))
80
+ ActiveModel::Type.register(:ipv6, HCloud::ResourceType.Type("HCloud::IPv6"))
64
81
  ActiveModel::Type.register(:iso, HCloud::ResourceType.Type("HCloud::ISO"))
82
+ ActiveModel::Type.register(:label_selector, HCloud::ResourceType.Type("HCloud::LabelSelector"))
83
+ ActiveModel::Type.register(:load_balancer, HCloud::ResourceType.Type("HCloud::LoadBalancer"))
84
+ ActiveModel::Type.register(:load_balancer_private_net, HCloud::ResourceType.Type("HCloud::LoadBalancerPrivateNet"))
85
+ ActiveModel::Type.register(:load_balancer_public_net, HCloud::ResourceType.Type("HCloud::LoadBalancerPublicNet"))
86
+ ActiveModel::Type.register(:load_balancer_type, HCloud::ResourceType.Type("HCloud::LoadBalancerType"))
87
+ ActiveModel::Type.register(:load_balancer_type_price, HCloud::ResourceType.Type("HCloud::LoadBalancerTypePrice"))
65
88
  ActiveModel::Type.register(:location, HCloud::ResourceType.Type("HCloud::Location"))
89
+ ActiveModel::Type.register(:network, HCloud::ResourceType.Type("HCloud::Network"))
66
90
  ActiveModel::Type.register(:placement_group, HCloud::ResourceType.Type("HCloud::PlacementGroup"))
67
91
  ActiveModel::Type.register(:price, HCloud::ResourceType.Type("HCloud::Price"))
92
+ ActiveModel::Type.register(:pricing, HCloud::ResourceType.Type("HCloud::Pricing"))
93
+ ActiveModel::Type.register(:private_net, HCloud::ResourceType.Type("HCloud::PrivateNet"))
68
94
  ActiveModel::Type.register(:protection, HCloud::ResourceType.Type("HCloud::Protection"))
95
+ ActiveModel::Type.register(:public_net, HCloud::ResourceType.Type("HCloud::PublicNet"))
96
+ ActiveModel::Type.register(:route, HCloud::ResourceType.Type("HCloud::Route"))
69
97
  ActiveModel::Type.register(:rule, HCloud::ResourceType.Type("HCloud::Rule"))
70
98
  ActiveModel::Type.register(:server, HCloud::ResourceType.Type("HCloud::Server"))
99
+ ActiveModel::Type.register(:server_backup_price, HCloud::ResourceType.Type("HCloud::ServerBackupPrice"))
71
100
  ActiveModel::Type.register(:server_type, HCloud::ResourceType.Type("HCloud::ServerType"))
101
+ ActiveModel::Type.register(:server_type_price, HCloud::ResourceType.Type("HCloud::ServerTypePrice"))
102
+ ActiveModel::Type.register(:service, HCloud::ResourceType.Type("HCloud::Service"))
103
+ ActiveModel::Type.register(:service_http, HCloud::ResourceType.Type("HCloud::ServiceHTTP"))
72
104
  ActiveModel::Type.register(:ssh_key, HCloud::ResourceType.Type("HCloud::SSHKey"))
105
+ ActiveModel::Type.register(:subnet, HCloud::ResourceType.Type("HCloud::Subnet"))
106
+ ActiveModel::Type.register(:target, HCloud::ResourceType.Type("HCloud::Target"))
107
+ ActiveModel::Type.register(:targets, HCloud::ResourceType.Type("HCloud::Targets"))
108
+ ActiveModel::Type.register(:target_ip, HCloud::ResourceType.Type("HCloud::TargetIP"))
109
+ ActiveModel::Type.register(:traffic_price, HCloud::ResourceType.Type("HCloud::TrafficPrice"))
110
+ ActiveModel::Type.register(:used_by, HCloud::ResourceType.Type("HCloud::UsedBy"))
73
111
  ActiveModel::Type.register(:volume, HCloud::ResourceType.Type("HCloud::Volume"))
112
+ ActiveModel::Type.register(:volume_price, HCloud::ResourceType.Type("HCloud::VolumePrice"))
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents a certificate
6
+ #
7
+ # == List all certificates
8
+ #
9
+ # HCloud::Certificate.all
10
+ # # => [#<HCloud::Certificate id: 1, ...>, ...]
11
+ #
12
+ # == Sort certificates
13
+ #
14
+ # HCloud::Certificate.all.sort(name: :desc)
15
+ # # => [#<HCloud::Certificate id: 1, ...>, ...]
16
+ #
17
+ # HCloud::Certificate.all.sort(:id, name: :asc)
18
+ # # => [#<HCloud::Certificate id: 1, ...>, ...]
19
+ #
20
+ # == Search certificates
21
+ #
22
+ # HCloud::Certificate.all.where(name: "my_certificate")
23
+ # # => #<HCloud::Certificate id: 1, ...>
24
+ #
25
+ # HCloud::Certificate.all.where(type: "uploaded")
26
+ # # => #<HCloud::Certificate id: 1, ...>
27
+ #
28
+ # == Find certificate by ID
29
+ #
30
+ # HCloud::Certificate.find(1)
31
+ # # => #<HCloud::Certificate id: 1, ...>
32
+ #
33
+ # == Create certificate
34
+ #
35
+ # certificate = HCloud::Certificate.new(name: "my_certificate", type: "managed", domain_names: ["example.com"])
36
+ # certificate.create
37
+ # certificate.created?
38
+ # # => true
39
+ #
40
+ # certificate = HCloud::Certificate.create(name: "my_certificate", type: "managed", domain_names: ["example.com"])
41
+ # # => #<HCloud::Certificate id: 1, ...>
42
+ #
43
+ # == Update certificate
44
+ #
45
+ # certificate = HCloud::Certificate.find(1)
46
+ # certificate.name = "another_certificate"
47
+ # certificate.update
48
+ #
49
+ # == Delete certificate
50
+ #
51
+ # certificate = HCloud::Certificate.find(1)
52
+ # certificate.delete
53
+ # certificate.deleted?
54
+ # # => true
55
+ #
56
+ # = Actions
57
+ # == List actions
58
+ #
59
+ # actions = HCloud::Certificate.find(1).actions
60
+ # # => [#<HCloud::Action id: 1, ...>, ...]
61
+ #
62
+ # == Sort actions
63
+ #
64
+ # HCloud::Certificate.find(1).actions.sort(finished: :desc)
65
+ # # => [#<HCloud::Action id: 1, ...>, ...]
66
+ #
67
+ # HCloud::Certificate.find(1).actions.sort(:command, finished: :asc)
68
+ # # => [#<HCloud::Actions id: 1, ...>, ...]
69
+ #
70
+ # == Search actions
71
+ #
72
+ # HCloud::Certificate.find(1).actions.where(command: "set_rules")
73
+ # # => #<HCloud::Action id: 1, ...>
74
+ #
75
+ # HCloud::Certificate.find(1).actions.where(status: "success")
76
+ # # => #<HCloud::Action id: 1, ...>
77
+ #
78
+ # == Find action by ID
79
+ #
80
+ # HCloud::Certificate.find(1).actions.find(1)
81
+ # # => #<HCloud::Action id: 1, ...>
82
+ #
83
+ # = Resource-specific actions
84
+ # == Retry issuance or renewal
85
+ #
86
+ # certificate = HCloud::Certificate.find(1)
87
+ #
88
+ # certificate.retry
89
+ # # => #<HCloud::Action ...>
90
+ #
91
+ class Certificate < Resource
92
+ actionable
93
+ queryable
94
+ creatable
95
+ updatable
96
+ deletable
97
+
98
+ attribute :id, :integer
99
+ attribute :name
100
+
101
+ attribute :type
102
+
103
+ attribute :certificate
104
+ attribute :fingerprint
105
+
106
+ # TODO: use only for creation
107
+ attribute :private_key
108
+
109
+ attribute :not_valid_before, :datetime
110
+ attribute :not_valid_after, :datetime
111
+
112
+ attribute :domain_names, array: true, default: -> { [] }
113
+
114
+ attribute :status, :certificate_status
115
+
116
+ # TODO: dynamically return resource classes
117
+ attribute :used_by, :used_by, array: true, default: -> { [] }
118
+
119
+ attribute :labels, default: -> { {} }
120
+
121
+ action :retry
122
+
123
+ def creatable_attributes
124
+ [:name, :labels, :type, :private_key, :certificate, :domain_names]
125
+ end
126
+
127
+ def updatable_attributes
128
+ [:name, :labels]
129
+ end
130
+ end
131
+ end
@@ -19,7 +19,7 @@ module HCloud
19
19
  #
20
20
  # == Search firewalls
21
21
  #
22
- # HCloud::Firewall.all.where(name: "my_irewall")
22
+ # HCloud::Firewall.all.where(name: "my_firewall")
23
23
  # # => #<HCloud::Firewall id: 1, ...>
24
24
  #
25
25
  # == Find firewall by ID
@@ -50,9 +50,59 @@ module HCloud
50
50
  # firewall.deleted?
51
51
  # # => true
52
52
  #
53
- # TODO: firewall actions
53
+ # = Actions
54
+ # == List actions
55
+ #
56
+ # actions = HCloud::Firewall.find(1).actions
57
+ # # => [#<HCloud::Action id: 1, ...>, ...]
58
+ #
59
+ # == Sort actions
60
+ #
61
+ # HCloud::Firewall.find(1).actions.sort(finished: :desc)
62
+ # # => [#<HCloud::Action id: 1, ...>, ...]
63
+ #
64
+ # HCloud::Firewall.find(1).actions.sort(:command, finished: :asc)
65
+ # # => [#<HCloud::Actions id: 1, ...>, ...]
66
+ #
67
+ # == Search actions
68
+ #
69
+ # HCloud::Firewall.find(1).actions.where(command: "set_rules")
70
+ # # => #<HCloud::Action id: 1, ...>
71
+ #
72
+ # HCloud::Firewall.find(1).actions.where(status: "success")
73
+ # # => #<HCloud::Action id: 1, ...>
74
+ #
75
+ # == Find action by ID
76
+ #
77
+ # HCloud::Firewall.find(1).actions.find(1)
78
+ # # => #<HCloud::Action id: 1, ...>
79
+ #
80
+ # = Resource-specific actions
81
+ # == Apply a firewall to resources
82
+ #
83
+ # firewall = HCloud::Firewall.find(1)
84
+ # server = HCloud::Server.find(1)
85
+ #
86
+ # firewall.apply_to_resources(apply_to: [{ type: "server", server: { id: server.id } }])
87
+ # # => #<HCloud::Action ...>
88
+ #
89
+ # == Remove a firewall from resources
90
+ #
91
+ # firewall = HCloud::Firewall.find(1)
92
+ # server = HCloud::Server.find(1)
93
+ #
94
+ # firewall.remove_from_resources(remove_from: [{ type: "server", server: { id: server.id } }])
95
+ # # => #<HCloud::Action ...>
96
+ #
97
+ # == Set firewall rules
98
+ #
99
+ # firewall = HCloud::Firewall.find(1)
100
+ #
101
+ # firewall.set_rules(rules: [{ direction: "in", protocol: "tcp", ... }])
102
+ # # => #<HCloud::Action ...>
54
103
  #
55
104
  class Firewall < Resource
105
+ actionable
56
106
  queryable
57
107
  creatable
58
108
  updatable
@@ -62,13 +112,17 @@ module HCloud
62
112
  attribute :name
63
113
 
64
114
  attribute :applied_to, :applied_to, array: true, default: -> { [] }
65
- # Only used for creation
115
+ # TODO: use only for creation
66
116
  attribute :apply_to, :apply_to, array: true, default: -> { [] }
67
117
 
68
118
  attribute :rules, :rule, array: true, default: -> { [] }
69
119
 
70
120
  attribute :labels, default: -> { {} }
71
121
 
122
+ action :apply_to_resources
123
+ action :remove_from_resources
124
+ action :set_rules
125
+
72
126
  def creatable_attributes
73
127
  [:name, :labels, :apply_to, :rules]
74
128
  end
@@ -77,7 +77,7 @@ module HCloud
77
77
  # HCloud::FloatingIP.find(1).actions.find(1)
78
78
  # # => #<HCloud::Action id: 1, ...>
79
79
  #
80
- # = Floating IP-specific actions
80
+ # = Resource-specific actions
81
81
  # == Assign a floating IP to a server
82
82
  #
83
83
  # HCloud::FloatingIP.find(1).assign(server: 1)
@@ -119,8 +119,7 @@ module HCloud
119
119
 
120
120
  attribute :protection, :protection
121
121
 
122
- # TODO: return Server object
123
- attribute :server, :integer
122
+ attribute :server, :server
124
123
 
125
124
  attribute :labels, default: -> { {} }
126
125
 
@@ -74,7 +74,7 @@ module HCloud
74
74
  # HCloud::Image.find(1).actions.find(1)
75
75
  # # => #<HCloud::Action id: 1, ...>
76
76
  #
77
- # = Image-specific actions
77
+ # = Resource-specific actions
78
78
  # == Change protection
79
79
  #
80
80
  # HCloud::Image.find(1).change_protection(delete: true)
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents a load balancer
6
+ #
7
+ # == List all load balancers
8
+ #
9
+ # HCloud::LoadBalancer.all
10
+ # # => [#<HCloud::LoadBalancer id: 1, ...>, ...]
11
+ #
12
+ # == Sort load balancers
13
+ #
14
+ # HCloud::LoadBalancer.all.sort(name: :desc)
15
+ # # => [#<HCloud::LoadBalancer id: 1, ...>, ...]
16
+ #
17
+ # HCloud::LoadBalancer.all.sort(:id, name: :asc)
18
+ # # => [#<HCloud::LoadBalancer id: 1, ...>, ...]
19
+ #
20
+ # == Search load balancers
21
+ #
22
+ # HCloud::LoadBalancer.all.where(name: "my_load_balancer")
23
+ # # => #<HCloud::LoadBalancer id: 1, ...>
24
+ #
25
+ # == Find load balancer by ID
26
+ #
27
+ # HCloud::LoadBalancer.find(1)
28
+ # # => #<HCloud::LoadBalancer id: 1, ...>
29
+ #
30
+ # == Create load balancer
31
+ #
32
+ # load_balancer = HCloud::LoadBalancer.new(name: "my_load_balancer", algorithm: { type: "round_robin" }, load_balancer_type: "lb11", location: "nbg1")
33
+ # load_balancer.create
34
+ # load_balancer.created?
35
+ # # => true
36
+ #
37
+ # load_balancer = HCloud::LoadBalancer.create(name: "my_load_balancer", algorithm: { type: "round_robin" }, load_balancer_type: "lb11", location: "nbg1")
38
+ # # => #<HCloud::LoadBalancer id: 1, ...>
39
+ #
40
+ # == Update load balancer
41
+ #
42
+ # load_balancer = HCloud::LoadBalancer.find(1)
43
+ # load_balancer.name = "another_load_balancer"
44
+ # load_balancer.update
45
+ #
46
+ # == Delete load balancer
47
+ #
48
+ # load_balancer = HCloud::LoadBalancer.find(1)
49
+ # load_balancer.delete
50
+ # load_balancer.deleted?
51
+ # # => true
52
+ #
53
+ # == Get metrics
54
+ #
55
+ # load_balancer = HCloud::LoadBalancer.find(1)
56
+ # load_balancer.metrics(type: :bandwidth, from: 2.minutes.ago, to: 1.minute.ago)
57
+ # # => #<HCloud::Metrics ...>
58
+ #
59
+ # load_balancer.metrics(type: [:connections_per_second, :requests_per_second], from: 2.minutes.ago, to: 1.minute.ago, step: 60)
60
+ # # => #<HCloud::Metrics ...>
61
+ #
62
+ class LoadBalancer < Resource
63
+ queryable
64
+ creatable
65
+ updatable
66
+ deletable
67
+ meterable
68
+
69
+ attribute :id, :integer
70
+ attribute :name
71
+
72
+ attribute :algorithm, :algorithm
73
+
74
+ attribute :included_traffic, :integer
75
+ attribute :ingoing_traffic, :integer
76
+ attribute :outgoing_traffic, :integer
77
+
78
+ attribute :load_balancer_type, :load_balancer_type
79
+
80
+ attribute :location, :location
81
+
82
+ # TODO: use only for creation
83
+ attribute :network_zone
84
+ # TODO: use only for creation
85
+ attribute :network, :network
86
+ # TODO: use only for creation
87
+ attribute :public_interface, :boolean
88
+
89
+ attribute :private_net, :load_balancer_private_net
90
+ attribute :public_net, :load_balancer_public_net
91
+
92
+ attribute :services, :service, array: true, default: -> { [] }
93
+ attribute :targets, :target, array: true, default: -> { [] }
94
+
95
+ attribute :protection, :protection
96
+
97
+ attribute :labels, default: -> { {} }
98
+
99
+ def creatable_attributes
100
+ [:name, :labels, :algorithm, :network_zone, :public_interface, :services, :targets, load_balancer_type: [:id, :name], location: [:id, :name], network: [:id, :name]]
101
+ end
102
+
103
+ def updatable_attributes
104
+ [:name, :labels]
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents a load balancer type
6
+ #
7
+ # == List all load balancer types
8
+ #
9
+ # HCloud::LoadBalancerType.all
10
+ # # => [#<HCloud::LoadBalancerType id: 1, ...>, ...]
11
+ #
12
+ # == Search load balancer types
13
+ #
14
+ # HCloud::LoadBalancerType.all.where(name: "cx11")
15
+ # # => #<HCloud::LoadBalancerType id: 1, ...>
16
+ #
17
+ # == Find load balancer type by ID
18
+ #
19
+ # HCloud::LoadBalancerType.find(1)
20
+ # # => #<HCloud::LoadBalancerType id: 1, ...>
21
+ #
22
+ class LoadBalancerType < Resource
23
+ queryable
24
+
25
+ attribute :id, :integer
26
+ attribute :name
27
+ attribute :description
28
+
29
+ attribute :max_assigned_certificates, :integer
30
+ attribute :max_connections, :integer
31
+ attribute :max_services, :integer
32
+ attribute :max_targets, :integer
33
+
34
+ attribute :prices, :price, array: true, default: -> { [] }
35
+
36
+ attribute :deprecated, :datetime
37
+ end
38
+ end