1 | <?php |
||
2 | /** |
||
3 | * DependencyController.php |
||
4 | * |
||
5 | * Controller for graphing Relationships |
||
6 | * |
||
7 | * This program is free software: you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation, either version 3 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * This program is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License |
||
18 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
||
19 | * |
||
20 | * @link https://www.librenms.org |
||
21 | * |
||
22 | * @copyright 2019 Thomas Berberich |
||
23 | * @author Thomas Berberich <[email protected]> |
||
24 | */ |
||
25 | |||
26 | namespace App\Http\Controllers\Maps; |
||
27 | |||
28 | use App\Models\Device; |
||
29 | use App\Models\DeviceGroup; |
||
30 | use Illuminate\Http\Request; |
||
31 | use LibreNMS\Util\Url; |
||
32 | |||
33 | class DeviceDependencyController extends MapController |
||
34 | { |
||
35 | protected $isolatedDeviceId = -1; |
||
36 | |||
37 | protected $deviceIdAll = []; |
||
38 | |||
39 | private $parentDeviceIds = []; |
||
40 | |||
41 | protected static function deviceList($request) |
||
42 | { |
||
43 | $group_id = $request->get('group'); |
||
44 | |||
45 | if (! $group_id) { |
||
46 | return Device::hasAccess($request->user())->with('parents', 'location')->get(); |
||
47 | } |
||
48 | |||
49 | $devices = Device::inDeviceGroup($group_id) |
||
50 | ->hasAccess($request->user()) |
||
51 | ->with([ |
||
52 | 'location', |
||
53 | 'parents' => function ($query) use ($request) { |
||
54 | $query->hasAccess($request->user()); |
||
55 | }, |
||
56 | 'children' => function ($query) use ($request) { |
||
57 | $query->hasAccess($request->user()); |
||
58 | }, ]) |
||
59 | ->get(); |
||
60 | |||
61 | return $devices->merge($devices->map->only('children', 'parents')->flatten())->loadMissing('parents', 'location'); |
||
62 | } |
||
63 | |||
64 | protected function highlightDevices($devices_by_id, $device_id_list) |
||
65 | { |
||
66 | $new_device_list = []; |
||
67 | foreach ($devices_by_id as $device) { |
||
68 | if (in_array($device['id'], $device_id_list)) { |
||
69 | $new_device_list[] = array_merge($device, $this->nodeHighlightStyle()); |
||
70 | continue; |
||
71 | } |
||
72 | $new_device_list[] = $device; |
||
73 | } |
||
74 | |||
75 | return $new_device_list; |
||
76 | } |
||
77 | |||
78 | protected function getParentDevices($device) |
||
79 | { |
||
80 | foreach ($device->parents as $parent) { |
||
81 | if (! in_array($parent->device_id, $this->deviceIdAll)) { |
||
82 | continue; |
||
83 | } |
||
84 | if (in_array($parent->device_id, $this->parentDeviceIds)) { |
||
85 | continue; |
||
86 | } |
||
87 | $this->parentDeviceIds[] = $parent->device_id; |
||
88 | if ($parent) { |
||
89 | $this->getParentDevices($parent); |
||
90 | } |
||
91 | } |
||
92 | } |
||
93 | |||
94 | // Device Dependency Map |
||
95 | public function dependencyMap(Request $request) |
||
96 | { |
||
97 | $group_id = $request->get('group'); |
||
98 | $highlight_node = $request->get('highlight_node'); |
||
99 | $show_device_path = $request->get('showparentdevicepath'); |
||
100 | |||
101 | $dependencies = []; |
||
102 | $devices_by_id = []; |
||
103 | $device_list = []; |
||
104 | |||
105 | // collect Device IDs and Parents/Children to find isolated Devices |
||
106 | $device_associations = []; |
||
107 | |||
108 | // List all devices |
||
109 | foreach (self::deviceList($request) as $device) { |
||
110 | $device_list[] = ['id' => $device->device_id, 'label' => $device->hostname]; |
||
111 | $this->deviceIdAll[] = $device->device_id; |
||
112 | |||
113 | // List all Device |
||
114 | $devices_by_id[] = array_merge( |
||
115 | [ |
||
116 | 'id' => $device->device_id, |
||
117 | 'label' => $device->shortDisplayName(), |
||
118 | 'title' => Url::deviceLink($device, null, [], 0, 0, 0, 0), |
||
119 | 'shape' => 'box', |
||
120 | ], |
||
121 | $this->deviceStyle($device, $highlight_node) |
||
122 | ); |
||
123 | |||
124 | // List all Device Dependencies |
||
125 | $children = $device->children; |
||
126 | foreach ($children as $child) { |
||
127 | $device_associations[] = $child->device_id; |
||
128 | } |
||
129 | |||
130 | $parents = $device->parents; |
||
131 | foreach ($parents as $parent) { |
||
132 | $device_associations[] = $parent->device_id; |
||
133 | $dependencies[] = [ |
||
134 | 'from' => $device->device_id, |
||
135 | 'to' => $parent->device_id, |
||
136 | 'width' => 2, |
||
137 | ]; |
||
138 | } |
||
139 | } |
||
140 | |||
141 | // highlight isolated Devices |
||
142 | if ($highlight_node == $this->isolatedDeviceId) { |
||
143 | $device_associations = array_unique($device_associations); |
||
144 | $isolated_device_ids = array_diff($this->deviceIdAll, $device_associations); |
||
145 | |||
146 | $devices_by_id = $this->highlightDevices($devices_by_id, $isolated_device_ids); |
||
147 | } elseif ($show_device_path && ($highlight_node > 0)) { |
||
148 | foreach (self::deviceList($request) as $device) { |
||
149 | if ($device->device_id != $highlight_node) { |
||
150 | continue; |
||
151 | } |
||
152 | $this->getParentDevices($device); |
||
153 | break; |
||
154 | } |
||
155 | $devices_by_id = $this->highlightDevices($devices_by_id, $this->parentDeviceIds); |
||
156 | } |
||
157 | |||
158 | $device_list_labels = array_column($device_list, 'label'); |
||
159 | array_multisort($device_list_labels, SORT_ASC, $device_list); |
||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
160 | |||
161 | $group_name = DeviceGroup::where('id', '=', $group_id)->first('name'); |
||
162 | if (! empty($group_name)) { |
||
163 | $group_name = $group_name->name; |
||
164 | } |
||
165 | |||
166 | $data = [ |
||
167 | 'showparentdevicepath' => $show_device_path, |
||
168 | 'isolated_device_id' => $this->isolatedDeviceId, |
||
169 | 'device_list' => $device_list, |
||
170 | 'group_id' => $group_id, |
||
171 | 'highlight_node' => $highlight_node, |
||
172 | 'node_count' => count($devices_by_id), |
||
173 | 'options' => $this->visOptions(), |
||
174 | 'nodes' => json_encode(array_values($devices_by_id)), |
||
175 | 'edges' => json_encode($dependencies), |
||
176 | 'group_name' => $group_name, |
||
177 | ]; |
||
178 | |||
179 | return view('map.device-dependency', $data); |
||
180 | } |
||
181 | } |
||
182 |