]>
git.proxmox.com Git - pve-manager.git/blob - PVE/API2/Network.pm
35b077b97baf6495f9cbb05d5a61cefda6967f33
1 package PVE
::API2
::Network
;
7 use PVE
::Tools
qw(extract_param);
10 use PVE
::Exception
qw(raise_param_exc);
12 use PVE
::RPCEnvironment
;
13 use PVE
::JSONSchema
qw(get_standard_option);
14 use PVE
::AccessControl
;
17 use base
qw(PVE::RESTHandler);
19 my $iflockfn = "/etc/network/.pve-interfaces.lock";
21 my $bond_mode_enum = [
33 description
=> "Automatically start interface on boot.",
38 description
=> "Specify the iterfaces you want to add to your bridge.",
40 type
=> 'string', format
=> 'pve-iface-list',
43 description
=> "Specify the interfaces used by the bonding device.",
45 type
=> 'string', format
=> 'pve-iface-list',
48 description
=> "Bonding mode.",
50 type
=> 'string', enum
=> $bond_mode_enum,
53 description
=> 'Default gateway address.',
54 type
=> 'string', format
=> 'ipv4',
58 description
=> 'Network mask.',
59 type
=> 'string', format
=> 'ipv4mask',
61 requires
=> 'address',
64 description
=> 'IP address.',
65 type
=> 'string', format
=> 'ipv4',
67 requires
=> 'netmask',
71 sub json_config_properties
{
74 foreach my $opt (keys %$confdesc) {
75 $prop->{$opt} = $confdesc->{$opt};
81 __PACKAGE__-
>register_method({
85 permissions
=> { user
=> 'all' },
86 description
=> "List available networks",
89 additionalProperties
=> 0,
91 node
=> get_standard_option
('pve-node'),
93 description
=> "Only list specific interface types.",
95 enum
=> ['bond', 'bridge', 'alias', 'eth'],
106 links
=> [ { rel
=> 'child', href
=> "{iface}" } ],
111 my $rpcenv = PVE
::RPCEnvironment
::get
();
113 my $tmp = PVE
::INotify
::read_file
('interfaces', 1);
114 my $config = $tmp->{data
};
115 my $changes = $tmp->{changes
};
117 $rpcenv->set_result_attrib('changes', $changes) if $changes;
119 delete $config->{lo
}; # do not list the loopback device
121 if ($param->{type
}) {
122 foreach my $k (keys %$config) {
123 delete $config->{$k} if $param->{type
} ne $config->{$k}->{type
};
127 return PVE
::RESTHandler
::hash_to_array
($config, 'iface');
130 __PACKAGE__-
>register_method({
131 name
=> 'revert_network_changes',
135 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
138 description
=> "Revert network configuration changes.",
141 additionalProperties
=> 0,
143 node
=> get_standard_option
('pve-node'),
146 returns
=> { type
=> "null" },
150 unlink "/etc/network/interfaces.new";
155 my $check_duplicate_gateway = sub {
156 my ($config, $newiface) = @_;
158 foreach my $iface (keys %$config) {
159 raise_param_exc
({ gateway
=> "Default gateway already exists on interface '$iface'." })
160 if ($newiface ne $iface) && $config->{$iface}->{gateway
};
164 my $check_ipv4_settings = sub {
165 my ($address, $netmask) = @_;
167 my $binip = Net
::IP
::ip_iptobin
($address, 4);
168 my $binmask = Net
::IP
::ip_iptobin
($netmask, 4);
169 my $broadcast = Net
::IP
::ip_iptobin
('255.255.255.255', 4);
170 my $binhost = $binip | $binmask;
172 raise_param_exc
({ address
=> "$address is not a valid host ip address." })
173 if ($binhost eq $binmask) || ($binhost eq $broadcast);
176 __PACKAGE__-
>register_method({
177 name
=> 'create_network',
181 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
183 description
=> "Create network device configuration",
187 additionalProperties
=> 0,
188 properties
=> json_config_properties
({
189 node
=> get_standard_option
('pve-node'),
190 iface
=> get_standard_option
('pve-iface')}),
192 returns
=> { type
=> 'null' },
196 my $node = extract_param
($param, 'node');
197 my $iface = extract_param
($param, 'iface');
200 my $config = PVE
::INotify
::read_file
('interfaces');
202 raise_param_exc
({ iface
=> "interface already exists" })
203 if $config->{$iface};
205 &$check_duplicate_gateway($config, $iface)
206 if $param->{gateway
};
208 &$check_ipv4_settings($param->{address
}, $param->{netmask
})
209 if $param->{address
};
211 $param->{method} = $param->{address
} ?
'static' : 'manual';
213 $config->{$iface} = $param;
215 PVE
::INotify
::write_file
('interfaces', $config);
218 PVE
::Tools
::lock_file
($iflockfn, 10, $code);
224 __PACKAGE__-
>register_method({
225 name
=> 'update_network',
229 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
231 description
=> "Update network device configuration",
235 additionalProperties
=> 0,
236 properties
=> json_config_properties
({
237 node
=> get_standard_option
('pve-node'),
238 iface
=> get_standard_option
('pve-iface'),
240 type
=> 'string', format
=> 'pve-configid-list',
241 description
=> "A list of settings you want to delete.",
245 returns
=> { type
=> 'null' },
249 my $node = extract_param
($param, 'node');
250 my $iface = extract_param
($param, 'iface');
251 my $delete = extract_param
($param, 'delete');
254 my $config = PVE
::INotify
::read_file
('interfaces');
256 raise_param_exc
({ iface
=> "interface does not exist" })
257 if !$config->{$iface};
259 foreach my $k (PVE
::Tools
::split_list
($delete)) {
260 delete $config->{$iface}->{$k};
263 &$check_duplicate_gateway($config, $iface)
264 if $param->{gateway
};
266 &$check_ipv4_settings($param->{address
}, $param->{netmask
})
267 if $param->{address
};
269 $param->{method} = $param->{address
} ?
'static' : 'manual';
271 foreach my $k (keys %$param) {
272 $config->{$iface}->{$k} = $param->{$k};
275 PVE
::INotify
::write_file
('interfaces', $config);
278 PVE
::Tools
::lock_file
($iflockfn, 10, $code);
284 __PACKAGE__-
>register_method({
285 name
=> 'network_config',
289 check
=> ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
291 description
=> "Read network device configuration",
294 additionalProperties
=> 0,
296 node
=> get_standard_option
('pve-node'),
297 iface
=> get_standard_option
('pve-iface'),
314 my $config = PVE
::INotify
::read_file
('interfaces');
316 raise_param_exc
({ iface
=> "interface does not exist" })
317 if !$config->{$param->{iface
}};
319 return $config->{$param->{iface
}};
322 __PACKAGE__-
>register_method({
323 name
=> 'delete_network',
327 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
329 description
=> "Delete network device configuration",
333 additionalProperties
=> 0,
335 node
=> get_standard_option
('pve-node'),
336 iface
=> get_standard_option
('pve-iface'),
339 returns
=> { type
=> 'null' },
344 my $config = PVE
::INotify
::read_file
('interfaces');
346 raise_param_exc
({ iface
=> "interface does not exist" })
347 if !$config->{$param->{iface
}};
349 delete $config->{$param->{iface
}};
351 PVE
::INotify
::write_file
('interfaces', $config);
354 PVE
::Tools
::lock_file
($iflockfn, 10, $code);