]> git.proxmox.com Git - pve-network.git/blob - PVE/API2/Network/SDN/Zones.pm
api: generate 'running-config' state instead of version increase on apply
[pve-network.git] / PVE / API2 / Network / SDN / Zones.pm
1 package PVE::API2::Network::SDN::Zones;
2
3 use strict;
4 use warnings;
5
6 use PVE::SafeSyslog;
7 use PVE::Tools qw(extract_param);
8 use PVE::Cluster qw(cfs_read_file cfs_write_file);
9 use PVE::Network::SDN;
10 use PVE::Network::SDN::Vnets;
11 use PVE::Network::SDN::Zones;
12 use PVE::Network::SDN::Zones::Plugin;
13 use PVE::Network::SDN::Zones::VlanPlugin;
14 use PVE::Network::SDN::Zones::QinQPlugin;
15 use PVE::Network::SDN::Zones::VxlanPlugin;
16 use PVE::Network::SDN::Zones::EvpnPlugin;
17 use PVE::Network::SDN::Zones::FaucetPlugin;
18 use PVE::Network::SDN::Zones::SimplePlugin;
19
20 use Storable qw(dclone);
21 use PVE::JSONSchema qw(get_standard_option);
22 use PVE::RPCEnvironment;
23
24 use PVE::RESTHandler;
25
26 use base qw(PVE::RESTHandler);
27
28 my $sdn_zones_type_enum = PVE::Network::SDN::Zones::Plugin->lookup_types();
29
30 my $api_sdn_zones_config = sub {
31 my ($cfg, $id) = @_;
32
33 my $scfg = dclone(PVE::Network::SDN::Zones::sdn_zones_config($cfg, $id));
34 $scfg->{zone} = $id;
35 $scfg->{digest} = $cfg->{digest};
36
37 if ($scfg->{nodes}) {
38 $scfg->{nodes} = PVE::Network::SDN::Zones::Plugin->encode_value($scfg->{type}, 'nodes', $scfg->{nodes});
39 }
40
41 return $scfg;
42 };
43
44 __PACKAGE__->register_method ({
45 name => 'index',
46 path => '',
47 method => 'GET',
48 description => "SDN zones index.",
49 permissions => {
50 description => "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/<zone>'",
51 user => 'all',
52 },
53 parameters => {
54 additionalProperties => 0,
55 properties => {
56 type => {
57 description => "Only list sdn zones of specific type",
58 type => 'string',
59 enum => $sdn_zones_type_enum,
60 optional => 1,
61 },
62 },
63 },
64 returns => {
65 type => 'array',
66 items => {
67 type => "object",
68 properties => { zone => { type => 'string'},
69 type => { type => 'string'},
70 },
71 },
72 links => [ { rel => 'child', href => "{zone}" } ],
73 },
74 code => sub {
75 my ($param) = @_;
76
77 my $rpcenv = PVE::RPCEnvironment::get();
78 my $authuser = $rpcenv->get_user();
79
80
81 my $cfg = PVE::Network::SDN::Zones::config();
82
83 my @sids = PVE::Network::SDN::Zones::sdn_zones_ids($cfg);
84 my $res = [];
85 foreach my $id (@sids) {
86 my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
87 next if !$rpcenv->check_any($authuser, "/sdn/zones/$id", $privs, 1);
88
89 my $scfg = &$api_sdn_zones_config($cfg, $id);
90 next if $param->{type} && $param->{type} ne $scfg->{type};
91
92 my $plugin_config = $cfg->{ids}->{$id};
93 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
94 push @$res, $scfg;
95 }
96
97 return $res;
98 }});
99
100 __PACKAGE__->register_method ({
101 name => 'read',
102 path => '{zone}',
103 method => 'GET',
104 description => "Read sdn zone configuration.",
105 permissions => {
106 check => ['perm', '/sdn/zones/{zone}', ['SDN.Allocate']],
107 },
108
109 parameters => {
110 additionalProperties => 0,
111 properties => {
112 zone => get_standard_option('pve-sdn-zone-id'),
113 },
114 },
115 returns => { type => 'object' },
116 code => sub {
117 my ($param) = @_;
118
119 my $cfg = PVE::Network::SDN::Zones::config();
120
121 return &$api_sdn_zones_config($cfg, $param->{zone});
122 }});
123
124 __PACKAGE__->register_method ({
125 name => 'create',
126 protected => 1,
127 path => '',
128 method => 'POST',
129 description => "Create a new sdn zone object.",
130 permissions => {
131 check => ['perm', '/sdn/zones', ['SDN.Allocate']],
132 },
133 parameters => PVE::Network::SDN::Zones::Plugin->createSchema(),
134 returns => { type => 'null' },
135 code => sub {
136 my ($param) = @_;
137
138 my $type = extract_param($param, 'type');
139 my $id = extract_param($param, 'zone');
140
141 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($type);
142 my $opts = $plugin->check_config($id, $param, 1, 1);
143
144 # create /etc/pve/sdn directory
145 PVE::Cluster::check_cfs_quorum();
146 mkdir("/etc/pve/sdn");
147
148 PVE::Network::SDN::lock_sdn_config(
149 sub {
150
151 my $zone_cfg = PVE::Network::SDN::Zones::config();
152 my $controller_cfg = PVE::Network::SDN::Controllers::config();
153
154 my $scfg = undef;
155 if ($scfg = PVE::Network::SDN::Zones::sdn_zones_config($zone_cfg, $id, 1)) {
156 die "sdn zone object ID '$id' already defined\n";
157 }
158
159 $zone_cfg->{ids}->{$id} = $opts;
160 $plugin->on_update_hook($id, $zone_cfg, $controller_cfg);
161
162 PVE::Network::SDN::Zones::write_config($zone_cfg);
163
164 }, "create sdn zone object failed");
165
166 return undef;
167 }});
168
169 __PACKAGE__->register_method ({
170 name => 'update',
171 protected => 1,
172 path => '{zone}',
173 method => 'PUT',
174 description => "Update sdn zone object configuration.",
175 permissions => {
176 check => ['perm', '/sdn/zones', ['SDN.Allocate']],
177 },
178 parameters => PVE::Network::SDN::Zones::Plugin->updateSchema(),
179 returns => { type => 'null' },
180 code => sub {
181 my ($param) = @_;
182
183 my $id = extract_param($param, 'zone');
184 my $digest = extract_param($param, 'digest');
185
186 PVE::Network::SDN::lock_sdn_config(
187 sub {
188
189 my $zone_cfg = PVE::Network::SDN::Zones::config();
190 my $controller_cfg = PVE::Network::SDN::Controllers::config();
191
192 PVE::SectionConfig::assert_if_modified($zone_cfg, $digest);
193
194 my $scfg = PVE::Network::SDN::Zones::sdn_zones_config($zone_cfg, $id);
195
196 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($scfg->{type});
197 my $opts = $plugin->check_config($id, $param, 0, 1);
198
199 foreach my $k (%$opts) {
200 $scfg->{$k} = $opts->{$k};
201 }
202
203 $plugin->on_update_hook($id, $zone_cfg, $controller_cfg);
204
205 PVE::Network::SDN::Zones::write_config($zone_cfg);
206
207 }, "update sdn zone object failed");
208
209 return undef;
210 }});
211
212 __PACKAGE__->register_method ({
213 name => 'delete',
214 protected => 1,
215 path => '{zone}',
216 method => 'DELETE',
217 description => "Delete sdn zone object configuration.",
218 permissions => {
219 check => ['perm', '/sdn/zones', ['SDN.Allocate']],
220 },
221 parameters => {
222 additionalProperties => 0,
223 properties => {
224 zone => get_standard_option('pve-sdn-zone-id', {
225 completion => \&PVE::Network::SDN::Zones::complete_sdn_zones,
226 }),
227 },
228 },
229 returns => { type => 'null' },
230 code => sub {
231 my ($param) = @_;
232
233 my $id = extract_param($param, 'zone');
234
235 PVE::Network::SDN::lock_sdn_config(
236 sub {
237
238 my $cfg = PVE::Network::SDN::Zones::config();
239
240 my $scfg = PVE::Network::SDN::Zones::sdn_zones_config($cfg, $id);
241
242 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($scfg->{type});
243
244 my $vnet_cfg = PVE::Network::SDN::Vnets::config();
245
246 $plugin->on_delete_hook($id, $vnet_cfg);
247
248 delete $cfg->{ids}->{$id};
249 PVE::Network::SDN::Zones::write_config($cfg);
250
251 }, "delete sdn zone object failed");
252
253
254 return undef;
255 }});
256
257 1;