]>
git.proxmox.com Git - pve-network.git/blob - src/PVE/API2/Network/SDN/Subnets.pm
1 package PVE
::API2
::Network
::SDN
::Subnets
;
7 use PVE
::Tools
qw(extract_param);
8 use PVE
::Cluster
qw(cfs_read_file cfs_write_file);
9 use PVE
::Exception
qw(raise raise_param_exc);
10 use PVE
::Network
::SDN
;
11 use PVE
::Network
::SDN
::Subnets
;
12 use PVE
::Network
::SDN
::SubnetPlugin
;
13 use PVE
::Network
::SDN
::Vnets
;
14 use PVE
::Network
::SDN
::Zones
;
15 use PVE
::Network
::SDN
::Ipams
;
16 use PVE
::Network
::SDN
::Ipams
::Plugin
;
18 use Storable
qw(dclone);
19 use PVE
::JSONSchema
qw(get_standard_option);
20 use PVE
::RPCEnvironment
;
24 use base
qw(PVE::RESTHandler);
26 my $api_sdn_subnets_config = sub {
29 my $scfg = dclone
(PVE
::Network
::SDN
::Subnets
::sdn_subnets_config
($cfg, $id));
30 $scfg->{subnet
} = $id;
31 $scfg->{digest
} = $cfg->{digest
};
32 $scfg->{'dhcp-range'} = PVE
::Network
::SDN
::Subnets
::get_dhcp_ranges
($scfg);
37 my $api_sdn_vnets_config = sub {
40 my $scfg = dclone
(PVE
::Network
::SDN
::Vnets
::sdn_vnets_config
($cfg, $id));
42 $scfg->{digest
} = $cfg->{digest
};
47 my $check_vnet_access = sub {
48 my ($vnet, $privs) = @_;
50 my $cfg = PVE
::Network
::SDN
::Vnets
::config
();
51 my $rpcenv = PVE
::RPCEnvironment
::get
();
52 my $authuser = $rpcenv->get_user();
53 my $scfg = &$api_sdn_vnets_config($cfg, $vnet);
54 my $zoneid = $scfg->{zone
};
55 $rpcenv->check_any($authuser, "/sdn/zones/$zoneid/$vnet", $privs);
58 __PACKAGE__-
>register_method ({
62 description
=> "SDN subnets index.",
64 description
=> "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/<zone>/<vnet>'",
68 additionalProperties
=> 0,
70 vnet
=> get_standard_option
('pve-sdn-vnet-id'),
74 description
=> "Display running config.",
79 description
=> "Display pending config.",
89 links
=> [ { rel
=> 'child', href
=> "{subnet}" } ],
94 my $vnetid = $param->{vnet
};
95 my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
96 &$check_vnet_access($vnetid, $privs);
99 if($param->{pending
}) {
100 my $running_cfg = PVE
::Network
::SDN
::running_config
();
101 my $config = PVE
::Network
::SDN
::Subnets
::config
();
102 $cfg = PVE
::Network
::SDN
::pending_config
($running_cfg, $config, 'subnets');
103 } elsif ($param->{running
}) {
104 my $running_cfg = PVE
::Network
::SDN
::running_config
();
105 $cfg = $running_cfg->{subnets
};
107 $cfg = PVE
::Network
::SDN
::Subnets
::config
();
110 my @sids = PVE
::Network
::SDN
::Subnets
::sdn_subnets_ids
($cfg);
112 foreach my $id (@sids) {
113 my $scfg = &$api_sdn_subnets_config($cfg, $id);
114 next if !$scfg->{vnet
} || $scfg->{vnet
} ne $vnetid;
121 __PACKAGE__-
>register_method ({
125 description
=> "Read sdn subnet configuration.",
127 description
=> "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/<zone>/<vnet>'",
131 additionalProperties
=> 0,
133 vnet
=> get_standard_option
('pve-sdn-vnet-id'),
134 subnet
=> get_standard_option
('pve-sdn-subnet-id', {
135 completion
=> \
&PVE
::Network
::SDN
::Subnets
::complete_sdn_subnets
,
140 description
=> "Display running config.",
145 description
=> "Display pending config.",
149 returns
=> { type
=> 'object' },
153 my $vnet = extract_param
($param, 'vnet');
154 my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
155 &$check_vnet_access($vnet, $privs);
158 if($param->{pending
}) {
159 my $running_cfg = PVE
::Network
::SDN
::running_config
();
160 my $config = PVE
::Network
::SDN
::Subnets
::config
();
161 $cfg = PVE
::Network
::SDN
::pending_config
($running_cfg, $config, 'subnets');
162 } elsif ($param->{running
}) {
163 my $running_cfg = PVE
::Network
::SDN
::running_config
();
164 $cfg = $running_cfg->{subnets
};
166 $cfg = PVE
::Network
::SDN
::Subnets
::config
();
169 my $scfg = &$api_sdn_subnets_config($cfg, $param->{subnet
});
171 raise_param_exc
({ vnet
=> "wrong vnet"}) if $vnet ne $scfg->{vnet
};
176 __PACKAGE__-
>register_method ({
181 description
=> "Create a new sdn subnet object.",
183 description
=> "Require 'SDN.Allocate' permission on '/sdn/zones/<zone>/<vnet>'",
186 parameters
=> PVE
::Network
::SDN
::SubnetPlugin-
>createSchema(),
187 returns
=> { type
=> 'null' },
191 my $type = extract_param
($param, 'type');
192 my $cidr = extract_param
($param, 'subnet');
194 my $vnet = $param->{vnet
};
195 my $privs = [ 'SDN.Allocate' ];
196 &$check_vnet_access($vnet, $privs);
198 # create /etc/pve/sdn directory
199 PVE
::Cluster
::check_cfs_quorum
();
200 mkdir("/etc/pve/sdn") if ! -d
'/etc/pve/sdn';
202 PVE
::Network
::SDN
::lock_sdn_config
(
205 my $cfg = PVE
::Network
::SDN
::Subnets
::config
();
206 my $zone_cfg = PVE
::Network
::SDN
::Zones
::config
();
207 my $vnet_cfg = PVE
::Network
::SDN
::Vnets
::config
();
208 my $vnet = $param->{vnet
};
209 my $zoneid = $vnet_cfg->{ids
}->{$vnet}->{zone
};
210 my $zone = $zone_cfg->{ids
}->{$zoneid};
211 my $id = $cidr =~ s/\//-/r
;
214 my $opts = PVE
::Network
::SDN
::SubnetPlugin-
>check_config($id, $param, 1, 1);
217 if ($scfg = PVE
::Network
::SDN
::Subnets
::sdn_subnets_config
($cfg, $id, 1)) {
218 die "sdn subnet object ID '$id' already defined\n";
221 $cfg->{ids
}->{$id} = $opts;
223 my $subnet = PVE
::Network
::SDN
::Subnets
::sdn_subnets_config
($cfg, $id);
224 PVE
::Network
::SDN
::SubnetPlugin-
>on_update_hook($zone, $id, $subnet);
226 PVE
::Network
::SDN
::Subnets
::write_config
($cfg);
228 }, "create sdn subnet object failed");
233 __PACKAGE__-
>register_method ({
238 description
=> "Update sdn subnet object configuration.",
240 description
=> "Require 'SDN.Allocate' permission on '/sdn/zones/<zone>/<vnet>'",
243 parameters
=> PVE
::Network
::SDN
::SubnetPlugin-
>updateSchema(),
244 returns
=> { type
=> 'null' },
248 my $id = extract_param
($param, 'subnet');
249 my $digest = extract_param
($param, 'digest');
250 my $vnet = $param->{vnet
};
252 my $privs = [ 'SDN.Allocate' ];
253 &$check_vnet_access($vnet, $privs);
255 PVE
::Network
::SDN
::lock_sdn_config
(
258 my $cfg = PVE
::Network
::SDN
::Subnets
::config
();
259 my $zone_cfg = PVE
::Network
::SDN
::Zones
::config
();
260 my $vnet_cfg = PVE
::Network
::SDN
::Vnets
::config
();
261 my $zoneid = $vnet_cfg->{ids
}->{$vnet}->{zone
};
262 my $zone = $zone_cfg->{ids
}->{$zoneid};
264 my $scfg = &$api_sdn_subnets_config($cfg, $id);
266 PVE
::SectionConfig
::assert_if_modified
($cfg, $digest);
268 my $opts = PVE
::Network
::SDN
::SubnetPlugin-
>check_config($id, $param, 0, 1);
269 $cfg->{ids
}->{$id} = $opts;
271 raise_param_exc
({ ipam
=> "you can't change ipam"}) if $opts->{ipam
} && $scfg->{ipam
} && $opts->{ipam
} ne $scfg->{ipam
};
273 my $subnet = PVE
::Network
::SDN
::Subnets
::sdn_subnets_config
($cfg, $id);
274 PVE
::Network
::SDN
::SubnetPlugin-
>on_update_hook($zone, $id, $subnet, $scfg);
276 PVE
::Network
::SDN
::Subnets
::write_config
($cfg);
278 }, "update sdn subnet object failed");
283 __PACKAGE__-
>register_method ({
288 description
=> "Delete sdn subnet object configuration.",
290 description
=> "Require 'SDN.Allocate' permission on '/sdn/zones/<zone>/<vnet>'",
294 additionalProperties
=> 0,
296 vnet
=> get_standard_option
('pve-sdn-vnet-id'),
297 subnet
=> get_standard_option
('pve-sdn-subnet-id', {
298 completion
=> \
&PVE
::Network
::SDN
::Subnets
::complete_sdn_subnets
,
302 returns
=> { type
=> 'null' },
306 my $id = extract_param
($param, 'subnet');
307 my $vnet = extract_param
($param, 'vnet');
308 my $privs = [ 'SDN.Allocate' ];
309 &$check_vnet_access($vnet, $privs);
311 PVE
::Network
::SDN
::lock_sdn_config
(
313 my $cfg = PVE
::Network
::SDN
::Subnets
::config
();
315 my $scfg = PVE
::Network
::SDN
::Subnets
::sdn_subnets_config
($cfg, $id, 1);
317 my $vnets_cfg = PVE
::Network
::SDN
::Vnets
::config
();
319 PVE
::Network
::SDN
::SubnetPlugin-
>on_delete_hook($id, $cfg, $vnets_cfg);
321 my $zone_cfg = PVE
::Network
::SDN
::Zones
::config
();
322 my $zoneid = $vnets_cfg->{ids
}->{$vnet}->{zone
};
323 my $zone = $zone_cfg->{ids
}->{$zoneid};
325 PVE
::Network
::SDN
::Subnets
::del_subnet
($zone, $id, $scfg);
327 delete $cfg->{ids
}->{$id};
329 PVE
::Network
::SDN
::Subnets
::write_config
($cfg);
331 }, "delete sdn subnet object failed");