hetznercloud 1.1.0 → 1.2.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 (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