]> git.proxmox.com Git - pve-network.git/blame - PVE/API2/Network/SDN/Subnets.pm
move dns options from subnets to zone
[pve-network.git] / PVE / API2 / Network / SDN / Subnets.pm
CommitLineData
c33dd818
AD
1package PVE::API2::Network::SDN::Subnets;
2
3use strict;
4use warnings;
5
6use PVE::SafeSyslog;
7use PVE::Tools qw(extract_param);
8use PVE::Cluster qw(cfs_read_file cfs_write_file);
70b03506 9use PVE::Exception qw(raise raise_param_exc);
c33dd818
AD
10use PVE::Network::SDN;
11use PVE::Network::SDN::Subnets;
12use PVE::Network::SDN::SubnetPlugin;
58a7773a 13use PVE::Network::SDN::Vnets;
4ad78442 14use PVE::Network::SDN::Zones;
70b03506
AD
15use PVE::Network::SDN::Ipams;
16use PVE::Network::SDN::Ipams::Plugin;
c33dd818
AD
17
18use Storable qw(dclone);
19use PVE::JSONSchema qw(get_standard_option);
20use PVE::RPCEnvironment;
21
22use PVE::RESTHandler;
23
24use base qw(PVE::RESTHandler);
25
26my $api_sdn_subnets_config = sub {
27 my ($cfg, $id) = @_;
28
29 my $scfg = dclone(PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id));
30 $scfg->{subnet} = $id;
31 $scfg->{cidr} = $id =~ s/-/\//r;
32 $scfg->{digest} = $cfg->{digest};
33
34 return $scfg;
35};
36
37__PACKAGE__->register_method ({
38 name => 'index',
39 path => '',
40 method => 'GET',
41 description => "SDN subnets index.",
42 permissions => {
43 description => "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/subnets/<subnet>'",
44 user => 'all',
45 },
46 parameters => {
47 additionalProperties => 0,
3926d9a7
AD
48 properties => {
49 vnet => get_standard_option('pve-sdn-vnet-id'),
6f5f42e4
AD
50 running => {
51 type => 'boolean',
52 optional => 1,
53 description => "Display running config.",
54 },
55 pending => {
56 type => 'boolean',
57 optional => 1,
58 description => "Display pending config.",
59 },
60 },
c33dd818
AD
61 },
62 returns => {
63 type => 'array',
64 items => {
65 type => "object",
66 properties => {},
67 },
68 links => [ { rel => 'child', href => "{subnet}" } ],
69 },
70 code => sub {
71 my ($param) = @_;
72
73 my $rpcenv = PVE::RPCEnvironment::get();
74 my $authuser = $rpcenv->get_user();
75
3926d9a7 76 my $vnetid = $param->{vnet};
c33dd818 77
6f5f42e4
AD
78 my $cfg = {};
79 if($param->{pending}) {
80 my $running_cfg = PVE::Network::SDN::config();
81 my $config = PVE::Network::SDN::Subnets::config();
82 $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'subnets');
83 } elsif ($param->{running}) {
84 my $running_cfg = PVE::Network::SDN::config();
85 $cfg = $running_cfg->{subnets};
86 } else {
87 $cfg = PVE::Network::SDN::Subnets::config();
88 }
c33dd818
AD
89
90 my @sids = PVE::Network::SDN::Subnets::sdn_subnets_ids($cfg);
91 my $res = [];
92 foreach my $id (@sids) {
93 my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
3926d9a7 94 next if !$rpcenv->check_any($authuser, "/sdn/vnets/$vnetid/subnets/$id", $privs, 1);
c33dd818
AD
95
96 my $scfg = &$api_sdn_subnets_config($cfg, $id);
3926d9a7 97 next if !$scfg->{vnet} || $scfg->{vnet} ne $vnetid;
c33dd818
AD
98 push @$res, $scfg;
99 }
100
101 return $res;
102 }});
103
104__PACKAGE__->register_method ({
105 name => 'read',
106 path => '{subnet}',
107 method => 'GET',
108 description => "Read sdn subnet configuration.",
109 permissions => {
3926d9a7 110 check => ['perm', '/sdn/vnets/{vnet}/subnets/{subnet}', ['SDN.Allocate']],
c33dd818
AD
111 },
112
113 parameters => {
114 additionalProperties => 0,
115 properties => {
3926d9a7 116 vnet => get_standard_option('pve-sdn-vnet-id'),
c33dd818
AD
117 subnet => get_standard_option('pve-sdn-subnet-id', {
118 completion => \&PVE::Network::SDN::Subnets::complete_sdn_subnets,
119 }),
6f5f42e4
AD
120 running => {
121 type => 'boolean',
122 optional => 1,
123 description => "Display running config.",
124 },
125 pending => {
126 type => 'boolean',
127 optional => 1,
128 description => "Display pending config.",
129 },
130 },
c33dd818
AD
131 },
132 returns => { type => 'object' },
133 code => sub {
134 my ($param) = @_;
135
6f5f42e4
AD
136 my $cfg = {};
137 if($param->{pending}) {
138 my $running_cfg = PVE::Network::SDN::config();
139 my $config = PVE::Network::SDN::Subnets::config();
140 $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'subnets');
141 } elsif ($param->{running}) {
142 my $running_cfg = PVE::Network::SDN::config();
143 $cfg = $running_cfg->{subnets};
144 } else {
145 $cfg = PVE::Network::SDN::Subnets::config();
146 }
147
3926d9a7
AD
148 my $scfg = &$api_sdn_subnets_config($cfg, $param->{subnet});
149
150 raise_param_exc({ vnet => "wrong vnet"}) if $param->{vnet} ne $scfg->{vnet};
c33dd818 151
3926d9a7 152 return $scfg;
c33dd818
AD
153 }});
154
155__PACKAGE__->register_method ({
156 name => 'create',
157 protected => 1,
158 path => '',
159 method => 'POST',
160 description => "Create a new sdn subnet object.",
161 permissions => {
3926d9a7 162 check => ['perm', '/sdn/vnets/{vnet}/subnets', ['SDN.Allocate']],
c33dd818
AD
163 },
164 parameters => PVE::Network::SDN::SubnetPlugin->createSchema(),
165 returns => { type => 'null' },
166 code => sub {
167 my ($param) = @_;
168
169 my $type = extract_param($param, 'type');
170 my $cidr = extract_param($param, 'subnet');
171 my $id = $cidr =~ s/\//-/r;
172
173 # create /etc/pve/sdn directory
174 PVE::Cluster::check_cfs_quorum();
175 mkdir("/etc/pve/sdn") if ! -d '/etc/pve/sdn';
176
177 PVE::Network::SDN::lock_sdn_config(
178 sub {
179
180 my $cfg = PVE::Network::SDN::Subnets::config();
4ad78442
AD
181 my $zone_cfg = PVE::Network::SDN::Zones::config();
182 my $vnet_cfg = PVE::Network::SDN::Vnets::config();
183 my $vnet = $param->{vnet};
184 my $zoneid = $vnet_cfg->{ids}->{$vnet}->{zone};
185 my $zone = $zone_cfg->{ids}->{$zoneid};
186
c33dd818
AD
187 my $opts = PVE::Network::SDN::SubnetPlugin->check_config($id, $param, 1, 1);
188
189 my $scfg = undef;
190 if ($scfg = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id, 1)) {
191 die "sdn subnet object ID '$id' already defined\n";
192 }
193
194 $cfg->{ids}->{$id} = $opts;
4ad78442 195 PVE::Network::SDN::SubnetPlugin->on_update_hook($zone, $id, $opts);
70b03506 196
c33dd818 197 PVE::Network::SDN::Subnets::write_config($cfg);
c33dd818
AD
198
199 }, "create sdn subnet object failed");
200
201 return undef;
202 }});
203
204__PACKAGE__->register_method ({
205 name => 'update',
206 protected => 1,
207 path => '{subnet}',
208 method => 'PUT',
209 description => "Update sdn subnet object configuration.",
210 permissions => {
3926d9a7 211 check => ['perm', '/sdn/vnets/{vnet}/subnets', ['SDN.Allocate']],
c33dd818
AD
212 },
213 parameters => PVE::Network::SDN::SubnetPlugin->updateSchema(),
214 returns => { type => 'null' },
215 code => sub {
216 my ($param) = @_;
217
218 my $id = extract_param($param, 'subnet');
219 my $digest = extract_param($param, 'digest');
220
221 PVE::Network::SDN::lock_sdn_config(
222 sub {
223
224 my $cfg = PVE::Network::SDN::Subnets::config();
4ad78442
AD
225 my $zone_cfg = PVE::Network::SDN::Zones::config();
226 my $vnet_cfg = PVE::Network::SDN::Vnets::config();
227 my $vnet = $param->{vnet};
228 my $zoneid = $vnet_cfg->{ids}->{$vnet}->{zone};
229 my $zone = $zone_cfg->{ids}->{$zoneid};
230
70b03506 231 my $scfg = &$api_sdn_subnets_config($cfg, $id);
c33dd818
AD
232
233 PVE::SectionConfig::assert_if_modified($cfg, $digest);
234
235 my $opts = PVE::Network::SDN::SubnetPlugin->check_config($id, $param, 0, 1);
236 $cfg->{ids}->{$id} = $opts;
237
9dfa9202
AD
238 raise_param_exc({ ipam => "you can't change ipam"}) if $opts->{ipam} && $scfg->{ipam} && $opts->{ipam} ne $scfg->{ipam};
239
4ad78442 240 PVE::Network::SDN::SubnetPlugin->on_update_hook($zone, $id, $opts, $scfg);
70b03506 241
c33dd818 242 PVE::Network::SDN::Subnets::write_config($cfg);
c33dd818
AD
243
244 }, "update sdn subnet object failed");
245
246 return undef;
247 }});
248
249__PACKAGE__->register_method ({
250 name => 'delete',
251 protected => 1,
252 path => '{subnet}',
253 method => 'DELETE',
254 description => "Delete sdn subnet object configuration.",
255 permissions => {
3926d9a7 256 check => ['perm', '/sdn/vnets/{vnet}/subnets', ['SDN.Allocate']],
c33dd818
AD
257 },
258 parameters => {
259 additionalProperties => 0,
260 properties => {
3926d9a7 261 vnet => get_standard_option('pve-sdn-vnet-id'),
c33dd818
AD
262 subnet => get_standard_option('pve-sdn-subnet-id', {
263 completion => \&PVE::Network::SDN::Subnets::complete_sdn_subnets,
264 }),
265 },
266 },
267 returns => { type => 'null' },
268 code => sub {
269 my ($param) = @_;
270
271 my $id = extract_param($param, 'subnet');
272
273 PVE::Network::SDN::lock_sdn_config(
274 sub {
c33dd818
AD
275 my $cfg = PVE::Network::SDN::Subnets::config();
276
277 my $scfg = PVE::Network::SDN::Subnets::sdn_subnets_config($cfg, $id);
278
58a7773a
AD
279 my $subnets_cfg = PVE::Network::SDN::Subnets::config();
280 my $vnets_cfg = PVE::Network::SDN::Vnets::config();
c33dd818 281
58a7773a 282 PVE::Network::SDN::SubnetPlugin->on_delete_hook($id, $subnets_cfg, $vnets_cfg);
70b03506
AD
283
284 my $ipam_cfg = PVE::Network::SDN::Ipams::config();
285 my $ipam = $cfg->{ids}->{$id}->{ipam};
286 if ($ipam) {
287 raise_param_exc({ ipam => "$ipam not existing"}) if !$ipam_cfg->{ids}->{$ipam};
288 my $plugin_config = $ipam_cfg->{ids}->{$ipam};
289 my $plugin = PVE::Network::SDN::Ipams::Plugin->lookup($plugin_config->{type});
290 $plugin->del_subnet($plugin_config, $id, $scfg);
291 }
292
293 delete $cfg->{ids}->{$id};
294
c33dd818 295 PVE::Network::SDN::Subnets::write_config($cfg);
c33dd818
AD
296
297 }, "delete sdn subnet object failed");
298
299
300 return undef;
301 }});
302
3031;