]> git.proxmox.com Git - pve-network.git/blob - PVE/API2/Network/SDN.pm
rename plugins with controllers
[pve-network.git] / PVE / API2 / Network / SDN.pm
1 package PVE::API2::Network::SDN;
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::Plugin;
11 use PVE::Network::SDN::VlanPlugin;
12 use PVE::Network::SDN::VxlanPlugin;
13 use PVE::Network::SDN::VnetPlugin;
14 use PVE::Network::SDN::FaucetControllerPlugin;
15 use PVE::Network::SDN::FaucetPlugin;
16 use PVE::Network::SDN::EvpnControllerPlugin;
17 use PVE::Network::SDN::EvpnPlugin;
18
19 use Storable qw(dclone);
20 use PVE::JSONSchema qw(get_standard_option);
21 use PVE::RPCEnvironment;
22
23 use PVE::RESTHandler;
24
25 use base qw(PVE::RESTHandler);
26
27 my $sdn_type_enum = PVE::Network::SDN::Plugin->lookup_types();
28
29 my $api_sdn_config = sub {
30 my ($cfg, $sdnid) = @_;
31
32 my $scfg = dclone(PVE::Network::SDN::sdn_config($cfg, $sdnid));
33 $scfg->{sdn} = $sdnid;
34 $scfg->{digest} = $cfg->{digest};
35
36 return $scfg;
37 };
38
39 __PACKAGE__->register_method ({
40 name => 'index',
41 path => '',
42 method => 'GET',
43 description => "SDN index.",
44 permissions => {
45 description => "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/cluster/sdn/<sdn>'",
46 user => 'all',
47 },
48 parameters => {
49 additionalProperties => 0,
50 properties => {
51 type => {
52 description => "Only list sdn of specific type",
53 type => 'string',
54 enum => $sdn_type_enum,
55 optional => 1,
56 },
57 },
58 },
59 returns => {
60 type => 'array',
61 items => {
62 type => "object",
63 properties => { sdn => { type => 'string'} },
64 },
65 links => [ { rel => 'child', href => "{sdn}" } ],
66 },
67 code => sub {
68 my ($param) = @_;
69
70 my $rpcenv = PVE::RPCEnvironment::get();
71 my $authuser = $rpcenv->get_user();
72
73
74 my $cfg = PVE::Network::SDN::config();
75
76 my @sids = PVE::Network::SDN::sdn_ids($cfg);
77 my $res = [];
78 foreach my $sdnid (@sids) {
79 # my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
80 # next if !$rpcenv->check_any($authuser, "/cluster/sdn/$sdnid", $privs, 1);
81
82 my $scfg = &$api_sdn_config($cfg, $sdnid);
83 next if $param->{type} && $param->{type} ne $scfg->{type};
84 push @$res, $scfg;
85 }
86
87 return $res;
88 }});
89
90 __PACKAGE__->register_method ({
91 name => 'read',
92 path => '{sdn}',
93 method => 'GET',
94 description => "Read sdn configuration.",
95 # permissions => {
96 # check => ['perm', '/cluster/sdn/{sdn}', ['SDN.Allocate']],
97 # },
98
99 parameters => {
100 additionalProperties => 0,
101 properties => {
102 sdn => get_standard_option('pve-sdn-id'),
103 },
104 },
105 returns => { type => 'object' },
106 code => sub {
107 my ($param) = @_;
108
109 my $cfg = PVE::Network::SDN::config();
110
111 return &$api_sdn_config($cfg, $param->{sdn});
112 }});
113
114 __PACKAGE__->register_method ({
115 name => 'create',
116 protected => 1,
117 path => '',
118 method => 'POST',
119 description => "Create a new sdn object.",
120 # permissions => {
121 # check => ['perm', '/cluster/sdn', ['SDN.Allocate']],
122 # },
123 parameters => PVE::Network::SDN::Plugin->createSchema(),
124 returns => { type => 'null' },
125 code => sub {
126 my ($param) = @_;
127
128 my $type = extract_param($param, 'type');
129 my $sdnid = extract_param($param, 'sdn');
130
131 my $plugin = PVE::Network::SDN::Plugin->lookup($type);
132 my $opts = $plugin->check_config($sdnid, $param, 1, 1);
133
134 PVE::Network::SDN::lock_sdn_config(
135 sub {
136
137 my $cfg = PVE::Network::SDN::config();
138
139 my $scfg = undef;
140 if ($scfg = PVE::Network::SDN::sdn_config($cfg, $sdnid, 1)) {
141 die "sdn object ID '$sdnid' already defined\n";
142 }
143
144 $cfg->{ids}->{$sdnid} = $opts;
145 $plugin->on_update_hook($sdnid, $cfg);
146 #also verify transport associated to vnet
147 if($scfg && $scfg->{type} eq 'vnet') {
148 my $transportid = $scfg->{transportzone};
149 die "missing transportzone" if !$transportid;
150 my $transport_cfg = $cfg->{ids}->{$transportid};
151 my $transport_plugin = PVE::Network::SDN::Plugin->lookup($transport_cfg->{type});
152 $transport_plugin->on_update_hook($transportid, $cfg);
153 }
154
155 PVE::Network::SDN::write_config($cfg);
156
157 }, "create sdn object failed");
158
159 return undef;
160 }});
161
162 __PACKAGE__->register_method ({
163 name => 'apply_configuration',
164 protected => 1,
165 path => '',
166 method => 'PUT',
167 description => "Apply sdn changes.",
168 # permissions => {
169 # check => ['perm', '/cluster/sdn', ['SDN.Allocate']],
170 # },
171 parameters => {
172 additionalProperties => 0,
173 },
174 returns => { type => 'null' },
175 code => sub {
176 my ($param) = @_;
177
178 die "no sdn changes to apply" if !-e "/etc/pve/sdn.cfg.new";
179 rename("/etc/pve/sdn.cfg.new", "/etc/pve/sdn.cfg")
180 || die "applying sdn.cfg changes failed - $!\n";
181
182
183 return undef;
184 }});
185
186 __PACKAGE__->register_method ({
187 name => 'revert_configuration',
188 protected => 1,
189 path => '',
190 method => 'DELETE',
191 description => "Revert sdn changes.",
192 # permissions => {
193 # check => ['perm', '/cluster/sdn', ['SDN.Allocate']],
194 # },
195 parameters => {
196 additionalProperties => 0,
197 },
198 returns => { type => 'null' },
199 code => sub {
200 my ($param) = @_;
201
202 die "no sdn changes to revert" if !-e "/etc/pve/sdn.cfg.new";
203 unlink "/etc/pve/sdn.cfg.new";
204
205 return undef;
206 }});
207
208 __PACKAGE__->register_method ({
209 name => 'update',
210 protected => 1,
211 path => '{sdn}',
212 method => 'PUT',
213 description => "Update sdn object configuration.",
214 # permissions => {
215 # check => ['perm', '/cluster/sdn', ['SDN.Allocate']],
216 # },
217 parameters => PVE::Network::SDN::Plugin->updateSchema(),
218 returns => { type => 'null' },
219 code => sub {
220 my ($param) = @_;
221
222 my $sdnid = extract_param($param, 'sdn');
223 my $digest = extract_param($param, 'digest');
224
225 PVE::Network::SDN::lock_sdn_config(
226 sub {
227
228 my $cfg = PVE::Network::SDN::config();
229
230 PVE::SectionConfig::assert_if_modified($cfg, $digest);
231
232 my $scfg = PVE::Network::SDN::sdn_config($cfg, $sdnid);
233
234 my $plugin = PVE::Network::SDN::Plugin->lookup($scfg->{type});
235 my $opts = $plugin->check_config($sdnid, $param, 0, 1);
236
237 foreach my $k (%$opts) {
238 $scfg->{$k} = $opts->{$k};
239 }
240
241 $plugin->on_update_hook($sdnid, $cfg);
242 #also verify transport associated to vnet
243 if($scfg->{type} eq 'vnet') {
244 my $transportid = $scfg->{transportzone};
245 die "missing transportzone" if !$transportid;
246 my $transport_cfg = $cfg->{ids}->{$transportid};
247 my $transport_plugin = PVE::Network::SDN::Plugin->lookup($transport_cfg->{type});
248 $transport_plugin->on_update_hook($transportid, $cfg);
249 }
250 PVE::Network::SDN::write_config($cfg);
251
252 }, "update sdn object failed");
253
254 return undef;
255 }});
256
257 __PACKAGE__->register_method ({
258 name => 'delete',
259 protected => 1,
260 path => '{sdn}',
261 method => 'DELETE',
262 description => "Delete sdn object configuration.",
263 # permissions => {
264 # check => ['perm', '/cluster/sdn', ['SDN.Allocate']],
265 # },
266 parameters => {
267 additionalProperties => 0,
268 properties => {
269 sdn => get_standard_option('pve-sdn-id', {
270 completion => \&PVE::Network::SDN::complete_sdn,
271 }),
272 },
273 },
274 returns => { type => 'null' },
275 code => sub {
276 my ($param) = @_;
277
278 my $sdnid = extract_param($param, 'sdn');
279
280 PVE::Network::SDN::lock_sdn_config(
281 sub {
282
283 my $cfg = PVE::Network::SDN::config();
284
285 my $scfg = PVE::Network::SDN::sdn_config($cfg, $sdnid);
286
287 my $plugin = PVE::Network::SDN::Plugin->lookup($scfg->{type});
288 $plugin->on_delete_hook($sdnid, $cfg);
289
290 delete $cfg->{ids}->{$sdnid};
291 PVE::Network::SDN::write_config($cfg);
292
293 }, "delete sdn object failed");
294
295
296 return undef;
297 }});
298
299 1;