1source: Extensions/Component.md
2path: blob/master/doc/
3
4# About
5
6The Component extension provides a generic database storage mechanism
7for discovery and poller modules. The Driver behind this extension was
8to provide the features of ports, in a generic manner to
9discovery/poller modules.
10
11It provides a status (Nagios convention), the ability to Disable (do
12not poll), or Ignore (do not Alert).
13
14# Database Structure
15
16The database structure contains the component table:
17
18```SQL
19mysql> select * from component limit 1;
20+----+-----------+------+------------+--------+----------+--------+-------+
21| id | device_id | type | label      | status | disabled | ignore | error |
22+----+-----------+------+------------+--------+----------+--------+-------+
23|  9 |         1 | TEST | TEST LABEL |      0 |        1 |      1 |       |
24+----+-----------+------+------------+--------+----------+--------+-------+
251 row in set (0.00 sec)
26```
27
28These fields are described below:
29
30- `id` - ID for each component, unique index
31- `device_id` - device_id from the devices table
32- `type` - name from the component_type table
33- `label` - Display label for the component
34- `status` - The status of the component, retrieved from the device
35- `disabled` - Should this component be polled?
36- `ignore` - Should this component be alerted on
37- `error` - Error message if in Alert state
38
39The component_prefs table holds custom data in an Attribute/Value format:
40
41```sql
42mysql> select * from component_prefs limit 1;
43+----+-----------+-----------+-----------+
44| id | component | attribute | value     |
45+----+-----------+-----------+-----------+
46|  4 |         9 | TEST_ATTR | TEST_ATTR |
47+----+-----------+-----------+-----------+
482 rows in set (0.00 sec)
49```
50
51## Reserved Fields
52
53When this data from both the `component` and `component_prefs` tables
54is returned in one single consolidated array, there is the potential
55for someone to attempt to set an attribute (in the `component_prefs`)
56table that is used in the `component` table. Because of this all
57fields of the `component` table are reserved, they cannot be used as
58custom attributes, if you update these the module will attempt to
59write them to the `component` table, not the `component_prefs` table.
60
61# Using Components
62
63Create an instance of the component class:
64
65```php
66$COMPONENT = new LibreNMS\Component();
67```
68
69## Retrieving Components
70
71Now you can retrieve an array of the available components:
72
73```php
74$ARRAY = $COMPONENT->getComponents($DEVICE_ID, $OPTIONS);
75```
76
77`getComponents` takes 2 arguments:
78
79- `DEVICE_ID` or null for all devices.
80- `OPTIONS` - an array of various options.
81
82`getComponents` will return an array containing components in the following format:
83
84```php
85Array
86(
87    [X] => Array
88    (
89        [Y1] => Array
90        (
91            [device_id] => 1
92            [TEST_ATTR] => TEST_ATTR
93            [type] => TEST
94            [label] => TEST LABEL
95            [status] => 0
96            [ignore] => 1
97            [disabled] => 1
98            [error] =>
99        ),
100        [Y2] => Array
101        (
102            [device_id] => 1
103            [TEST_ATTR] => TEST_ATTR
104            [type] => TESTING
105            [label] => TEST LABEL
106            [status] => 0
107            [ignore] => 1
108            [disabled] => 0
109            [error] =>
110        ),
111    )
112)
113```
114
115Where X is the Device ID and Y1/Y2 is the Component ID. In the example
116above, `TEST_ATTR` is a custom field, the rest are reserved fields.
117
118### Options
119
120Options can be supplied to `getComponents` to influence which and how
121components are returned.
122
123#### Filtering
124
125You can filter on any of the [reserved](#reserved) fields. Filters are
126created in the following format:
127
128```php
129$options['filter']['FIELD'] = array ('OPERATOR', 'CRITERIA');
130```
131
132Where:
133
134- `FIELD` - The [reserved](#reserved) field to filter on
135- `OPERATOR` - 'LIKE' or '=', are we checking if the FIELD equals or
136  contains the CRITERIA.
137- `CRITERIA` - The criteria to search on
138
139There are 2 filtering shortcuts:
140
141`$DEVICE_ID` is a synonym for:
142
143```php
144$OPTIONS['filter']['device_id'] = array ('=', $DEVICE_ID);
145```
146
147`$OPTIONS['type'] = $TYPE` is a synonym for:
148
149```php
150$OPTIONS['filter']['type'] = array ('=', $TYPE);
151```
152
153#### Sorting
154
155You can sort the records that are returned by specifying the following option:
156
157```php
158$OPTIONS['sort'][FIELD] = 'DIRECTION';
159```
160
161Where Direction is one of:
162
163- `ASC` - Ascending, from Low to High
164- `DESC` - Descending, from High to Low
165
166## Creating Components
167
168To create a new component, run the `createComponent` function.
169
170```php
171$ARRAY = $COMPONENT->createComponent($DEVICE_ID, $TYPE);
172```
173
174`createComponent` takes 2 arguments:
175
176- `DEVICE_ID` - The ID of the device to attach the component to.
177- `TYPE` - The unique type for your module.
178
179This will return a new, empty array with a component ID and Type set,
180all other fields will be set to defaults.
181
182```php
183Array
184(
185    [1] => Array
186    (
187        [type] => TESTING
188        [label] =>
189        [status] => 1
190        [ignore] => 0
191        [disabled] => 0
192        [error] =>
193    )
194)
195```
196
197## Deleting Components
198
199When a component is no longer needed, it can be deleted.
200
201```php
202$COMPONENT->deleteComponent($COMPONENT_ID)
203```
204
205This will return `True` on success or `False` on failure.
206
207## Editing Components
208
209To edit a component, the procedure is:
210
2111. [Get the Current Components](#get)
2121. [Edit the array](#update-edit)
2131. [Write the components](#update-write)
214
215### Edit the Array
216
217Once you have a component array from `getComponents` the first thing
218to do is extract the components for only the single device you are
219editing. This is required because the `setComponentPrefs` function
220only saves a single device at a time.
221
222```php
223$ARRAY = $COMPONENT->getComponents($DEVICE_ID, $OPTIONS);
224$ARRAY = $ARRAY[$DEVICE_ID];
225```
226
227Then simply edit this array to suit your needs.
228If you need to add a new Attribute/Value pair you can:
229
230```php
231$ARRAY[COMPONENT_ID]['New Attribute'] = "Value";
232```
233
234If you need to delete a previously set Attribute/Value pair you can:
235
236```php
237unset($ARRAY[COMPONENT_ID]['New Attribute']);
238```
239
240If you need to edit a previously set Attribute/Value pair you can:
241
242```php
243$ARRAY[COMPONENT_ID]['Existing Attribute'] = "New Value";
244```
245
246### Write the components
247
248To write component changes back to the database simply:
249
250```php
251$COMPONENT->setComponentPrefs($DEVICE_ID, $ARRAY)
252```
253
254When writing the component array there are several caveats to be aware
255of, these are:
256
257- `$ARRAY` must be in the format of a single device ID -
258  `$ARRAY[$COMPONENT_ID][Attribute] = 'Value';` NOT in the multi
259  device format returned by `getComponents` -
260  `$ARRAY[$DEVICE_ID][$COMPONENT_ID][Attribute] = 'Value';`
261- You cannot edit the Component ID or the Device ID
262- [reserved](#reserved) fields can not be removed
263- if a change is found an entry will be written to the eventlog.
264
265## API
266
267Component details are available via the API.
268Please see the [API-Docs](/API/#function-get_components) for details.
269
270## Alerting
271
272It is intended that discovery/poller modules will detect the status of
273a component during the polling cycle. Status is logged using the
274Nagios convention for status codes, where:
275
276```
2770 = Ok,
2781 = Warning,
2792 = Critical
280```
281
282If you are creating a poller module which can detect a fault condition
283simply set STATUS to something other than 0 and ERROR to a message
284that indicates the problem.
285
286To actually raise an alert, the user will need to create an alert
287rule. To assist with this several Alerting Macro's have been created:
288
289- `%macro.component_normal` - A component that is not disabled or
290  ignored and in a Normal state.
291- `%macro.component_warning` - A component that is not disabled or
292  ignored and NOT in a Warning state.
293- `%macro.component_critical` - A component that is not disabled or
294  ignored and NOT in a Critical state.
295
296To raise alerts for components, the following rules could be created:
297
298- `%macros.component_critical = "1"` - To alert on all Critical
299  components
300- `%macros.component_critical = "1" && %component.type = "<Type of
301  Component>"` - To alert on all Critical components of a particular
302  type.
303
304If there is a particular component you would like excluded from
305alerting, simply set the ignore field to 1.
306
307The data that is written to each alert when it is raised is in the following format:
308
309`COMPONENT_TYPE - LABEL - ERROR`
310
311# Example Code
312
313To see an example of how the component module can used, please see the
314following modules:
315
316- Cisco CBQoS
317  - `includes/discovery/cisco-cbqos.inc.php`
318  - `includes/polling/cisco-cbqos.inc.php`
319  - `html/includes/graphs/device/cbqos_traffic.inc.php`
320- Cisco OTV
321  - `includes/discovery/cisco-otv.inc.php`
322  - `includes/polling/cisco-otv.inc.php`
323  - `html/includes/graphs/device/cisco-otv-mac.inc.php`
324  - `html/pages/routing/cisco-otv.inc.php`
325