1
+ <?php
2
+
3
+ /**
4
+ * phpIPAM API class to work with devices.
5
+ *
6
+ *
7
+ */
8
+ class Devices_controller extends Common_api_functions {
9
+
10
+ /**
11
+ * _params provided.
12
+ *
13
+ * @var mixed
14
+ */
15
+ public $ _params ;
16
+
17
+ /**
18
+ * Database object.
19
+ *
20
+ * @var mixed
21
+ */
22
+ protected $ Database ;
23
+
24
+ /**
25
+ * Response.
26
+ *
27
+ * @var mixed
28
+ */
29
+ protected $ Response ;
30
+
31
+ /**
32
+ * Master Tools object.
33
+ *
34
+ * @var mixed
35
+ */
36
+ protected $ Tools ;
37
+
38
+ /**
39
+ * Main Admin class.
40
+ *
41
+ * @var mixed
42
+ */
43
+ protected $ Admin ;
44
+
45
+ /**
46
+ * Main Subnets class.
47
+ *
48
+ * @var mixed
49
+ */
50
+ protected $ Subnets ;
51
+
52
+ /**
53
+ * Default fields to search.
54
+ *
55
+ * @var mixed
56
+ */
57
+ protected $ default_search_fields = ['hostname ' ,'ip_addr ' ,'description ' ];
58
+
59
+
60
+ /**
61
+ * __construct function.
62
+ *
63
+ * @param class $Database
64
+ * @param class $Tools
65
+ * @param mixed $params // post/get values
66
+ * @param class $Response
67
+ */
68
+ public function __construct ($ Database , $ Tools , $ params , $ Response ) {
69
+ $ this ->Database = $ Database ;
70
+ $ this ->Response = $ Response ;
71
+ $ this ->Tools = $ Tools ;
72
+ $ this ->_params = $ params ;
73
+
74
+ // init required objects
75
+ $ this ->init_object ('Admin ' , $ Database );
76
+ $ this ->init_object ('Subnets ' , $ Database );
77
+
78
+ // set valid keys
79
+ $ this ->set_valid_keys ("devices " );
80
+ }
81
+
82
+
83
+
84
+
85
+
86
+ /**
87
+ * Returns json encoded options and version
88
+ *
89
+ * @access public
90
+ * @return void
91
+ */
92
+ public function OPTIONS () {
93
+ // validate
94
+ $ this ->validate_options_request ();
95
+
96
+ // get api
97
+ $ app = $ this ->Tools ->fetch_object ('api ' , 'app_id ' , $ this ->_params ->app_id );
98
+
99
+ // methods
100
+ $ result = array ();
101
+ $ result ['methods ' ] = array (
102
+ array ("href " =>"/api/ " .$ this ->_params ->app_id ."/devices/ " , "methods " =>array (array ("rel " =>"options " , "method " =>"OPTIONS " ))),
103
+ array ("href " =>"/api/ " .$ this ->_params ->app_id ."/devices/search/{search_term} " , "methods " =>array (array ("rel " =>"search " , "method " =>"GET " ))),
104
+ array ("href " =>"/api/ " .$ this ->_params ->app_id ."/devices/{id}/ " , "methods " =>array (array ("rel " =>"read " , "method " =>"GET " ),
105
+ array ("rel " =>"create " , "method " =>"POST " ),
106
+ array ("rel " =>"update " , "method " =>"PATCH " ),
107
+ array ("rel " =>"delete " , "method " =>"DELETE " ))),
108
+ );
109
+ # Response
110
+ return array ('code ' =>200 , 'data ' =>$ result );
111
+ }
112
+
113
+
114
+
115
+
116
+
117
+
118
+ /**
119
+ * GET devices functions
120
+ *
121
+ * ID can be:
122
+ * - / // returns all devices
123
+ * - /{id}/ // returns device details
124
+ * - /{id}/{subnets}/ // returns all subnets attached to device
125
+ * - /{id}/{addresses}/ // returns all IP addresses attached to device
126
+ * - /search/{search_q}/ // searches for devices
127
+ *
128
+ * @access public
129
+ * @return void
130
+ */
131
+ public function GET () {
132
+ // all objects
133
+ if (!isset ($ this ->_params ->id )) {
134
+ // fetch all devices
135
+ $ result = $ this ->Tools ->fetch_all_objects ('devices ' , 'id ' );
136
+ // result
137
+ if (!$ result ) { return $ this ->Response ->throw_exception (200 , "No devices configured " ); }
138
+ else { return array ('code ' =>200 , 'data ' =>$ this ->prepare_result ($ result , 'devices ' , true , false )); }
139
+ }
140
+ // parameters are set
141
+ else {
142
+ // search for devices
143
+ if ($ this ->_params ->id == 'search ' ) {
144
+ // verify that search params are set
145
+ if (isset ($ this ->_params ->id2 )) {
146
+ // set query
147
+ $ base_query = "SELECT * from `devices` where " ;
148
+
149
+ # Search all custom fields
150
+ $ cfs = array_keys ($ this ->Tools ->fetch_custom_fields ('devices ' ));
151
+
152
+ # Merge default fields with custom fields
153
+ $ search_fields = array_merge ($ cfs , $ this ->default_search_fields );
154
+
155
+ # Using the search fields, build a string to query parameters chained together with " or "
156
+ $ search_term = $ this ->_params ->id2 ;
157
+ $ extended_query = implode (' or ' , array_map (
158
+ function ($ k ) {
159
+ return " ` $ k` like ? " ;
160
+ }, $ search_fields ));
161
+
162
+ # Set up an array of parameters to match the query we built
163
+ $ query_params = array_fill (0 , count ($ search_fields ), "% $ search_term% " );
164
+
165
+ # Put together with the base query
166
+ $ search_query = $ base_query . $ extended_query ;
167
+
168
+ # Search query
169
+ $ result = $ this ->Database ->getObjectsQuery ($ search_query , $ query_params );
170
+
171
+ // result
172
+ if (!$ result ) { return $ this ->Response ->throw_exception (200 , "No devices found " ); }
173
+ else { return array ('code ' =>200 , 'data ' =>$ this ->prepare_result ($ result , 'devices ' , true , false )); }
174
+ }
175
+ else {
176
+ $ this ->Response ->throw_exception (400 , 'No search term given ' );
177
+ }
178
+ }
179
+ // not search
180
+ else {
181
+ // Id must be numeric
182
+ if (!is_numeric ($ this ->_params ->id )) { $ this ->Response ->throw_exception (400 , 'ID must be numeric ' ); }
183
+
184
+ // additional parameter is set?
185
+ if (isset ($ this ->_params ->id2 )) {
186
+ // addresses
187
+ if ($ this ->_params ->id2 == 'addresses ' ) {
188
+ $ result = $ this ->Tools ->fetch_multiple_objects ("ipaddresses " , 'switch ' , $ this ->_params ->id , 'id ' , true );
189
+ }
190
+ // subnets
191
+ elseif ($ this ->_params ->id2 == 'subnets ' ) {
192
+ $ result = $ this ->Tools ->fetch_multiple_objects ("subnets " , 'device ' , $ this ->_params ->id , 'id ' , true );
193
+ }
194
+ // error
195
+ else {
196
+ $ this ->Response ->throw_exception (400 , 'Invalid parameters ' );
197
+ }
198
+ }
199
+ // device details
200
+ else {
201
+ // fetch device
202
+ $ result = $ this ->Tools ->fetch_object ('devices ' , 'id ' , $ this ->_params ->id );
203
+ if (!$ result ) { $ this ->Response ->throw_exception (404 , 'Device not found ' ); }
204
+ }
205
+
206
+ // all ok, prepare result
207
+ if ($ result === false ) { return $ this ->Response ->throw_exception (200 , "No " .$ this ->_params ->id2 ." found " ); }
208
+ else { return array ('code ' =>200 , 'data ' =>$ this ->prepare_result ($ result , 'devices ' , true , false )); }
209
+ }
210
+ }
211
+ }
212
+
213
+
214
+
215
+
216
+
217
+ /**
218
+ * HEAD, no response.
219
+ */
220
+ public function HEAD () {
221
+ return $ this ->GET ();
222
+ }
223
+
224
+
225
+
226
+
227
+ /**
228
+ * Creates new device
229
+ *
230
+ * /devices/
231
+ *
232
+ * @method POST
233
+ */
234
+ public function POST () {
235
+ # Put incoming keys in order
236
+ $ this ->remap_keys ();
237
+
238
+ # check for valid keys
239
+ $ values = $ this ->validate_keys ();
240
+
241
+ # validations
242
+ $ this ->validate_device_type ();
243
+
244
+ # only 1 parameter ?
245
+ if (sizeof ($ values ) == 1 ) { $ this ->Response ->throw_exception (400 , 'No parameters ' ); }
246
+
247
+ // provide default params if they are not set
248
+ if (!isset ($ this ->_params ->sections )) {
249
+ $ sections_json = $ this ->get_all_sections_delimited ();
250
+ if ($ sections_json !==false ) {
251
+ $ values ['sections ' ] = $ sections_json ;
252
+ }
253
+ }
254
+
255
+ // execute update
256
+ if (!$ this ->Admin ->object_modify ('devices ' , 'add ' , '' , $ values )) {
257
+ { $ this ->Response ->throw_exception (500 , 'Device creation failed ' ); }
258
+ }
259
+ else {
260
+ //set result
261
+ return array ("code " =>201 , "message " =>"Device created " , "id " =>$ this ->Admin ->lastId , "location " =>"/api/ " .$ this ->_params ->app_id ."/devices/ " .$ this ->Admin ->lastId ."/ " );
262
+ }
263
+ }
264
+
265
+
266
+
267
+
268
+
269
+
270
+ /**
271
+ * Update device details
272
+ *
273
+ * @method PATCH
274
+ */
275
+ public function PATCH (){
276
+ # Put incoming keys back in order
277
+ $ this ->remap_keys ();
278
+
279
+ # validations
280
+ $ this ->validate_device_type ();
281
+
282
+ # validate and prepare keys
283
+ $ values = $ this ->validate_keys ();
284
+
285
+ # only 1 parameter ?
286
+ if (sizeof ($ values ) == 1 ) { $ this ->Response ->throw_exception (400 , 'No parameters ' ); }
287
+
288
+ # execute update
289
+ if (!$ this ->Admin ->object_modify ('devices ' , 'edit ' , 'id ' , $ values )) {
290
+ $ this ->Response ->throw_exception (500 , 'Device edit failed ' );
291
+ } else {
292
+ // fetch the updated object and hand it back to the client
293
+ return array ("code " =>200 , "message " =>"Device updated " , "id " =>$ this ->Admin ->lastId , "location " =>"/api/ " .$ this ->_params ->app_id ."/devices/ " .$ values ['id ' ]."/ " );
294
+ }
295
+ }
296
+
297
+
298
+
299
+
300
+
301
+
302
+ /**
303
+ * Delete existing device
304
+ *
305
+ * @method DELETE
306
+ */
307
+ public function DELETE () {
308
+ # set variables for delete
309
+ $ values = array ();
310
+ $ values ['id ' ] = $ this ->_params ->id ;
311
+
312
+ # check that section exists
313
+ if ($ this ->Admin ->fetch_object ("devices " , "id " , $ this ->_params ->id )===false )
314
+ { $ this ->Response ->throw_exception (404 , "Device does not exist " ); }
315
+
316
+ # execute delete
317
+ if (!$ this ->Admin ->object_modify ('devices ' , 'delete ' , 'id ' , $ values )) {
318
+ $ this ->Response ->throw_exception (500 , 'Device delete failed ' );
319
+ }
320
+ else {
321
+ // delete all references
322
+ $ this ->Admin ->remove_object_references ('ipaddresses ' , 'switch ' , $ this ->_params ->id );
323
+
324
+ // set result
325
+ return array ("code " =>200 , "message " =>"Device deleted " );
326
+ }
327
+ }
328
+
329
+
330
+
331
+
332
+
333
+
334
+ /**
335
+ * Validate device type
336
+ *
337
+ * @method validate_device_type
338
+ * @return [type] [description]
339
+ */
340
+ private function validate_device_type () {
341
+ if (isset ($ this ->_params ->type )) {
342
+ // numeric
343
+ if (!is_numeric ($ this ->_params ->type )) {
344
+ $ this ->Response ->throw_exception (400 , 'Invalid devicetype identifier ' );
345
+ }
346
+ // check
347
+ if ($ this ->Tools ->fetch_object ('deviceTypes ' , 'id ' , $ this ->_params ->type ) === false ) {
348
+ $ this ->Response ->throw_exception (400 , 'Device type does not exist ' );
349
+ }
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Create delimited string from all sections for default permissions
355
+ *
356
+ * @method get_all_sections_delimited
357
+ * @return [type] [description]
358
+ */
359
+ private function get_all_sections_delimited () {
360
+ $ sections = $ this ->Admin ->fetch_all_objects ("sections " );
361
+ // reformat
362
+ if ($ sections !==false ) {
363
+ $ sections_all = array ();
364
+ foreach ($ sections as $ s ) {
365
+ $ sections_all [$ s ->id ] = $ s ->id ;
366
+ }
367
+ $ sections = implode ("; " ,$ sections_all );
368
+ }
369
+ // return
370
+ return $ sections ;
371
+ }
372
+ }
0 commit comments