hcloud 1.1.0 → 1.3.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.
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/hash/keys'
4
+
5
+ module Hcloud
6
+ class LoadBalancer
7
+ require 'hcloud/load_balancer_resource'
8
+
9
+ include EntryLoader
10
+
11
+ schema(
12
+ location: Location,
13
+ load_balancer_type: LoadBalancerType,
14
+ created: :time
15
+ )
16
+
17
+ protectable :delete
18
+ updatable :name
19
+ destructible
20
+
21
+ has_metrics
22
+ has_actions
23
+
24
+ %w[enable_public_interface disable_public_interface].each do |action|
25
+ define_method(action) do
26
+ prepare_request("actions/#{action}", method: :post)
27
+ end
28
+ end
29
+
30
+ def attach_to_network(network:, ip: nil)
31
+ raise Hcloud::Error::InvalidInput, 'no network given' if network.nil?
32
+
33
+ prepare_request('actions/attach_to_network', j: COLLECT_ARGS.call(__method__, binding))
34
+ end
35
+
36
+ def detach_from_network(network:)
37
+ raise Hcloud::Error::InvalidInput, 'no network given' if network.nil?
38
+
39
+ prepare_request('actions/detach_from_network', j: COLLECT_ARGS.call(__method__, binding))
40
+ end
41
+
42
+ def change_dns_ptr(ip:, dns_ptr:)
43
+ raise Hcloud::Error::InvalidInput, 'no IP given' if ip.blank?
44
+ raise Hcloud::Error::InvalidInput, 'no dns_ptr given' if dns_ptr.blank?
45
+
46
+ prepare_request('actions/change_dns_ptr', j: COLLECT_ARGS.call(__method__, binding))
47
+ end
48
+
49
+ def change_type(load_balancer_type:)
50
+ raise Hcloud::Error::InvalidInput, 'no type given' if load_balancer_type.blank?
51
+
52
+ prepare_request('actions/change_type', j: COLLECT_ARGS.call(__method__, binding))
53
+ end
54
+
55
+ def change_algorithm(type:)
56
+ raise Hcloud::Error::InvalidInput, 'no type given' if type.blank?
57
+
58
+ prepare_request('actions/change_algorithm', j: COLLECT_ARGS.call(__method__, binding))
59
+ end
60
+
61
+ def add_service(
62
+ protocol:, listen_port:, destination_port:, health_check:, proxyprotocol:, http: nil
63
+ )
64
+ validate_service_input(
65
+ protocol: protocol,
66
+ listen_port: listen_port,
67
+ destination_port: destination_port,
68
+ health_check: health_check,
69
+ proxyprotocol: proxyprotocol
70
+ )
71
+
72
+ prepare_request('actions/add_service', j: COLLECT_ARGS.call(__method__, binding))
73
+ end
74
+
75
+ def update_service(
76
+ protocol:, listen_port:, destination_port:, health_check:, proxyprotocol:, http: nil
77
+ )
78
+ validate_service_input(
79
+ protocol: protocol,
80
+ listen_port: listen_port,
81
+ destination_port: destination_port,
82
+ health_check: health_check,
83
+ proxyprotocol: proxyprotocol
84
+ )
85
+
86
+ prepare_request('actions/update_service', j: COLLECT_ARGS.call(__method__, binding))
87
+ end
88
+
89
+ def delete_service(listen_port:)
90
+ raise Hcloud::Error::InvalidInput, 'no listen_port given' if listen_port.nil?
91
+
92
+ prepare_request('actions/delete_service', j: COLLECT_ARGS.call(__method__, binding))
93
+ end
94
+
95
+ def add_target(type:, server: nil, label_selector: nil, ip: nil, use_private_ip: false)
96
+ validate_target_input(
97
+ type: type, server: server, label_selector: label_selector, ip: ip
98
+ )
99
+
100
+ prepare_request('actions/add_target', j: COLLECT_ARGS.call(__method__, binding))
101
+ end
102
+
103
+ def remove_target(type:, server: nil, label_selector: nil, ip: nil)
104
+ validate_target_input(
105
+ type: type, server: server, label_selector: label_selector, ip: ip
106
+ )
107
+
108
+ prepare_request('actions/remove_target', j: COLLECT_ARGS.call(__method__, binding))
109
+ end
110
+
111
+ private
112
+
113
+ def validate_service_input(
114
+ protocol:, listen_port:, destination_port:, health_check:, proxyprotocol:
115
+ )
116
+ raise Hcloud::Error::InvalidInput, 'no protocol given' if protocol.blank?
117
+ raise Hcloud::Error::InvalidInput, 'no listen_port given' if listen_port.nil?
118
+ raise Hcloud::Error::InvalidInput, 'no destination_port given' if destination_port.nil?
119
+ raise Hcloud::Error::InvalidInput, 'no health_check given' if health_check.nil?
120
+ raise Hcloud::Error::InvalidInput, 'no proxyprotocol given' if proxyprotocol.nil?
121
+ end
122
+
123
+ def validate_target_input(type:, server: nil, label_selector: nil, ip: nil)
124
+ raise Hcloud::Error::InvalidInput, 'no type given' if type.nil?
125
+
126
+ case type.to_sym
127
+ when :server
128
+ raise Hcloud::Error::InvalidInput, 'invalid server given' unless server.to_h.key?(:id)
129
+ when :ip
130
+ raise Hcloud::Error::InvalidInput, 'no IP given' if ip.blank?
131
+ when :label_selector
132
+ unless label_selector.to_h.key?(:selector)
133
+ raise Hcloud::Error::InvalidInput, 'invalid label_selector given'
134
+ end
135
+ else
136
+ raise Hcloud::Error::InvalidInput, 'invalid type given'
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class LoadBalancerResource < AbstractResource
5
+ filter_attributes :name, :label_selector
6
+
7
+ bind_to LoadBalancer
8
+
9
+ def [](arg)
10
+ case arg
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
13
+ end
14
+ end
15
+
16
+ def create(
17
+ name:, load_balancer_type:, algorithm:, location: nil, network_zone: nil,
18
+ network: nil, public_interface: nil, services: nil, targets: nil,
19
+ labels: {}
20
+ )
21
+ raise Hcloud::Error::InvalidInput, 'no name given' if name.blank?
22
+ raise Hcloud::Error::InvalidInput, 'no type given' if load_balancer_type.blank?
23
+ if !algorithm.to_h.key?(:type) || algorithm[:type].blank?
24
+ raise Hcloud::Error::InvalidInput, 'invalid algorithm given'
25
+ end
26
+ if location.blank? && network_zone.blank?
27
+ raise Hcloud::Error::InvalidInput, 'either location or network_zone must be given'
28
+ end
29
+
30
+ prepare_request(
31
+ 'load_balancers', j: COLLECT_ARGS.call(__method__, binding),
32
+ expected_code: 201
33
+ ) do |response|
34
+ action = Action.new(client, response[:action]) if response[:action]
35
+ [action, LoadBalancer.new(client, response[:load_balancer])]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class LoadBalancerType
5
+ require 'hcloud/load_balancer_type_resource'
6
+
7
+ include EntryLoader
8
+
9
+ schema(
10
+ deprecated: :time
11
+ )
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class LoadBalancerTypeResource < AbstractResource
5
+ filter_attributes :name
6
+
7
+ bind_to LoadBalancerType
8
+
9
+ def [](arg)
10
+ case arg
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -15,19 +15,36 @@ module Hcloud
15
15
  has_actions
16
16
 
17
17
  def add_subnet(type:, network_zone:, ip_range: nil)
18
+ raise Hcloud::Error::InvalidInput, 'no type given' if type.blank?
19
+ raise Hcloud::Error::InvalidInput, 'no network_zone given' if network_zone.blank?
20
+
18
21
  prepare_request('actions/add_subnet', j: COLLECT_ARGS.call(__method__, binding))
19
22
  end
20
23
 
21
24
  def del_subnet(ip_range:)
25
+ raise Hcloud::Error::InvalidInput, 'no ip_range given' if ip_range.blank?
26
+
22
27
  prepare_request('actions/delete_subnet', j: COLLECT_ARGS.call(__method__, binding))
23
28
  end
24
29
 
25
30
  def add_route(destination:, gateway:)
31
+ raise Hcloud::Error::InvalidInput, 'no destination given' if destination.blank?
32
+ raise Hcloud::Error::InvalidInput, 'no gateway given' if gateway.blank?
33
+
26
34
  prepare_request('actions/add_route', j: COLLECT_ARGS.call(__method__, binding))
27
35
  end
28
36
 
29
37
  def del_route(destination:, gateway:)
38
+ raise Hcloud::Error::InvalidInput, 'no destination given' if destination.blank?
39
+ raise Hcloud::Error::InvalidInput, 'no gateway given' if gateway.blank?
40
+
30
41
  prepare_request('actions/delete_route', j: COLLECT_ARGS.call(__method__, binding))
31
42
  end
43
+
44
+ def change_ip_range(ip_range:)
45
+ raise Hcloud::Error::InvalidInput, 'no ip_range given' if ip_range.blank?
46
+
47
+ prepare_request('actions/change_ip_range', j: COLLECT_ARGS.call(__method__, binding))
48
+ end
32
49
  end
33
50
  end
@@ -14,6 +14,9 @@ module Hcloud
14
14
  end
15
15
 
16
16
  def create(name:, ip_range:, subnets: nil, routes: nil, labels: {})
17
+ raise Hcloud::Error::InvalidInput, 'no name given' if name.blank?
18
+ raise Hcloud::Error::InvalidInput, 'no IP range given' if ip_range.blank?
19
+
17
20
  prepare_request(
18
21
  'networks', j: COLLECT_ARGS.call(__method__, binding),
19
22
  expected_code: 201
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class PlacementGroup
5
+ require 'hcloud/placement_group_resource'
6
+
7
+ include EntryLoader
8
+
9
+ schema(
10
+ created: :time
11
+ )
12
+
13
+ updatable :name
14
+ destructible
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class PlacementGroupResource < AbstractResource
5
+ filter_attributes :type, :name, :label_selector
6
+
7
+ bind_to PlacementGroup
8
+
9
+ def [](arg)
10
+ return find_by(name: arg) if arg.is_a?(String)
11
+
12
+ super
13
+ end
14
+
15
+ # currently only spread is available
16
+ def create(name:, type: 'spread', labels: {})
17
+ if type.to_s != 'spread'
18
+ raise Hcloud::Error::InvalidInput, "invalid type #{type.inspect}, only 'spread' is allowed"
19
+ end
20
+ raise Hcloud::Error::InvalidInput, 'no name given' if name.blank?
21
+
22
+ prepare_request(
23
+ 'placement_groups', j: COLLECT_ARGS.call(__method__, binding),
24
+ expected_code: 201
25
+ ) do |response|
26
+ PlacementGroup.new(client, response.parsed_json[:placement_group])
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class PrimaryIP
5
+ require 'hcloud/primary_ip_resource'
6
+
7
+ include EntryLoader
8
+
9
+ schema(
10
+ datacenter: Datacenter,
11
+ created: :time
12
+ )
13
+
14
+ protectable :delete
15
+ updatable :name, :auto_delete
16
+ destructible
17
+
18
+ def assign(assignee_id:, assignee_type: 'server')
19
+ raise Hcloud::Error::InvalidInput, 'no assignee_id given' if assignee_id.nil?
20
+ raise Hcloud::Error::InvalidInput, 'no assignee_type given' if assignee_type.nil?
21
+
22
+ prepare_request('actions/assign', j: COLLECT_ARGS.call(__method__, binding))
23
+ end
24
+
25
+ def unassign
26
+ prepare_request('actions/unassign', method: :post)
27
+ end
28
+
29
+ def change_dns_ptr(ip:, dns_ptr:)
30
+ raise Hcloud::Error::InvalidInput, 'no IP given' if ip.blank?
31
+
32
+ prepare_request('actions/change_dns_ptr', j: { ip: ip, dns_ptr: dns_ptr })
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hcloud
4
+ class PrimaryIPResource < AbstractResource
5
+ filter_attributes :name, :label_selector, :ip
6
+
7
+ bind_to PrimaryIP
8
+
9
+ def [](arg)
10
+ case arg
11
+ when Integer then find_by(id: arg)
12
+ when String then find_by(name: arg)
13
+ end
14
+ end
15
+
16
+ def create(
17
+ name:,
18
+ type:,
19
+ assignee_id: nil,
20
+ assignee_type: 'server',
21
+ datacenter: nil,
22
+ auto_delete: nil,
23
+ labels: {}
24
+ )
25
+ raise Hcloud::Error::InvalidInput, 'no name given' if name.blank?
26
+
27
+ unless %w[ipv4 ipv6].include?(type.to_s)
28
+ raise Hcloud::Error::InvalidInput, 'invalid type given'
29
+ end
30
+
31
+ raise Hcloud::Error::InvalidInput, 'no assignee_type given' if assignee_type.blank?
32
+
33
+ if assignee_id.nil? && datacenter.nil?
34
+ raise Hcloud::Error::InvalidInput, 'either assignee_id or datacenter must be given'
35
+ end
36
+
37
+ prepare_request(
38
+ 'primary_ips', j: COLLECT_ARGS.call(__method__, binding),
39
+ expected_code: 201
40
+ ) do |response|
41
+ action = Action.new(client, response[:action]) if response[:action]
42
+ [action, PrimaryIP.new(client, response[:primary_ip])]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Hcloud
6
+ class ResourceLoader
7
+ def initialize(schema, client:)
8
+ @schema = schema
9
+ @client = client
10
+ end
11
+
12
+ def load(data)
13
+ load_with_schema(@schema, data)
14
+ end
15
+
16
+ private
17
+
18
+ def load_with_schema(schema, data)
19
+ if schema.respond_to?(:call)
20
+ schema.call(data, @client)
21
+ elsif schema.is_a?(Array) && schema.count.positive? && data.is_a?(Array)
22
+ load_array(schema, data)
23
+ elsif schema.is_a?(Hash) && data.is_a?(Hash)
24
+ load_hash(schema, data)
25
+ else
26
+ load_single_item(schema, data)
27
+ end
28
+ end
29
+
30
+ def load_array(schema, data)
31
+ data.map do |item|
32
+ load_with_schema(schema[0], item)
33
+ end
34
+ end
35
+
36
+ def load_hash(schema, data)
37
+ data.map do |key, value|
38
+ [key, load_with_schema(schema[key], value)]
39
+ end.to_h
40
+ end
41
+
42
+ def load_single_item(definition, value)
43
+ if definition == :time
44
+ return value ? Time.parse(value) : nil
45
+ end
46
+
47
+ if definition.is_a?(Class) && definition.include?(EntryLoader)
48
+ return if value.nil?
49
+
50
+ # If value is an integer, this is the id of an object which's class can be
51
+ # retreived from definition. Load a future object that can on access retreive the
52
+ # data from the api and convert it to a proper object.
53
+ return Future.new(@client, definition, value) if value.is_a?(Integer)
54
+
55
+ # Otherwise the value *is* the content of the object
56
+ return definition.new(@client, value)
57
+ end
58
+
59
+ value
60
+ end
61
+ end
62
+ end
data/lib/hcloud/server.rb CHANGED
@@ -12,7 +12,24 @@ module Hcloud
12
12
  datacenter: Datacenter,
13
13
  image: Image,
14
14
  iso: Iso,
15
+ load_balancers: [LoadBalancer],
16
+ placement_group: PlacementGroup,
15
17
  private_net: [Network],
18
+ public_net: {
19
+ ipv4: lambda do |data, client|
20
+ Future.new(client, PrimaryIP, data[:id]) if data.to_h[:id].is_a?(Integer)
21
+ end,
22
+ ipv6: lambda do |data, client|
23
+ Future.new(client, PrimaryIP, data[:id]) if data.to_h[:id].is_a?(Integer)
24
+ end,
25
+ floating_ips: [FloatingIP],
26
+ firewalls: [
27
+ lambda do |data, client|
28
+ Future.new(client, Firewall, data[:id], raw_data: data) if data.to_h[:id].is_a?(Integer)
29
+ end
30
+ ]
31
+ # firewalls: [{ id: Firewall }]
32
+ },
16
33
  volumes: [Volume]
17
34
  )
18
35
 
@@ -21,6 +38,7 @@ module Hcloud
21
38
  destructible
22
39
 
23
40
  has_actions
41
+ has_metrics
24
42
 
25
43
  def enable_rescue(type: 'linux64', ssh_keys: [])
26
44
  query = COLLECT_ARGS.call(__method__, binding)
@@ -37,10 +55,15 @@ module Hcloud
37
55
  end
38
56
 
39
57
  def rebuild(image:)
58
+ raise Hcloud::Error::InvalidInput, 'no image given' if image.blank?
59
+
40
60
  prepare_request('actions/rebuild', j: { image: image }) { |j| j[:root_password] }
41
61
  end
42
62
 
43
- def change_type(server_type:, upgrade_disk: nil)
63
+ def change_type(server_type:, upgrade_disk:)
64
+ raise Hcloud::Error::InvalidInput, 'no server_type given' if server_type.blank?
65
+ raise Hcloud::Error::InvalidInput, 'no upgrade_disk given' if upgrade_disk.nil?
66
+
44
67
  prepare_request('actions/change_type', j: COLLECT_ARGS.call(__method__, binding))
45
68
  end
46
69
 
@@ -51,21 +74,47 @@ module Hcloud
51
74
  end
52
75
 
53
76
  def attach_iso(iso:)
77
+ raise Hcloud::Error::InvalidInput, 'no iso given' if iso.blank?
78
+
54
79
  prepare_request('actions/attach_iso', j: { iso: iso })
55
80
  end
56
81
 
57
82
  def attach_to_network(network:, ip: nil, alias_ips: nil)
83
+ raise Hcloud::Error::InvalidInput, 'no network given' if network.nil?
84
+
58
85
  prepare_request('actions/attach_to_network', j: COLLECT_ARGS.call(__method__, binding))
59
86
  end
60
87
 
61
88
  def detach_from_network(network:)
89
+ raise Hcloud::Error::InvalidInput, 'no network given' if network.nil?
90
+
62
91
  prepare_request('actions/detach_from_network', j: { network: network })
63
92
  end
64
93
 
94
+ def add_to_placement_group(placement_group:)
95
+ raise Hcloud::Error::InvalidInput, 'no placement_group given' if placement_group.nil?
96
+
97
+ prepare_request('actions/add_to_placement_group', j: COLLECT_ARGS.call(__method__, binding))
98
+ end
99
+
100
+ def change_alias_ips(alias_ips:, network:)
101
+ raise Hcloud::Error::InvalidInput, 'no alias_ips given' if alias_ips.to_a.count.zero?
102
+ raise Hcloud::Error::InvalidInput, 'no network given' if network.nil?
103
+
104
+ prepare_request('actions/change_alias_ips', j: COLLECT_ARGS.call(__method__, binding))
105
+ end
106
+
107
+ def change_dns_ptr(ip:, dns_ptr:)
108
+ raise Hcloud::Error::InvalidInput, 'no IP given' if ip.blank?
109
+ raise Hcloud::Error::InvalidInput, 'no dns_ptr given' if dns_ptr.blank?
110
+
111
+ prepare_request('actions/change_dns_ptr', j: COLLECT_ARGS.call(__method__, binding))
112
+ end
113
+
65
114
  %w[
66
115
  poweron poweroff shutdown reboot reset
67
116
  disable_rescue disable_backup detach_iso
68
- request_console
117
+ request_console remove_from_placement_group
69
118
  ].each do |action|
70
119
  define_method(action) do
71
120
  prepare_request("actions/#{action}", method: :post)
@@ -12,15 +12,23 @@ module Hcloud
12
12
  location: nil,
13
13
  start_after_create: nil,
14
14
  ssh_keys: [],
15
+ public_net: nil,
16
+ firewalls: nil,
15
17
  networks: [],
18
+ placement_group: nil,
16
19
  user_data: nil,
20
+ volumes: nil,
21
+ automount: nil,
17
22
  labels: {})
18
23
  prepare_request('servers', j: COLLECT_ARGS.call(__method__, binding),
19
24
  expected_code: 201) do |response|
20
25
  [
21
26
  Action.new(client, response.parsed_json[:action]),
22
27
  Server.new(client, response.parsed_json[:server]),
23
- response.parsed_json[:root_password]
28
+ response.parsed_json[:root_password],
29
+ response.parsed_json[:next_actions].to_a.map do |action|
30
+ Action.new(client, action)
31
+ end
24
32
  ]
25
33
  end
26
34
  end
@@ -6,6 +6,10 @@ module Hcloud
6
6
 
7
7
  include EntryLoader
8
8
 
9
+ schema(
10
+ created: :time
11
+ )
12
+
9
13
  updatable :name
10
14
  destructible
11
15
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Hcloud
4
4
  class SSHKeyResource < AbstractResource
5
- filter_attributes :name, :label_selector
5
+ filter_attributes :name, :label_selector, :fingerprint
6
6
 
7
7
  def [](arg)
8
8
  case arg
@@ -12,6 +12,12 @@ module Hcloud
12
12
  end
13
13
 
14
14
  def create(name:, public_key:, labels: {})
15
+ raise Hcloud::Error::InvalidInput, 'no name given' if name.blank?
16
+
17
+ unless public_key.to_s.starts_with?('ssh')
18
+ raise Hcloud::Error::InvalidInput, 'no valid SSH key given'
19
+ end
20
+
15
21
  prepare_request(
16
22
  'ssh_keys', j: COLLECT_ARGS.call(__method__, binding),
17
23
  expected_code: 201
@@ -30,7 +30,7 @@ module Hcloud
30
30
  def parsed_json
31
31
  return {} if code == 204
32
32
 
33
- @parsed_json ||= Oj.load(body, symbol_keys: true).tap do |json|
33
+ @parsed_json ||= Oj.load(body, symbol_keys: true, mode: :compat).tap do |json|
34
34
  next unless request.hydra
35
35
 
36
36
  check_for_error(
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hcloud
4
- VERSION = '1.1.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/lib/hcloud/volume.rb CHANGED
@@ -17,7 +17,9 @@ module Hcloud
17
17
 
18
18
  has_actions
19
19
 
20
- def attach(server:, automount:)
20
+ def attach(server:, automount: nil)
21
+ raise Hcloud::Error::InvalidInput, 'no server given' if server.nil?
22
+
21
23
  prepare_request('actions/attach', j: COLLECT_ARGS.call(__method__, binding))
22
24
  end
23
25
 
@@ -26,6 +28,8 @@ module Hcloud
26
28
  end
27
29
 
28
30
  def resize(size:)
31
+ raise Hcloud::Error::InvalidInput, 'invalid size given' unless size.to_i > self.size
32
+
29
33
  prepare_request('actions/resize', j: COLLECT_ARGS.call(__method__, binding))
30
34
  end
31
35
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Hcloud
4
4
  class VolumeResource < AbstractResource
5
- filter_attributes :name, :label_selector
5
+ filter_attributes :name, :label_selector, :status
6
6
 
7
7
  def [](arg)
8
8
  case arg
@@ -12,6 +12,12 @@ module Hcloud
12
12
  end
13
13
 
14
14
  def create(size:, name:, automount: nil, format: nil, location: nil, server: nil, labels: {})
15
+ raise Hcloud::Error::InvalidInput, 'no name given' if name.blank?
16
+ raise Hcloud::Error::InvalidInput, 'invalid size given' unless size.to_i >= 10
17
+ if location.blank? && server.nil?
18
+ raise Hcloud::Error::InvalidInput, 'location or server must be given'
19
+ end
20
+
15
21
  prepare_request(
16
22
  'volumes', j: COLLECT_ARGS.call(__method__, binding),
17
23
  expected_code: 201