]> git.proxmox.com Git - pve-manager.git/blob - PVE/API2/Cluster/Mapping/PCI.pm
api: mappings: cleanup perl imports
[pve-manager.git] / PVE / API2 / Cluster / Mapping / PCI.pm
1 package PVE::API2::Cluster::Mapping::PCI;
2
3 use strict;
4 use warnings;
5
6 use Storable qw(dclone);
7
8 use PVE::Mapping::PCI ();
9 use PVE::JSONSchema qw(get_standard_option);
10 use PVE::Tools qw(extract_param);
11
12 use base qw(PVE::RESTHandler);
13
14 __PACKAGE__->register_method ({
15 name => 'index',
16 path => '',
17 method => 'GET',
18 # only proxy if we give the 'check-node' parameter
19 proxyto_callback => sub {
20 my ($rpcenv, $proxyto, $param) = @_;
21 return $param->{'check-node'} // 'localhost';
22 },
23 description => "List PCI Hardware Mapping",
24 permissions => {
25 description => "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or".
26 " 'Mapping.Audit' permissions on '/mapping/pci/<id>'.",
27 user => 'all',
28 },
29 parameters => {
30 additionalProperties => 0,
31 properties => {
32 'check-node' => get_standard_option('pve-node', {
33 description => "If given, checks the configurations on the given node for ".
34 "correctness, and adds relevant diagnostics for the devices to the response.",
35 optional => 1,
36 }),
37 },
38 },
39 returns => {
40 type => 'array',
41 items => {
42 type => "object",
43 properties => {
44 id => {
45 type => 'string',
46 description => "The logical ID of the mapping."
47 },
48 map => {
49 type => 'array',
50 description => "The entries of the mapping.",
51 items => {
52 type => 'string',
53 description => "A mapping for a node.",
54 },
55 },
56 description => {
57 type => 'string',
58 description => "A description of the logical mapping.",
59 },
60 checks => {
61 type => "array",
62 optional => 1,
63 description => "A list of checks, only present if 'check_node' is set.",
64 items => {
65 type => 'object',
66 properties => {
67 severity => {
68 type => "string",
69 enum => ['warning', 'error'],
70 description => "The severity of the error",
71 },
72 message => {
73 type => "string",
74 description => "The message of the error",
75 },
76 },
77 }
78 },
79 },
80 },
81 links => [ { rel => 'child', href => "{id}" } ],
82 },
83 code => sub {
84 my ($param) = @_;
85
86 my $rpcenv = PVE::RPCEnvironment::get();
87 my $authuser = $rpcenv->get_user();
88
89 my $check_node = $param->{'check-node'};
90 my $local_node = PVE::INotify::nodename();
91
92 die "wrong node to check - $check_node != $local_node\n"
93 if defined($check_node) && $check_node ne 'localhost' && $check_node ne $local_node;
94
95 my $cfg = PVE::Mapping::PCI::config();
96
97 my $can_see_mapping_privs = ['Mapping.Modify', 'Mapping.Use', 'Mapping.Audit'];
98
99 my $res = [];
100 for my $id (keys $cfg->{ids}->%*) {
101 next if !$rpcenv->check_any($authuser, "/mapping/pci/$id", $can_see_mapping_privs, 1);
102 next if !$cfg->{ids}->{$id};
103
104 my $entry = dclone($cfg->{ids}->{$id});
105 $entry->{id} = $id;
106 $entry->{digest} = $cfg->{digest};
107
108 if (defined($check_node)) {
109 $entry->{checks} = [];
110 if (my $mappings = PVE::Mapping::PCI::get_node_mapping($cfg, $id, $check_node)) {
111 if (!scalar($mappings->@*)) {
112 push $entry->{checks}->@*, {
113 severity => 'warning',
114 message => "No mapping for node $check_node.",
115 };
116 }
117 for my $mapping ($mappings->@*) {
118 eval { PVE::Mapping::PCI::assert_valid($id, $mapping) };
119 if (my $err = $@) {
120 push $entry->{checks}->@*, {
121 severity => 'error',
122 message => "Invalid configuration: $err",
123 };
124 }
125 }
126 }
127 }
128
129 push @$res, $entry;
130 }
131
132 return $res;
133 },
134 });
135
136 __PACKAGE__->register_method ({
137 name => 'get',
138 protected => 1,
139 path => '{id}',
140 method => 'GET',
141 description => "Get PCI Mapping.",
142 permissions => {
143 check =>['or',
144 ['perm', '/mapping/pci/{id}', ['Mapping.Use']],
145 ['perm', '/mapping/pci/{id}', ['Mapping.Modify']],
146 ['perm', '/mapping/pci/{id}', ['Mapping.Audit']],
147 ],
148 },
149 parameters => {
150 additionalProperties => 0,
151 properties => {
152 id => {
153 type => 'string',
154 format => 'pve-configid',
155 },
156 }
157 },
158 returns => { type => 'object' },
159 code => sub {
160 my ($param) = @_;
161
162 my $cfg = PVE::Mapping::PCI::config();
163 my $id = $param->{id};
164
165 my $entry = $cfg->{ids}->{$id};
166 die "mapping '$param->{id}' not found\n" if !defined($entry);
167
168 my $data = dclone($entry);
169
170 $data->{digest} = $cfg->{digest};
171
172 return $data;
173 }});
174
175 __PACKAGE__->register_method ({
176 name => 'create',
177 protected => 1,
178 path => '',
179 method => 'POST',
180 description => "Create a new hardware mapping.",
181 permissions => {
182 check => ['perm', '/mapping/pci', ['Mapping.Modify']],
183 },
184 parameters => PVE::Mapping::PCI->createSchema(1),
185 returns => {
186 type => 'null',
187 },
188 code => sub {
189 my ($param) = @_;
190
191 my $id = extract_param($param, 'id');
192
193 my $plugin = PVE::Mapping::PCI->lookup('pci');
194 my $opts = $plugin->check_config($id, $param, 1, 1);
195
196 PVE::Mapping::PCI::lock_pci_config(sub {
197 my $cfg = PVE::Mapping::PCI::config();
198
199 die "pci ID '$id' already defined\n" if defined($cfg->{ids}->{$id});
200
201 $cfg->{ids}->{$id} = $opts;
202
203 PVE::Mapping::PCI::write_pci_config($cfg);
204
205 }, "create hardware mapping failed");
206
207 return;
208 },
209 });
210
211 __PACKAGE__->register_method ({
212 name => 'update',
213 protected => 1,
214 path => '{id}',
215 method => 'PUT',
216 description => "Update a hardware mapping.",
217 permissions => {
218 check => ['perm', '/mapping/pci/{id}', ['Mapping.Modify']],
219 },
220 parameters => PVE::Mapping::PCI->updateSchema(),
221 returns => {
222 type => 'null',
223 },
224 code => sub {
225 my ($param) = @_;
226
227 my $digest = extract_param($param, 'digest');
228 my $delete = extract_param($param, 'delete');
229 my $id = extract_param($param, 'id');
230
231 if ($delete) {
232 $delete = [ PVE::Tools::split_list($delete) ];
233 }
234
235 PVE::Mapping::PCI::lock_pci_config(sub {
236 my $cfg = PVE::Mapping::PCI::config();
237
238 PVE::Tools::assert_if_modified($cfg->{digest}, $digest) if defined($digest);
239
240 die "pci ID '$id' does not exist\n" if !defined($cfg->{ids}->{$id});
241
242 my $plugin = PVE::Mapping::PCI->lookup('pci');
243 my $opts = $plugin->check_config($id, $param, 1, 1);
244
245 my $data = $cfg->{ids}->{$id};
246
247 my $options = $plugin->private()->{options}->{pci};
248 PVE::SectionConfig::delete_from_config($data, $options, $opts, $delete);
249
250 $data->{$_} = $opts->{$_} for keys $opts->%*;
251
252 PVE::Mapping::PCI::write_pci_config($cfg);
253
254 }, "update hardware mapping failed");
255
256 return;
257 },
258 });
259
260 __PACKAGE__->register_method ({
261 name => 'delete',
262 protected => 1,
263 path => '{id}',
264 method => 'DELETE',
265 description => "Remove Hardware Mapping.",
266 permissions => {
267 check => [ 'perm', '/mapping/pci', ['Mapping.Modify']],
268 },
269 parameters => {
270 additionalProperties => 0,
271 properties => {
272 id => {
273 type => 'string',
274 format => 'pve-configid',
275 },
276 }
277 },
278 returns => { type => 'null' },
279 code => sub {
280 my ($param) = @_;
281
282 my $id = $param->{id};
283
284 PVE::Mapping::PCI::lock_pci_config(sub {
285 my $cfg = PVE::Mapping::PCI::config();
286
287 if ($cfg->{ids}->{$id}) {
288 delete $cfg->{ids}->{$id};
289 }
290
291 PVE::Mapping::PCI::write_pci_config($cfg);
292
293 }, "delete pci mapping failed");
294
295 return;
296 }
297 });
298
299 1;