hetznercloud 4.1.0 → 4.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e9575422834c710e68322d4d3d9d738521d1a45d8924f90eee7b64da43e47ed
4
- data.tar.gz: 4edab154b29f3c5d3a43d55bdf5d9282418d470105d272446283e564b2f3ee12
3
+ metadata.gz: 8ab3cd637b80e65b74aab7136e5bd487ab7c435770e92e36e116cea33546f701
4
+ data.tar.gz: 8d36b9867b8a2706cf03b6447d5ec45e5c69a2e9d0b0e7d13a006de0ca9d91b3
5
5
  SHA512:
6
- metadata.gz: 5009c504916ca8404c11bd855377e101121fd77e7a53517f4f1b740d540ac36815a47b710429520ddb93458db29e43311444655196931f6a88c3c1dd7bd49461
7
- data.tar.gz: 8af42a4fe808cd090033913f1bb5b3d73eca8066da3ace50e470df6355a90b93981e7fe6167679f7b877b572fb26c2d7b5772b3ac15bd633f0a844353ab343a8
6
+ metadata.gz: ef118d404a4019591158f46350e199306f3b7ae2dd839b29e5a08c31c0a130821c033c4a32f1c9ed0adb9ae5f9e1663490f52aa2f590e63b76217b987eb03996
7
+ data.tar.gz: d9cea883a13f81dacb20e3b38103c30eed853b93f72e86929971a64826c10b7fcc4bcb8d4c6afacfdb369f0848b510e8aba34242fe2aec310df1b5bf13848ebe
data/CHANGELOG.md CHANGED
@@ -10,6 +10,35 @@
10
10
 
11
11
  ### Fixed
12
12
 
13
+ ## HCloud v4.4.0 (2025-11-25)
14
+
15
+ ### Added
16
+
17
+ - Add `update_records` action to `HCloud::RRSet`
18
+
19
+ ## HCloud v4.3.0 (2025-11-17)
20
+
21
+ ### Added
22
+
23
+ - Implement Zones
24
+ - Implement Zone actions
25
+ - Implement RRSets
26
+ - Implement RRSet actions
27
+
28
+ ### Removed
29
+
30
+ - Removed global `ActiveSupport::Inflector` inflections
31
+
32
+ ## HCloud v4.2.0 (2025-09-24)
33
+
34
+ ### Added
35
+
36
+ - Add `locations` attribute to `ServerType`
37
+
38
+ ### Changed
39
+
40
+ - Add deprecation warning for `ServerType#deprecation`
41
+
13
42
  ## HCloud v4.1.0 (2025-09-02)
14
43
 
15
44
  ### Added
data/README.md CHANGED
@@ -92,6 +92,8 @@ The following table lists the Hetzner Cloud API endpoints that are currently imp
92
92
  | [Network Actions](lib/hcloud/resources/network.rb) | Implemented |
93
93
  | [Placement Groups](lib/hcloud/resources/placement_group.rb) | Implemented |
94
94
  | [Pricing](lib/hcloud/resources/pricing.rb) | Implemented |
95
+ | [RRSets](lib/hcloud/resources/rrset.rb) | Implemented |
96
+ | [RRSet Actions](lib/hcloud/resources/rrset.rb) | Implemented |
95
97
  | [Servers](lib/hcloud/resources/server.rb) | Partially implemented |
96
98
  | [Server Actions](lib/hcloud/resources/server.rb) | Not implemented |
97
99
  | [Server Types](lib/hcloud/resources/server_type.rb) | Implemented |
@@ -105,6 +107,8 @@ The following table lists the Hetzner Cloud API endpoints that are currently imp
105
107
  | [Volumes](lib/hcloud/resources/volume.rb) | Implemented |
106
108
  | [Volume Actions](lib/hcloud/resources/volume.rb) | Implemented |
107
109
  | [Metadata](lib/hcloud/resources/metadata.rb) | Implemented |
110
+ | [Zones](lib/hcloud/resources/zone.rb) | Implemented |
111
+ | [Zone Actions](lib/hcloud/resources/zone.rb) | Implemented |
108
112
 
109
113
  ### Pagination
110
114
 
@@ -17,19 +17,9 @@ HCloud.loader.inflector.inflect(
17
17
  "iso_type" => "ISOType",
18
18
  "primary_ip" => "PrimaryIP",
19
19
  "primary_ip_prices" => "PrimaryIPPrices",
20
+ "rrset" => "RRSet",
20
21
  "service_http" => "ServiceHTTP",
21
22
  "ssh_key" => "SSHKey",
22
23
  "target_ip" => "TargetIP",
23
24
  "yaml" => "YAML",
24
25
  )
25
-
26
- ActiveSupport::Inflector.inflections(:en) do |inflect|
27
- inflect.acronym "DNS"
28
- inflect.acronym "HTTP"
29
- inflect.acronym "IP"
30
- inflect.acronym "IPv4"
31
- inflect.acronym "IPv6"
32
- inflect.acronym "ISO"
33
- inflect.acronym "JSON"
34
- inflect.acronym "YAML"
35
- end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class AuthoritativeNameservers < Entity
5
+ attribute :assigned, array: true, default: -> { [] }
6
+ attribute :delegated, array: true, default: -> { [] }
7
+ attribute :delegation_last_check, :datetime
8
+ attribute :delegation_status
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ChangeProtection < Entity
5
+ attribute :change, :boolean
6
+
7
+ alias change? change
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Nameserver < Entity
5
+ attribute :address
6
+ attribute :port, :integer
7
+
8
+ attribute :tsig_key
9
+ attribute :tsig_algorithm
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Record < Entity
5
+ attribute :value
6
+ attribute :comment
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class ServerTypeLocation < Entity
5
+ attribute :id, :integer
6
+ attribute :name
7
+ attribute :deprecation, :deprecation
8
+ end
9
+ end
data/lib/hcloud/errors.rb CHANGED
@@ -29,6 +29,7 @@ module HCloud
29
29
  class FirewallAlreadyRemoved < Error; end
30
30
  class FirewallResourceNotFound < Error; end
31
31
  class Forbidden < Error; end
32
+ class IncorrectZoneMode < Error; end
32
33
  class IPNotAvailable < Error; end
33
34
  class IPNotOwned < Error; end
34
35
  class IncompatibleNetworkType < Error; end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ class Inflector < Zeitwerk::Inflector
5
+ def underscore(classname)
6
+ classname
7
+ .to_s
8
+ .split("::")
9
+ .map { |word| overrides.key(word) || word.underscore }
10
+ .join("/")
11
+ end
12
+ end
13
+ end
@@ -15,6 +15,10 @@ module HCloud
15
15
  assign_attributes(attributes) if attributes
16
16
  end
17
17
 
18
+ def mutable?
19
+ true
20
+ end
21
+
18
22
  delegate :[], to: :attributes
19
23
 
20
24
  def inspect
@@ -12,6 +12,10 @@ module HCloud
12
12
  @array = array
13
13
  end
14
14
 
15
+ def mutable?
16
+ true
17
+ end
18
+
15
19
  def cast(value)
16
20
  case value
17
21
  when nil, []
@@ -88,8 +92,10 @@ ActiveModel::Type.register(:amount, HCloud::ResourceType.Type("HCloud::Amount"))
88
92
  ActiveModel::Type.register(:applied_to, HCloud::ResourceType.Type("HCloud::AppliedTo"))
89
93
  ActiveModel::Type.register(:applied_to_resource, HCloud::ResourceType.Type("HCloud::AppliedToResource"))
90
94
  ActiveModel::Type.register(:apply_to, HCloud::ResourceType.Type("HCloud::ApplyTo"))
95
+ ActiveModel::Type.register(:authoritative_nameservers, HCloud::ResourceType.Type("HCloud::AuthoritativeNameservers"))
91
96
  ActiveModel::Type.register(:certificate, HCloud::ResourceType.Type("HCloud::Certificate"))
92
97
  ActiveModel::Type.register(:certificate_status, HCloud::ResourceType.Type("HCloud::CertificateStatus"))
98
+ ActiveModel::Type.register(:change_protection, HCloud::ResourceType.Type("HCloud::ChangeProtection"))
93
99
  ActiveModel::Type.register(:datacenter, HCloud::ResourceType.Type("HCloud::Datacenter"))
94
100
  ActiveModel::Type.register(:datacenter_server_type, HCloud::ResourceType.Type("HCloud::DatacenterServerType"))
95
101
  ActiveModel::Type.register(:deprecation, HCloud::ResourceType.Type("HCloud::Deprecation"))
@@ -115,6 +121,7 @@ ActiveModel::Type.register(:load_balancer_type, HCloud::ResourceType.Type("HClou
115
121
  ActiveModel::Type.register(:load_balancer_type_price, HCloud::ResourceType.Type("HCloud::LoadBalancerTypePrice"))
116
122
  ActiveModel::Type.register(:location, HCloud::ResourceType.Type("HCloud::Location"))
117
123
  ActiveModel::Type.register(:metadata, HCloud::ResourceType.Type("HCloud::Metadata"))
124
+ ActiveModel::Type.register(:nameserver, HCloud::ResourceType.Type("HCloud::Nameserver"))
118
125
  ActiveModel::Type.register(:network, HCloud::ResourceType.Type("HCloud::Network"))
119
126
  ActiveModel::Type.register(:placement_group, HCloud::ResourceType.Type("HCloud::PlacementGroup"))
120
127
  ActiveModel::Type.register(:price, HCloud::ResourceType.Type("HCloud::Price"))
@@ -126,13 +133,16 @@ ActiveModel::Type.register(:private_network, HCloud::ResourceType.Type("HCloud::
126
133
  ActiveModel::Type.register(:protection, HCloud::ResourceType.Type("HCloud::Protection"))
127
134
  ActiveModel::Type.register(:public_net, HCloud::ResourceType.Type("HCloud::PublicNet"))
128
135
  ActiveModel::Type.register(:public_net_firewall, HCloud::ResourceType.Type("HCloud::PublicNetFirewall"))
136
+ ActiveModel::Type.register(:record, HCloud::ResourceType.Type("HCloud::Record"))
129
137
  ActiveModel::Type.register(:resource, HCloud::ResourceType::GenericType)
130
138
  ActiveModel::Type.register(:route, HCloud::ResourceType.Type("HCloud::Route"))
139
+ ActiveModel::Type.register(:rrset, HCloud::ResourceType.Type("HCloud::RRSet"))
131
140
  ActiveModel::Type.register(:rule, HCloud::ResourceType.Type("HCloud::Rule"))
132
141
  ActiveModel::Type.register(:server, HCloud::ResourceType.Type("HCloud::Server"))
133
142
  ActiveModel::Type.register(:server_backup_price, HCloud::ResourceType.Type("HCloud::ServerBackupPrice"))
134
143
  ActiveModel::Type.register(:server_protection, HCloud::ResourceType.Type("HCloud::ServerProtection"))
135
144
  ActiveModel::Type.register(:server_type, HCloud::ResourceType.Type("HCloud::ServerType"))
145
+ ActiveModel::Type.register(:server_type_location, HCloud::ResourceType.Type("HCloud::ServerTypeLocation"))
136
146
  ActiveModel::Type.register(:server_type_price, HCloud::ResourceType.Type("HCloud::ServerTypePrice"))
137
147
  ActiveModel::Type.register(:service, HCloud::ResourceType.Type("HCloud::Service"))
138
148
  ActiveModel::Type.register(:service_http, HCloud::ResourceType.Type("HCloud::ServiceHTTP"))
@@ -155,3 +165,4 @@ ActiveModel::Type.register(:traffic_price, HCloud::ResourceType.Type("HCloud::Tr
155
165
  ActiveModel::Type.register(:used_by, HCloud::ResourceType.Type("HCloud::UsedBy"))
156
166
  ActiveModel::Type.register(:volume, HCloud::ResourceType.Type("HCloud::Volume"))
157
167
  ActiveModel::Type.register(:volume_price, HCloud::ResourceType.Type("HCloud::VolumePrice"))
168
+ ActiveModel::Type.register(:zone, HCloud::ResourceType.Type("HCloud::Zone"))
@@ -48,28 +48,28 @@ module HCloud
48
48
  # = Actions
49
49
  # == List actions
50
50
  #
51
- # actions = HCloud::FloatingIP.find(1).actions
51
+ # actions = HCloud::Network.find(1).actions
52
52
  # # => [#<HCloud::Action id: 1, ...>, ...]
53
53
  #
54
54
  # == Sort actions
55
55
  #
56
- # HCloud::FloatingIP.find(1).actions.sort(finished: :desc)
56
+ # HCloud::Network.find(1).actions.sort(finished: :desc)
57
57
  # # => [#<HCloud::Action id: 1, ...>, ...]
58
58
  #
59
- # HCloud::FloatingIP.find(1).actions.sort(:command, finished: :asc)
59
+ # HCloud::Network.find(1).actions.sort(:command, finished: :asc)
60
60
  # # => [#<HCloud::Actions id: 1, ...>, ...]
61
61
  #
62
62
  # == Search actions
63
63
  #
64
- # HCloud::FloatingIP.find(1).actions.where(command: "assign_floating_ip")
64
+ # HCloud::Network.find(1).actions.where(command: "assign_floating_ip")
65
65
  # # => #<HCloud::Action id: 1, ...>
66
66
  #
67
- # HCloud::FloatingIP.find(1).actions.where(status: "success")
67
+ # HCloud::Network.find(1).actions.where(status: "success")
68
68
  # # => #<HCloud::Action id: 1, ...>
69
69
  #
70
70
  # == Find action by ID
71
71
  #
72
- # HCloud::FloatingIP.find(1).actions.find(1)
72
+ # HCloud::Network.find(1).actions.find(1)
73
73
  # # => #<HCloud::Action id: 1, ...>
74
74
  #
75
75
  # = Resource-specific actions
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents a DNS zone's RRSet
6
+ #
7
+ # == List all RRSets
8
+ #
9
+ # zone = HCloud::Zone.find(1)
10
+ # zone.rrsets
11
+ # # => [#<HCloud::RRSet id: 1, ...>, ...]
12
+ #
13
+ # == Sort RRSets
14
+ #
15
+ # zone = HCloud::Zone.find(1)
16
+ # zone.rrsets.sort(name: :desc)
17
+ # # => [#<HCloud::RRSet id: 1, ...>, ...]
18
+ #
19
+ # zone.rrsets.sort(:id, name: :asc)
20
+ # # => [#<HCloud::RRSet id: 1, ...>, ...]
21
+ #
22
+ # == Search RRSets
23
+ #
24
+ # zone = HCloud::Zone.find(1)
25
+ # zone.rrsets.where(name: "my_zone")
26
+ # # => #<HCloud::RRSet id: 1, ...>
27
+ #
28
+ # zone.rrsets.where(type: "AAAA")
29
+ # # => #<HCloud::RRSet id: 1, ...>
30
+ #
31
+ # zone.rrsets.where(label_selector: "environment=production")
32
+ # # => #<HCloud::RRSet id: 1, ...>
33
+ #
34
+ # == Find RRSet by ID
35
+ #
36
+ # zone = HCloud::Zone.find(1)
37
+ # zone.rrsets.find(1)
38
+ # # => #<HCloud::RRSet id: 1, ...>
39
+ #
40
+ # == Create RRSet
41
+ #
42
+ # zone = HCloud::Zone.find(1)
43
+ # rrset = zone.rrsets.new(name: "my_rrset", type: "A", ttl: 10800, records: [{ value: "198.51.100.1", comment: "My web server at Hetzner Cloud" }])
44
+ # rrset.create
45
+ # rrset.created?
46
+ # # => true
47
+ #
48
+ # == Update RRSet
49
+ #
50
+ # zone = HCloud::Zone.find(1)
51
+ # rrset = zone.rrsets.find(1)
52
+ # rrset.name = "another_rrset"
53
+ # rrset.update
54
+ #
55
+ # == Delete RRSet
56
+ #
57
+ # zone = HCloud::Zone.find(1)
58
+ # rrset = zone.rrsets.find(1)
59
+ # rrset.delete
60
+ # # => #<HCloud::Action id: 1, ...>
61
+ #
62
+ # rrset.deleted?
63
+ # # => true
64
+ #
65
+ # = Actions
66
+ # == List actions
67
+ #
68
+ # zone = HCloud::Zone.find(1)
69
+ # actions = zone.rrsets.find(1).actions
70
+ # # => [#<HCloud::Action id: 1, ...>, ...]
71
+ #
72
+ # == Sort actions
73
+ #
74
+ # zone = HCloud::Zone.find(1)
75
+ # zone.rrsets.find(1).actions.sort(finished: :desc)
76
+ # # => [#<HCloud::Action id: 1, ...>, ...]
77
+ #
78
+ # zone = HCloud::Zone.find(1)
79
+ # zone.rrsets.find(1).actions.sort(:command, finished: :asc)
80
+ # # => [#<HCloud::Action id: 1, ...>, ...]
81
+ #
82
+ # == Search actions
83
+ #
84
+ # zone = HCloud::Zone.find(1)
85
+ # zone.rrsets.find(1).actions.where(command: "change_protection")
86
+ # # => #<HCloud::Action id: 1, ...>
87
+ #
88
+ # zone = HCloud::Zone.find(1)
89
+ # zone.rrsets.find(1).actions.where(status: "success")
90
+ # # => #<HCloud::Action id: 1, ...>
91
+ #
92
+ # == Find action by ID
93
+ #
94
+ # zone = HCloud::Zone.find(1)
95
+ # zone.rrsets.find(1).actions.find(1)
96
+ # # => #<HCloud::Action id: 1, ...>
97
+ #
98
+ # = Resource-specific actions
99
+ # == Change protection
100
+ #
101
+ # zone = HCloud::Zone.find(1)
102
+ # zone.rrsets.find(1).change_protection(change: true)
103
+ # # => #<HCloud::Action id: 1, ...>
104
+ #
105
+ # == Change TTL
106
+ #
107
+ # zone = HCloud::Zone.find(1)
108
+ # zone.rrsets.find(1).change_ttl(ttl: 10800)
109
+ # # => #<HCloud::Action id: 1, ...>
110
+ #
111
+ # == Set records
112
+ #
113
+ # zone = HCloud::Zone.find(1)
114
+ # zone.rrsets.find(1).set_records(records: [{ value: "198.51.100.1", comment: "My web server at Hetzner Cloud" }])
115
+ # # => #<HCloud::Action id: 1, ...>
116
+ #
117
+ # == Add records
118
+ #
119
+ # zone = HCloud::Zone.find(1)
120
+ # zone.rrsets.find(1).add_records(ttl: 10800, records: [{ value: "198.51.100.1", comment: "My web server at Hetzner Cloud" }])
121
+ # # => #<HCloud::Action id: 1, ...>
122
+ #
123
+ # == Update records
124
+ #
125
+ # zone = HCloud::Zone.find(1)
126
+ # zone.rrsets.find(1).update_records(records: [{ value: "198.51.100.1", comment: "My web server at Hetzner Cloud" }])
127
+ # # => #<HCloud::Action id: 1, ...>
128
+ #
129
+ # == Remove records
130
+ #
131
+ # zone = HCloud::Zone.find(1)
132
+ # zone.rrsets.find(1).remove_records(records: [{ value: "198.51.100.1", comment: "My web server at Hetzner Cloud" }])
133
+ # # => #<HCloud::Action id: 1, ...>
134
+ #
135
+ class RRSet < Resource
136
+ subresource_of :zone
137
+
138
+ actionable
139
+ queryable
140
+ creatable
141
+ updatable
142
+ deletable
143
+ labelable
144
+
145
+ attribute :id
146
+ attribute :name
147
+
148
+ attribute :type
149
+
150
+ attribute :ttl, :integer
151
+
152
+ attribute :protection, :change_protection
153
+
154
+ attribute :records, :record, array: true, default: -> { [] }
155
+
156
+ attribute :zone, :zone
157
+
158
+ action :change_protection
159
+ action :change_ttl
160
+ action :set_records
161
+ action :add_records
162
+ action :update_records
163
+ action :remove_records
164
+
165
+ def creatable_attributes
166
+ [:name, :type, :ttl, :records, :labels]
167
+ end
168
+
169
+ def updatable_attributes
170
+ [:labels]
171
+ end
172
+ end
173
+ end
@@ -37,7 +37,9 @@ module HCloud
37
37
 
38
38
  attribute :prices, :price, array: true, default: -> { [] }
39
39
 
40
- attribute :deprecation, :deprecation
40
+ attribute :locations, :server_type_location, array: true, default: -> { [] }
41
+
42
+ attribute :deprecation, :deprecation, deprecated: true
41
43
 
42
44
  attribute :deprecated, :boolean, deprecated: true
43
45
 
@@ -8,23 +8,23 @@ module HCloud
8
8
  #
9
9
  # storage_box = HCloud::StorageBox.find(1)
10
10
  # storage_box.snapshots
11
- # # => [#<HCloud::StorageBox::Snapshot id: 1, ...>, ...]
11
+ # # => [#<HCloud::StorageBoxSnapshot id: 1, ...>, ...]
12
12
  #
13
13
  # == Search snapshots
14
14
  #
15
15
  # storage_box = HCloud::StorageBox.find(1)
16
16
  # storage_box.snapshots.where(name: "monthly_backup")
17
- # # => #<HCloud::StorageBox::Snapshot id: 1, ...>
17
+ # # => #<HCloud::StorageBoxSnapshot id: 1, ...>
18
18
  #
19
19
  # storage_box = HCloud::StorageBox.find(1)
20
20
  # storage_box.snapshots.where(label_selector: "environment=production")
21
- # # => #<HCloud::StorageBox::Snapshot id: 1, ...>
21
+ # # => #<HCloud::StorageBoxSnapshot id: 1, ...>
22
22
  #
23
23
  # == Find snapshot by ID
24
24
  #
25
25
  # storage_box = HCloud::StorageBox.find(1)
26
26
  # storage_box.snapshots.find(1)
27
- # # => #<HCloud::StorageBox::Snapshot id: 1, ...>
27
+ # # => #<HCloud::StorageBoxSnapshot id: 1, ...>
28
28
  #
29
29
  # == Create snapshot
30
30
  #
@@ -46,7 +46,7 @@ module HCloud
46
46
  #
47
47
  # Note: this method returns a {HCloud::Action} instance rather than the created resource itself
48
48
  #
49
- # snapshot = HCloud::StorageBox::Snapshot.create(storage_box: 1, description: "my_snapshot")
49
+ # snapshot = HCloud::StorageBoxSnapshot.create(storage_box: 1, description: "my_snapshot")
50
50
  # # => #<HCloud::Action id: 1, ...>
51
51
  #
52
52
  # Note: this method returns a {HCloud::Action} instance rather than the created resource itself
@@ -8,19 +8,19 @@ module HCloud
8
8
  #
9
9
  # storage_box = HCloud::StorageBox.find(1)
10
10
  # storage_box.subaccounts
11
- # # => [#<HCloud::StorageBox::Subaccount id: 1, ...>, ...]
11
+ # # => [#<HCloud::StorageBoxSubaccount id: 1, ...>, ...]
12
12
  #
13
13
  # == Search subaccounts
14
14
  #
15
15
  # storage_box = HCloud::StorageBox.find(1)
16
16
  # storage_box.subaccounts.where(label_selector: "environment=production")
17
- # # => #<HCloud::StorageBox::Subaccount id: 1, ...>
17
+ # # => #<HCloud::StorageBoxSubaccount id: 1, ...>
18
18
  #
19
19
  # == Find subaccount by ID
20
20
  #
21
21
  # storage_box = HCloud::StorageBox.find(1)
22
22
  # storage_box.subaccounts.find(1)
23
- # # => #<HCloud::StorageBox::Subaccount id: 1, ...>
23
+ # # => #<HCloud::StorageBoxSubaccount id: 1, ...>
24
24
  #
25
25
  # == Create subaccount
26
26
  #
@@ -42,7 +42,7 @@ module HCloud
42
42
  #
43
43
  # Note: this method returns a {HCloud::Action} instance rather than the created resource itself
44
44
  #
45
- # subaccount = HCloud::StorageBox::Subaccount.create(storage_box: 1, password: "my_password", description: "my_subaccount", home_directory: "backup/", access_settings: { samba_enabled: false, ssh_enabled: true, webdav_enabled: false, readonly: false, reachable_externally: false })
45
+ # subaccount = HCloud::StorageBoxSubaccount.create(storage_box: 1, password: "my_password", description: "my_subaccount", home_directory: "backup/", access_settings: { samba_enabled: false, ssh_enabled: true, webdav_enabled: false, readonly: false, reachable_externally: false })
46
46
  # # => #<HCloud::Action id: 1, ...>
47
47
  #
48
48
  # Note: this method returns a {HCloud::Action} instance rather than the created resource itself
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCloud
4
+ ##
5
+ # Represents a DNS zone
6
+ #
7
+ # == List all zones
8
+ #
9
+ # HCloud::Zone.all
10
+ # # => [#<HCloud::Zone id: 1, ...>, ...]
11
+ #
12
+ # == Sort zones
13
+ #
14
+ # HCloud::Zone.sort(name: :desc)
15
+ # # => [#<HCloud::Zone id: 1, ...>, ...]
16
+ #
17
+ # HCloud::Zone.sort(:id, name: :asc)
18
+ # # => [#<HCloud::Zone id: 1, ...>, ...]
19
+ #
20
+ # == Search zones
21
+ #
22
+ # HCloud::Zone.where(name: "my_zone")
23
+ # # => #<HCloud::Zone id: 1, ...>
24
+ #
25
+ # HCloud::Zone.where(mode: "primary")
26
+ # # => #<HCloud::Zone id: 1, ...>
27
+ #
28
+ # HCloud::Zone.where(label_selector: "environment=production")
29
+ # # => #<HCloud::Zone id: 1, ...>
30
+ #
31
+ # == Find zone by ID
32
+ #
33
+ # HCloud::Zone.find(1)
34
+ # # => #<HCloud::Zone id: 1, ...>
35
+ #
36
+ # == Create zone
37
+ #
38
+ # zone = HCloud::Zone.new(name: "my_zone", mode: "primary", ttl: 10800, rrsets: [{ name: "www", type: "A", records: [{ value: "198.51.100.1", comment: "My web server at Hetzner Cloud" }] }])
39
+ # zone.create
40
+ # zone.created?
41
+ # # => true
42
+ #
43
+ # zone = HCloud::Zone.create(name: "my_zone", mode: "primary", ttl: 10800)
44
+ # # => #<HCloud::Zone id: 1, ...>
45
+ #
46
+ # == Update zone
47
+ #
48
+ # zone = HCloud::Zone.find(1)
49
+ # zone.labels = { environment: "production" }
50
+ # zone.update
51
+ #
52
+ # == Delete zone
53
+ #
54
+ # zone = HCloud::Zone.find(1)
55
+ # zone.delete
56
+ # zone.deleted?
57
+ # # => true
58
+ #
59
+ # == Export zone file
60
+ #
61
+ # zone = HCloud::Zone.find(1)
62
+ # zone.export
63
+ # # => "$ORIGIN\texample.com.\n$TTL\t3600\n\n@\tIN\tSOA\thydrogen.ns.hetzner.com. dns.hetzner.com. ..."
64
+ #
65
+ # = Actions
66
+ # == List actions
67
+ #
68
+ # actions = HCloud::Zone.find(1).actions
69
+ # # => [#<HCloud::Action id: 1, ...>, ...]
70
+ #
71
+ # == Sort actions
72
+ #
73
+ # HCloud::Zone.find(1).actions.sort(finished: :desc)
74
+ # # => [#<HCloud::Action id: 1, ...>, ...]
75
+ #
76
+ # HCloud::Zone.find(1).actions.sort(:command, finished: :asc)
77
+ # # => [#<HCloud::Actions id: 1, ...>, ...]
78
+ #
79
+ # == Search actions
80
+ #
81
+ # HCloud::Zone.find(1).actions.where(command: "import_zonefile")
82
+ # # => #<HCloud::Action id: 1, ...>
83
+ #
84
+ # HCloud::Zone.find(1).actions.where(status: "success")
85
+ # # => #<HCloud::Action id: 1, ...>
86
+ #
87
+ # == Find action by ID
88
+ #
89
+ # HCloud::Zone.find(1).actions.find(1)
90
+ # # => #<HCloud::Action id: 1, ...>
91
+ #
92
+ # = Resource-specific actions
93
+ # == Change a zone's primary nameservers
94
+ #
95
+ # HCloud::Zone.find(1).change_primary_nameservers(primary_nameservers: [{ address: "198.51.100.1", port: 53 }, { address: "203.0.113.1", port: 53 }])
96
+ # # => #<HCloud::Action id: 1, ...>
97
+ #
98
+ # == Change protection
99
+ #
100
+ # HCloud::Zone.find(1).change_protection(delete: true)
101
+ # # => #<HCloud::Action id: 1, ...>
102
+ #
103
+ # == Change default TTL
104
+ #
105
+ # HCloud::Zone.find(1).change_ttl(ttl: 10800)
106
+ # # => #<HCloud::Action id: 1, ...>
107
+ #
108
+ # == Import zone file
109
+ #
110
+ # HCloud::Zone.find(1).import_zonefile(zonefile: "$ORIGIN\texample.com.\n$TTL\t3600\n\n@\tIN\tSOA\thydrogen.ns.hetzner.com. dns.hetzner.com. ...")
111
+ # # => #<HCloud::Action id: 1, ...>
112
+ #
113
+ class Zone < Resource
114
+ actionable
115
+ queryable
116
+ creatable
117
+ updatable
118
+ deletable
119
+ labelable
120
+
121
+ subresource :rrset, :rrset
122
+
123
+ attribute :id, :integer
124
+ attribute :name
125
+
126
+ attribute :mode
127
+
128
+ attribute :primary_nameservers, :nameserver, array: true, default: -> { [] }
129
+ attribute :authoritative_nameservers, :authoritative_nameservers
130
+
131
+ attribute :record_count, :integer
132
+ attribute :ttl, :integer
133
+ attribute :status
134
+ attribute :registrar
135
+
136
+ attribute :protection, :protection
137
+
138
+ action :change_primary_nameservers
139
+ action :change_protection
140
+ action :change_ttl
141
+ action :import_zonefile
142
+
143
+ def export
144
+ raise Errors::MissingIDError unless id
145
+
146
+ client
147
+ .get("#{resource_path}/#{id}/zonefile")
148
+ .fetch(:zonefile)
149
+ end
150
+
151
+ def creatable_attributes
152
+ [:name, :mode, :ttl, :labels, :primary_nameservers, :rrsets]
153
+ end
154
+
155
+ def updatable_attributes
156
+ [:labels]
157
+ end
158
+ end
159
+ end
@@ -4,7 +4,7 @@ module HCloud
4
4
  # @!visibility private
5
5
  module Version
6
6
  MAJOR = 4
7
- MINOR = 1
7
+ MINOR = 4
8
8
  PATCH = 0
9
9
  PRE = nil
10
10
 
data/lib/hcloud.rb CHANGED
@@ -4,6 +4,8 @@ require "active_model"
4
4
  require "active_support/all"
5
5
  require "zeitwerk"
6
6
 
7
+ require_relative "hcloud/inflector"
8
+
7
9
  module HCloud
8
10
  class << self
9
11
  # Code loader instance
@@ -16,6 +18,9 @@ module HCloud
16
18
  def setup
17
19
  @loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
18
20
 
21
+ # Set up inflector
22
+ loader.inflector = Inflector.new
23
+
19
24
  # Register inflections
20
25
  require root.join("config/inflections.rb")
21
26
 
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: 4.1.0
4
+ version: 4.4.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: 2025-09-02 00:00:00.000000000 Z
11
+ date: 2025-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: openssl
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: zeitwerk
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -99,7 +113,9 @@ files:
99
113
  - lib/hcloud/entities/applied_to.rb
100
114
  - lib/hcloud/entities/applied_to_resource.rb
101
115
  - lib/hcloud/entities/apply_to.rb
116
+ - lib/hcloud/entities/authoritative_nameservers.rb
102
117
  - lib/hcloud/entities/certificate_status.rb
118
+ - lib/hcloud/entities/change_protection.rb
103
119
  - lib/hcloud/entities/datacenter_server_type.rb
104
120
  - lib/hcloud/entities/deprecation.rb
105
121
  - lib/hcloud/entities/dns_pointer.rb
@@ -117,6 +133,7 @@ files:
117
133
  - lib/hcloud/entities/load_balancer_public_net.rb
118
134
  - lib/hcloud/entities/load_balancer_type_price.rb
119
135
  - lib/hcloud/entities/metrics.rb
136
+ - lib/hcloud/entities/nameserver.rb
120
137
  - lib/hcloud/entities/price.rb
121
138
  - lib/hcloud/entities/primary_ip_prices.rb
122
139
  - lib/hcloud/entities/private_net.rb
@@ -124,10 +141,12 @@ files:
124
141
  - lib/hcloud/entities/protection.rb
125
142
  - lib/hcloud/entities/public_net.rb
126
143
  - lib/hcloud/entities/public_net_firewall.rb
144
+ - lib/hcloud/entities/record.rb
127
145
  - lib/hcloud/entities/route.rb
128
146
  - lib/hcloud/entities/rule.rb
129
147
  - lib/hcloud/entities/server_backup_price.rb
130
148
  - lib/hcloud/entities/server_protection.rb
149
+ - lib/hcloud/entities/server_type_location.rb
131
150
  - lib/hcloud/entities/server_type_price.rb
132
151
  - lib/hcloud/entities/service.rb
133
152
  - lib/hcloud/entities/service_http.rb
@@ -148,6 +167,7 @@ files:
148
167
  - lib/hcloud/entity.rb
149
168
  - lib/hcloud/errors.rb
150
169
  - lib/hcloud/http.rb
170
+ - lib/hcloud/inflector.rb
151
171
  - lib/hcloud/resource.rb
152
172
  - lib/hcloud/resource_type.rb
153
173
  - lib/hcloud/resources/action.rb
@@ -165,6 +185,7 @@ files:
165
185
  - lib/hcloud/resources/placement_group.rb
166
186
  - lib/hcloud/resources/pricing.rb
167
187
  - lib/hcloud/resources/primary_ip.rb
188
+ - lib/hcloud/resources/rrset.rb
168
189
  - lib/hcloud/resources/server.rb
169
190
  - lib/hcloud/resources/server_type.rb
170
191
  - lib/hcloud/resources/ssh_key.rb
@@ -173,6 +194,7 @@ files:
173
194
  - lib/hcloud/resources/storage_box_subaccount.rb
174
195
  - lib/hcloud/resources/storage_box_type.rb
175
196
  - lib/hcloud/resources/volume.rb
197
+ - lib/hcloud/resources/zone.rb
176
198
  - lib/hcloud/sub_collection.rb
177
199
  - lib/hcloud/version.rb
178
200
  - lib/http/features/block_io.rb