hetznercloud 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +29 -5
  4. data/config/inflections.rb +5 -0
  5. data/lib/core_ext/send_wrap.rb +11 -4
  6. data/lib/hcloud/concerns/actionable.rb +2 -0
  7. data/lib/hcloud/concerns/concerns.rb +4 -0
  8. data/lib/hcloud/concerns/creatable.rb +2 -2
  9. data/lib/hcloud/concerns/deletable.rb +2 -0
  10. data/lib/hcloud/concerns/queryable.rb +4 -0
  11. data/lib/hcloud/concerns/singleton.rb +25 -0
  12. data/lib/hcloud/concerns/updatable.rb +2 -0
  13. data/lib/hcloud/entities/certificate_status.rb +9 -0
  14. data/lib/hcloud/entities/floating_ip_price.rb +7 -0
  15. data/lib/hcloud/entities/floating_ip_prices.rb +8 -0
  16. data/lib/hcloud/entities/image_price.rb +7 -0
  17. data/lib/hcloud/entities/ipv4.rb +12 -0
  18. data/lib/hcloud/entities/ipv6.rb +12 -0
  19. data/lib/hcloud/entities/load_balancer_type_price.rb +9 -0
  20. data/lib/hcloud/entities/private_net.rb +10 -0
  21. data/lib/hcloud/entities/public_net.rb +10 -0
  22. data/lib/hcloud/entities/route.rb +8 -0
  23. data/lib/hcloud/entities/server_backup_price.rb +7 -0
  24. data/lib/hcloud/entities/server_type_price.rb +9 -0
  25. data/lib/hcloud/entities/subnet.rb +11 -0
  26. data/lib/hcloud/entities/traffic_price.rb +7 -0
  27. data/lib/hcloud/entities/used_by.rb +8 -0
  28. data/lib/hcloud/entities/volume_price.rb +7 -0
  29. data/lib/hcloud/entity.rb +1 -0
  30. data/lib/hcloud/errors.rb +2 -0
  31. data/lib/hcloud/http.rb +8 -0
  32. data/lib/hcloud/resource_type.rb +21 -0
  33. data/lib/hcloud/resources/certificate.rb +131 -0
  34. data/lib/hcloud/resources/firewall.rb +29 -1
  35. data/lib/hcloud/resources/floating_ip.rb +2 -3
  36. data/lib/hcloud/resources/image.rb +1 -1
  37. data/lib/hcloud/resources/network.rb +143 -0
  38. data/lib/hcloud/resources/pricing.rb +34 -0
  39. data/lib/hcloud/resources/server.rb +2 -3
  40. data/lib/hcloud/resources/volume.rb +4 -5
  41. data/lib/hcloud/version.rb +1 -1
  42. data/lib/hcloud.rb +0 -2
  43. metadata +22 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96dedcad6852bc32b89ff4a0df8ee183ed6a8c49a88c840b06dc6c0cd075d255
4
- data.tar.gz: b5105539a02269441777a43e045b80d7400ff7674d88f28553a8105f19a8d8d2
3
+ metadata.gz: 7177e5022ba3e3023d0d5537ba6c1784e6b05dcd0e378cf134f937057842e134
4
+ data.tar.gz: 6e7610f8b00c41b91993bcae03f1685494510718b3f063cb16ccc26faaa956bc
5
5
  SHA512:
6
- metadata.gz: 20b1d95239793c7790db9ced2f88a3b44a6add5d553a4bf4e17420b6be2290af4fe452ae5146bb769395fb645b7526322c0d4c488e00280135bcc2128f6532b0
7
- data.tar.gz: 5a5834d0ba17683ca5679ef7413297cca66200747e2ce36f37e6175db7c68b194ff267b832351c369ef8aaf98a82865ec2f0326a2a203640572db44d282e8a92
6
+ metadata.gz: 01ca0bfe1c72a5a4d49a9c33e4c4b0d574d69879bac68b94de3ad435fce3b3fa90319285c30808c08b7bc87dac08b3a314ab81f3018aac7fd360167c3a69e322
7
+ data.tar.gz: 987eacdba19a6ba38de99242f2d54612c5432b9a0309b91193cc0f4b5f59d60aaa96daedda2d81301fc974f1a368c20660a74d06a37b74849139e647ae8d43c2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## HCloud v1.2.0
4
+
5
+ - Implemented Networks
6
+ - Implemented Network Actions
7
+ - Implemented Pricing
8
+ - Implemented Certificates
9
+ - Implemented Certificate Actions
10
+
3
11
  ## HCloud v1.1.0
4
12
 
5
13
  - Implemented Firewall Actions
data/README.md CHANGED
@@ -74,8 +74,8 @@ Not all Hetzner Cloud API endpoints have been implemented yet.
74
74
  | Resource | State |
75
75
  |-----------------------|-----------------------|
76
76
  | Actions | Implemented |
77
- | Certificates | Not implemented |
78
- | Certificate Actions | Not implemented |
77
+ | Certificates | Implemented |
78
+ | Certificate Actions | Implemented |
79
79
  | Datacenters | Implemented |
80
80
  | Firewalls | Implemented |
81
81
  | Firewall Actions | Implemented |
@@ -88,10 +88,10 @@ Not all Hetzner Cloud API endpoints have been implemented yet.
88
88
  | Load Balancer Actions | Not implemented |
89
89
  | Load Balancer Types | Not implemented |
90
90
  | Locations | Implemented |
91
- | Networks | Not implemented |
92
- | Network Actions | Not implemented |
91
+ | Networks | Implemented |
92
+ | Network Actions | Implemented |
93
93
  | Placement Groups | Implemented |
94
- | Pricing | Not implemented |
94
+ | Pricing | Implemented |
95
95
  | Servers | Partially implemented |
96
96
  | Server Actions | Not implemented |
97
97
  | Server Types | Implemented |
@@ -109,6 +109,30 @@ bundle exec rspec
109
109
  bundle exec rspec --tag integration
110
110
  ```
111
111
 
112
+ ## Debugging
113
+
114
+ ### Logging
115
+
116
+ When using the gem in your code, you can pass a `logger:` argument to `HCloud::Client`:
117
+
118
+ ```ruby
119
+ logger = Logger.new("log/http.log")
120
+ logger.level = :debug
121
+
122
+ client = HCloud::Client.new(access_token: "my_access_token", logger: logger)
123
+ ```
124
+
125
+ When executing the test suite, set `LOG_LEVEL` environment variable to `debug` in order to see HTTP requests.
126
+
127
+ ### Endpoint
128
+
129
+ `HCloud::Client` also accepts an alternate endpoint:
130
+
131
+
132
+ ```ruby
133
+ client = HCloud::Client.new(access_token: "my_access_token", endpoint: "https://myproxy/v1")
134
+ ```
135
+
112
136
  ## Releasing
113
137
 
114
138
  To release a new version, update the version number in `lib/hcloud/version.rb`, update the changelog, commit the files and create a git tag starting with `v`, and push it to the repository.
@@ -5,7 +5,12 @@ HCloud.loader.inflector.inflect(
5
5
  "hcloud" => "HCloud",
6
6
  "ssh_key" => "SSHKey",
7
7
  "floating_ip" => "FloatingIP",
8
+ "floating_ip_price" => "FloatingIPPrice",
9
+ "floating_ips" => "FloatingIPs",
10
+ "floating_ip_prices" => "FloatingIPPrices",
8
11
  "http" => "HTTP",
12
+ "ipv4" => "IPv4",
13
+ "ipv6" => "IPv6",
9
14
  "ip_not_available" => "IPNotAvailable",
10
15
  "iso" => "ISO",
11
16
  "iso_type" => "ISOType",
@@ -2,12 +2,19 @@
2
2
 
3
3
  module CoreExt
4
4
  module SendWrap
5
- # Send a message to self, or all objects contained in self (for enumerables)
5
+ # Send a message to self, or all objects contained in self (for arrays)
6
6
 
7
- # FIXME: { env: "prod" }.send_wrap(:try, :to_h) returns { env: nil }
7
+ # NOTE: { env: "prod" }.send_wrap(:try, :to_h) returns { env: nil }
8
+ # NOTE: ["example.com"].send_wrap(:try, to_h) return [nil]
9
+ # Use a block for the above cases:
10
+ # { env: "prod" }.send_wrap { |o| o.try(:to_h) || o }
8
11
 
9
- def send_wrap(method_name, ...)
10
- is_a?(Array) ? map { |v| v.send(method_name, ...) } : send(method_name, ...)
12
+ def send_wrap(...)
13
+ if is_a?(Array)
14
+ map { |v| block_given? ? yield(v) : v.send(...) }
15
+ else
16
+ block_given? ? yield(self) : send(...)
17
+ end
11
18
  end
12
19
  end
13
20
  end
@@ -19,6 +19,8 @@ module HCloud
19
19
  action_names << name.to_s
20
20
 
21
21
  define_method(name) do |**params|
22
+ raise Errors::MissingIDError unless id
23
+
22
24
  response = client
23
25
  .post("/#{resource_name.pluralize}/#{id}/actions/#{name}", params)
24
26
 
@@ -24,6 +24,10 @@ module HCloud
24
24
  def deletable
25
25
  include Deletable
26
26
  end
27
+
28
+ def singleton
29
+ include Singleton
30
+ end
27
31
  end
28
32
  end
29
33
  end
@@ -29,9 +29,9 @@ module HCloud
29
29
 
30
30
  attributes
31
31
  .slice(*simple_attributes.map(&:to_s))
32
- .transform_values { |v| v&.send_wrap(:try, :to_h) || v&.send_wrap(:to_s) }
32
+ .transform_values { |v| v&.send_wrap { |o| o.try(:to_h) || o } || v&.send_wrap(:to_s) }
33
33
  .merge(nested_attributes.reduce(&:merge)&.map { |k, v| [k.to_s, Array(v).filter_map { |w| send(k)&.send_wrap(w) }.first] }.to_h)
34
- .compact
34
+ .compact_blank
35
35
  end
36
36
  # rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
37
37
  end
@@ -6,6 +6,8 @@ module HCloud
6
6
 
7
7
  included do
8
8
  def delete
9
+ raise Errors::MissingIDError unless id
10
+
9
11
  client
10
12
  .delete("/#{resource_name.pluralize}/#{id}")
11
13
 
@@ -6,6 +6,8 @@ module HCloud
6
6
 
7
7
  included do
8
8
  def reload
9
+ raise Errors::MissingIDError unless id
10
+
9
11
  assign_attributes client
10
12
  .get("/#{resource_name.pluralize}/#{id}")
11
13
  .fetch(resource_name.to_sym)
@@ -16,6 +18,8 @@ module HCloud
16
18
 
17
19
  class_methods do
18
20
  def find(id)
21
+ raise Errors::MissingIDError unless id
22
+
19
23
  new client
20
24
  .get("/#{resource_name.pluralize}/#{id}")
21
25
  .fetch(resource_name.to_sym)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ module Singleton
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def reload
9
+ assign_attributes client
10
+ .get("/#{resource_name}")
11
+ .fetch(resource_name.to_sym)
12
+
13
+ self
14
+ end
15
+ end
16
+
17
+ class_methods do
18
+ def find
19
+ new client
20
+ .get("/#{resource_name}")
21
+ .fetch(resource_name.to_sym)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,6 +6,8 @@ module HCloud
6
6
 
7
7
  included do
8
8
  def update
9
+ raise Errors::MissingIDError unless id
10
+
9
11
  assign_attributes client
10
12
  .put("/#{resource_name.pluralize}/#{id}", updatable_params)
11
13
  .fetch(resource_name.to_sym)
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class CertificateStatus < Entity
5
+ attribute :error, :error
6
+ attribute :issuance
7
+ attribute :renewal
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class FloatingIPPrice < Entity
5
+ attribute :price_monthly, :amount
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class FloatingIPPrices < Entity
5
+ attribute :type
6
+ attribute :prices, :price
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ImagePrice < Entity
5
+ attribute :price_per_gb_month, :amount
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class IPv4 < Entity
5
+ attribute :blocked, :boolean
6
+ attribute :dns_ptr
7
+ attribute :id, :integer
8
+ attribute :ip
9
+
10
+ alias blocked? blocked
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class IPv6 < Entity
5
+ attribute :blocked, :boolean
6
+ attribute :dns_ptr, :dns_pointer, array: true, default: -> { [] }
7
+ attribute :id, :integer
8
+ attribute :ip
9
+
10
+ alias blocked? blocked
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class LoadBalancerTypePrice < Entity
5
+ attribute :id, :integer
6
+ attribute :name
7
+ attribute :prices, :price, array: true, default: -> { [] }
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class PrivateNet < Entity
5
+ attribute :alias_ips, array: true, default: -> { [] }
6
+ attribute :ip
7
+ attribute :mac_address
8
+ attribute :network, :network
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class PublicNet < Entity
5
+ attribute :firewalls, :firewall, array: true, default: -> { [] }
6
+ attribute :floating_ips, :floating_ip, array: true, default: -> { [] }
7
+ attribute :ipv4, :ipv4
8
+ attribute :ipv6, :ipv6
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Route < Entity
5
+ attribute :destination
6
+ attribute :gateway
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServerBackupPrice < Entity
5
+ attribute :percentage
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServerTypePrice < Entity
5
+ attribute :id, :integer
6
+ attribute :name
7
+ attribute :prices, :price, array: true, default: -> { [] }
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Subnet < Entity
5
+ attribute :type
6
+ attribute :network_zone
7
+ attribute :gateway
8
+ attribute :ip_range
9
+ attribute :vswitch_id
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class TrafficPrice < Entity
5
+ attribute :price_per_tb, :amount
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class UsedBy < Entity
5
+ attribute :id, :integer
6
+ attribute :type
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class VolumePrice < Entity
5
+ attribute :price_per_gb_month, :amount
6
+ end
7
+ end
data/lib/hcloud/entity.rb CHANGED
@@ -18,6 +18,7 @@ module HCloud
18
18
  def to_h
19
19
  attributes
20
20
  .transform_values { |v| v.try(:to_h) || v }
21
+ .compact_blank
21
22
  end
22
23
  end
23
24
  end
data/lib/hcloud/errors.rb CHANGED
@@ -53,5 +53,7 @@ module HCloud
53
53
  class Unauthorized < Error; end
54
54
  class UniquenessError < Error; end
55
55
  class UnsupportedError < Error; end
56
+
57
+ class MissingIDError < Error; end
56
58
  end
57
59
  end
data/lib/hcloud/http.rb CHANGED
@@ -17,6 +17,8 @@ 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
@@ -30,6 +32,8 @@ module HCloud
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
@@ -43,6 +47,8 @@ module HCloud
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
@@ -58,6 +64,8 @@ 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
@@ -40,6 +40,8 @@ module HCloud
40
40
  def assert_valid_value(_); end
41
41
 
42
42
  # rubocop:disable Naming/MethodName
43
+ # Limitation: resource types cannot be nested, because the types
44
+ # are registered as soon as possible, and the modules may not exist yet.
43
45
  def self.Type(class_name)
44
46
  Class
45
47
  .new(ResourceType) { self.resource_class_name = class_name }
@@ -54,20 +56,39 @@ ActiveModel::Type.register(:amount, HCloud::ResourceType.Type("HCloud::Amount"))
54
56
  ActiveModel::Type.register(:applied_to, HCloud::ResourceType.Type("HCloud::AppliedTo"))
55
57
  ActiveModel::Type.register(:applied_to_resource, HCloud::ResourceType.Type("HCloud::AppliedToResource"))
56
58
  ActiveModel::Type.register(:apply_to, HCloud::ResourceType.Type("HCloud::ApplyTo"))
59
+ ActiveModel::Type.register(:certificate, HCloud::ResourceType.Type("HCloud::Certificate"))
60
+ ActiveModel::Type.register(:certificate_status, HCloud::ResourceType.Type("HCloud::CertificateStatus"))
57
61
  ActiveModel::Type.register(:datacenter, HCloud::ResourceType.Type("HCloud::Datacenter"))
58
62
  ActiveModel::Type.register(:datacenter_server_type, HCloud::ResourceType.Type("HCloud::DatacenterServerType"))
59
63
  ActiveModel::Type.register(:dns_pointer, HCloud::ResourceType.Type("HCloud::DNSPointer"))
60
64
  ActiveModel::Type.register(:error, HCloud::ResourceType.Type("HCloud::Error"))
61
65
  ActiveModel::Type.register(:firewall, HCloud::ResourceType.Type("HCloud::Firewall"))
62
66
  ActiveModel::Type.register(:floating_ip, HCloud::ResourceType.Type("HCloud::FloatingIP"))
67
+ ActiveModel::Type.register(:floating_ip_price, HCloud::ResourceType.Type("HCloud::FloatingIPPrice"))
68
+ ActiveModel::Type.register(:floating_ip_prices, HCloud::ResourceType.Type("HCloud::FloatingIPPrices"))
63
69
  ActiveModel::Type.register(:image, HCloud::ResourceType.Type("HCloud::Image"))
70
+ ActiveModel::Type.register(:image_price, HCloud::ResourceType.Type("HCloud::ImagePrice"))
71
+ ActiveModel::Type.register(:ipv4, HCloud::ResourceType.Type("HCloud::IPv4"))
72
+ ActiveModel::Type.register(:ipv6, HCloud::ResourceType.Type("HCloud::IPv6"))
64
73
  ActiveModel::Type.register(:iso, HCloud::ResourceType.Type("HCloud::ISO"))
74
+ ActiveModel::Type.register(:load_balancer_type_price, HCloud::ResourceType.Type("HCloud::LoadBalancerTypePrice"))
65
75
  ActiveModel::Type.register(:location, HCloud::ResourceType.Type("HCloud::Location"))
76
+ ActiveModel::Type.register(:network, HCloud::ResourceType.Type("HCloud::Network"))
66
77
  ActiveModel::Type.register(:placement_group, HCloud::ResourceType.Type("HCloud::PlacementGroup"))
67
78
  ActiveModel::Type.register(:price, HCloud::ResourceType.Type("HCloud::Price"))
79
+ ActiveModel::Type.register(:pricing, HCloud::ResourceType.Type("HCloud::Pricing"))
80
+ ActiveModel::Type.register(:private_net, HCloud::ResourceType.Type("HCloud::PrivateNet"))
68
81
  ActiveModel::Type.register(:protection, HCloud::ResourceType.Type("HCloud::Protection"))
82
+ ActiveModel::Type.register(:public_net, HCloud::ResourceType.Type("HCloud::PublicNet"))
83
+ ActiveModel::Type.register(:route, HCloud::ResourceType.Type("HCloud::Route"))
69
84
  ActiveModel::Type.register(:rule, HCloud::ResourceType.Type("HCloud::Rule"))
70
85
  ActiveModel::Type.register(:server, HCloud::ResourceType.Type("HCloud::Server"))
86
+ ActiveModel::Type.register(:server_backup_price, HCloud::ResourceType.Type("HCloud::ServerBackupPrice"))
71
87
  ActiveModel::Type.register(:server_type, HCloud::ResourceType.Type("HCloud::ServerType"))
88
+ ActiveModel::Type.register(:server_type_price, HCloud::ResourceType.Type("HCloud::ServerTypePrice"))
72
89
  ActiveModel::Type.register(:ssh_key, HCloud::ResourceType.Type("HCloud::SSHKey"))
90
+ ActiveModel::Type.register(:subnet, HCloud::ResourceType.Type("HCloud::Subnet"))
91
+ ActiveModel::Type.register(:traffic_price, HCloud::ResourceType.Type("HCloud::TrafficPrice"))
92
+ ActiveModel::Type.register(:used_by, HCloud::ResourceType.Type("HCloud::UsedBy"))
73
93
  ActiveModel::Type.register(:volume, HCloud::ResourceType.Type("HCloud::Volume"))
94
+ 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,6 +50,34 @@ module HCloud
50
50
  # firewall.deleted?
51
51
  # # => true
52
52
  #
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
53
81
  # == Apply a firewall to resources
54
82
  #
55
83
  # firewall = HCloud::Firewall.find(1)
@@ -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,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents a network
6
+ #
7
+ # == List all networks
8
+ #
9
+ # HCloud::Network.all
10
+ # # => [#<HCloud::Network id: 1, ...>, ...]
11
+ #
12
+ # == Search networks
13
+ #
14
+ # HCloud::Network.all.where(name: "my_network")
15
+ # # => #<HCloud::Network id: 1, ...>
16
+ #
17
+ # == Find network by ID
18
+ #
19
+ # HCloud::Network.find(1)
20
+ # # => #<HCloud::Network id: 1, ...>
21
+ #
22
+ # == Create network
23
+ #
24
+ # network = HCloud::Network.new(name: "my_network", ip_range: "10.0.0.0/16")
25
+ # network.create
26
+ # network.created?
27
+ # # => true
28
+ #
29
+ # network = HCloud::Network.create(name: "my_network", ip_range: "10.0.0.0/16")
30
+ # # => #<HCloud::Network id: 1, ...>
31
+ #
32
+ # == Update network
33
+ #
34
+ # network = HCloud::Network.find(1)
35
+ # network.name = "another_network"
36
+ # network.update
37
+ #
38
+ # == Delete network
39
+ #
40
+ # network = HCloud::Network.find(1)
41
+ # network.delete
42
+ # network.deleted?
43
+ # # => true
44
+ #
45
+ # = Actions
46
+ # == List actions
47
+ #
48
+ # actions = HCloud::FloatingIP.find(1).actions
49
+ # # => [#<HCloud::Action id: 1, ...>, ...]
50
+ #
51
+ # == Sort actions
52
+ #
53
+ # HCloud::FloatingIP.find(1).actions.sort(finished: :desc)
54
+ # # => [#<HCloud::Action id: 1, ...>, ...]
55
+ #
56
+ # HCloud::FloatingIP.find(1).actions.sort(:command, finished: :asc)
57
+ # # => [#<HCloud::Actions id: 1, ...>, ...]
58
+ #
59
+ # == Search actions
60
+ #
61
+ # HCloud::FloatingIP.find(1).actions.where(command: "assign_floating_ip")
62
+ # # => #<HCloud::Action id: 1, ...>
63
+ #
64
+ # HCloud::FloatingIP.find(1).actions.where(status: "success")
65
+ # # => #<HCloud::Action id: 1, ...>
66
+ #
67
+ # == Find action by ID
68
+ #
69
+ # HCloud::FloatingIP.find(1).actions.find(1)
70
+ # # => #<HCloud::Action id: 1, ...>
71
+ #
72
+ # = Resource-specific actions
73
+ # == Change protection
74
+ #
75
+ # HCloud::Network.find(1).change_protection(delete: true)
76
+ # # => #<HCloud::Action id: 1, ...>
77
+ #
78
+ # == Add a route
79
+ #
80
+ # HCloud::Network.find(1).add_route(destination: "10.100.1.0/24", gateway: "10.0.1.1")
81
+ # # => #<HCloud::Action id: 1, ...>
82
+ #
83
+ # == Add a subnet
84
+ #
85
+ # HCloud::Network.find(1).add_subnet(ip_range: "10.0.1.0/24", network_zone: "eu-central", type: "cloud")
86
+ # # => #<HCloud::Action id: 1, ...>
87
+ #
88
+ # == Change the IP range
89
+ #
90
+ # HCloud::Network.find(1).change_ip_range(ip_range: "10.0.0.0/15")
91
+ # # => #<HCloud::Action id: 1, ...>
92
+ #
93
+ # == Delete a route
94
+ #
95
+ # HCloud::Network.find(1).delete_route(destination: "10.100.1.0/24", gateway: "10.0.1.1")
96
+ # # => #<HCloud::Action id: 1, ...>
97
+ #
98
+ # == Delete a subnet
99
+ #
100
+ # HCloud::Network.find(1).delete_subnet(ip_range: "10.0.1.0/24", network_zone: "eu-central", type: "cloud")
101
+ # # => #<HCloud::Action id: 1, ...>
102
+ #
103
+ class Network < Resource
104
+ actionable
105
+ queryable
106
+ creatable
107
+ updatable
108
+ deletable
109
+
110
+ attribute :id, :integer
111
+ attribute :name
112
+
113
+ attribute :ip_range
114
+
115
+ attribute :routes, :route, array: true, default: -> { [] }
116
+ attribute :subnets, :subnet, array: true, default: -> { [] }
117
+
118
+ attribute :servers, :server, array: true, default: -> { [] }
119
+
120
+ # TODO: load balancer resource
121
+ attribute :load_balancers, array: true, default: -> { [] }
122
+
123
+ attribute :protection, :protection
124
+
125
+ attribute :labels, default: -> { {} }
126
+
127
+ action :change_protection
128
+
129
+ action :add_route
130
+ action :add_subnet
131
+ action :change_ip_range
132
+ action :delete_route
133
+ action :delete_subnet
134
+
135
+ def creatable_attributes
136
+ [:name, :labels, :ip_range, :routes, :subnets]
137
+ end
138
+
139
+ def updatable_attributes
140
+ [:name, :labels]
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents pricing
6
+ #
7
+ # == Find pricing
8
+ #
9
+ # HCloud::Pricing.find
10
+ # # => #<HCloud::Pricing ...>
11
+ #
12
+ class Pricing < Resource
13
+ singleton
14
+
15
+ attribute :currency
16
+
17
+ attribute :floating_ip, :floating_ip_price
18
+ attribute :floating_ips, :floating_ip_prices, array: true, default: -> { [] }
19
+
20
+ attribute :image, :image_price
21
+
22
+ attribute :load_balancer_types, :load_balancer_type_price, array: true, default: -> { [] }
23
+
24
+ attribute :server_backup, :server_backup_price
25
+
26
+ attribute :server_types, :server_type_price, array: true, default: -> { [] }
27
+
28
+ attribute :traffic, :traffic_price
29
+
30
+ attribute :vat_rate
31
+
32
+ attribute :volume, :volume_price
33
+ end
34
+ end
@@ -106,9 +106,8 @@ module HCloud
106
106
 
107
107
  attribute :image, :image
108
108
 
109
- # TODO: network resource
110
- attribute :public_net
111
- attribute :private_net
109
+ attribute :public_net, :public_net
110
+ attribute :private_net, :private_net
112
111
 
113
112
  attribute :placement_group, :placement_group
114
113
 
@@ -80,10 +80,10 @@ module HCloud
80
80
  # HCloud::Volume.find(1).actions.find(1)
81
81
  # # => #<HCloud::Action id: 1, ...>
82
82
  #
83
- # = Volume-specific actions
83
+ # = Resource-specific actions
84
84
  # == Attach a volume to a server
85
85
  #
86
- # HCloud::Volume.find(1).attach(server: 1)
86
+ # HCloud::Volume.find(1).attach(server: 1, automount: false)
87
87
  # # => #<HCloud::Action id: 1, ...>
88
88
  #
89
89
  # == Detach a volume from a server
@@ -93,7 +93,7 @@ module HCloud
93
93
  #
94
94
  # == Resize volume
95
95
  #
96
- # HCloud::Volume.find(1).resize(size: 100)
96
+ # HCloud::Volume.find(1).resize(size: 25)
97
97
  # # => #<HCloud::Action id: 1, ...>
98
98
  #
99
99
  # == Change protection
@@ -122,8 +122,7 @@ module HCloud
122
122
  attribute :location, :location
123
123
  attribute :protection, :protection
124
124
 
125
- # TODO: return Server object
126
- attribute :server, :integer
125
+ attribute :server, :server
127
126
 
128
127
  attribute :labels, default: -> { {} }
129
128
 
@@ -3,7 +3,7 @@
3
3
  module HCloud
4
4
  module Version
5
5
  MAJOR = 1
6
- MINOR = 1
6
+ MINOR = 2
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
data/lib/hcloud.rb CHANGED
@@ -15,7 +15,6 @@ module HCloud
15
15
  @root ||= Pathname.new(File.expand_path(File.join("..", ".."), __FILE__))
16
16
  end
17
17
 
18
- # rubocop:disable Metrics/AbcSize
19
18
  def setup
20
19
  @loader = Zeitwerk::Loader.for_gem
21
20
 
@@ -35,7 +34,6 @@ module HCloud
35
34
  loader.setup
36
35
  loader.eager_load
37
36
  end
38
- # rubocop:enable Metrics/AbcSize
39
37
  end
40
38
  end
41
39
 
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.1.0
4
+ version: 1.2.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: 2022-01-30 00:00:00.000000000 Z
11
+ date: 2022-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: factory_bot
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
97
  - !ruby/object:Gem::Dependency
112
98
  name: ffaker
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -228,31 +214,51 @@ files:
228
214
  - lib/hcloud/concerns/creatable.rb
229
215
  - lib/hcloud/concerns/deletable.rb
230
216
  - lib/hcloud/concerns/queryable.rb
217
+ - lib/hcloud/concerns/singleton.rb
231
218
  - lib/hcloud/concerns/updatable.rb
232
219
  - lib/hcloud/entities/amount.rb
233
220
  - lib/hcloud/entities/applied_to.rb
234
221
  - lib/hcloud/entities/applied_to_resource.rb
235
222
  - lib/hcloud/entities/apply_to.rb
223
+ - lib/hcloud/entities/certificate_status.rb
236
224
  - lib/hcloud/entities/datacenter_server_type.rb
237
225
  - lib/hcloud/entities/dns_pointer.rb
238
226
  - lib/hcloud/entities/error.rb
227
+ - lib/hcloud/entities/floating_ip_price.rb
228
+ - lib/hcloud/entities/floating_ip_prices.rb
229
+ - lib/hcloud/entities/image_price.rb
230
+ - lib/hcloud/entities/ipv4.rb
231
+ - lib/hcloud/entities/ipv6.rb
232
+ - lib/hcloud/entities/load_balancer_type_price.rb
239
233
  - lib/hcloud/entities/metrics.rb
240
234
  - lib/hcloud/entities/price.rb
235
+ - lib/hcloud/entities/private_net.rb
241
236
  - lib/hcloud/entities/protection.rb
237
+ - lib/hcloud/entities/public_net.rb
238
+ - lib/hcloud/entities/route.rb
242
239
  - lib/hcloud/entities/rule.rb
240
+ - lib/hcloud/entities/server_backup_price.rb
241
+ - lib/hcloud/entities/server_type_price.rb
242
+ - lib/hcloud/entities/subnet.rb
243
+ - lib/hcloud/entities/traffic_price.rb
244
+ - lib/hcloud/entities/used_by.rb
245
+ - lib/hcloud/entities/volume_price.rb
243
246
  - lib/hcloud/entity.rb
244
247
  - lib/hcloud/errors.rb
245
248
  - lib/hcloud/http.rb
246
249
  - lib/hcloud/resource.rb
247
250
  - lib/hcloud/resource_type.rb
248
251
  - lib/hcloud/resources/action.rb
252
+ - lib/hcloud/resources/certificate.rb
249
253
  - lib/hcloud/resources/datacenter.rb
250
254
  - lib/hcloud/resources/firewall.rb
251
255
  - lib/hcloud/resources/floating_ip.rb
252
256
  - lib/hcloud/resources/image.rb
253
257
  - lib/hcloud/resources/iso.rb
254
258
  - lib/hcloud/resources/location.rb
259
+ - lib/hcloud/resources/network.rb
255
260
  - lib/hcloud/resources/placement_group.rb
261
+ - lib/hcloud/resources/pricing.rb
256
262
  - lib/hcloud/resources/server.rb
257
263
  - lib/hcloud/resources/server_type.rb
258
264
  - lib/hcloud/resources/ssh_key.rb