1 | <?php |
||
2 | /** |
||
3 | * Server module for HiPanel |
||
4 | * |
||
5 | * @link https://github.com/hiqdev/hipanel-module-server |
||
6 | * @package hipanel-module-server |
||
7 | * @license BSD-3-Clause |
||
8 | * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/) |
||
9 | */ |
||
10 | |||
11 | namespace hipanel\modules\server\controllers; |
||
12 | |||
13 | use hipanel\actions\Action; |
||
14 | use hipanel\actions\ComboSearchAction; |
||
15 | use hipanel\actions\IndexAction; |
||
16 | use hipanel\actions\PrepareBulkAction; |
||
17 | use hipanel\actions\ProxyAction; |
||
18 | use hipanel\actions\RedirectAction; |
||
19 | use hipanel\actions\RenderAction; |
||
20 | use hipanel\actions\RenderJsonAction; |
||
21 | use hipanel\actions\RequestStateAction; |
||
22 | use hipanel\actions\SmartCreateAction; |
||
23 | use hipanel\actions\SmartDeleteAction; |
||
24 | use hipanel\actions\SmartPerformAction; |
||
25 | use hipanel\actions\SmartUpdateAction; |
||
26 | use hipanel\actions\ValidateFormAction; |
||
27 | use hipanel\actions\ViewAction; |
||
28 | use hipanel\base\CrudController; |
||
29 | use hipanel\filters\EasyAccessControl; |
||
30 | use hipanel\models\Ref; |
||
31 | use hipanel\modules\finance\models\Tariff; |
||
32 | use hipanel\modules\server\cart\ServerRenewProduct; |
||
33 | use hipanel\modules\server\forms\AssignHubsForm; |
||
34 | use hipanel\modules\server\forms\ServerForm; |
||
35 | use hipanel\modules\server\helpers\ServerHelper; |
||
36 | use hipanel\modules\server\models\HardwareSettings; |
||
37 | use hipanel\modules\server\models\MailSettings; |
||
38 | use hipanel\modules\server\models\MonitoringSettings; |
||
39 | use hipanel\modules\server\models\Osimage; |
||
40 | use hipanel\modules\server\models\query\ServerQuery; |
||
41 | use hipanel\modules\server\models\Server; |
||
42 | use hipanel\modules\server\models\ServerUseSearch; |
||
43 | use hipanel\modules\server\models\SoftwareSettings; |
||
44 | use hipanel\modules\server\widgets\ResourceConsumption; |
||
45 | use hiqdev\hiart\Collection; |
||
46 | use hiqdev\hiart\ResponseErrorException; |
||
47 | use hiqdev\yii2\cart\actions\AddToCartAction; |
||
48 | use Yii; |
||
49 | use yii\base\Event; |
||
50 | use yii\filters\VerbFilter; |
||
51 | use yii\helpers\ArrayHelper; |
||
52 | use yii\web\NotFoundHttpException; |
||
53 | use yii\web\Response; |
||
54 | |||
55 | class ServerController extends CrudController |
||
56 | { |
||
57 | public function behaviors() |
||
58 | { |
||
59 | return array_merge(parent::behaviors(), [ |
||
60 | 'server-actions-verb' => [ |
||
61 | 'class' => VerbFilter::class, |
||
62 | 'actions' => [ |
||
63 | 'reboot' => ['post'], |
||
64 | 'reset' => ['post'], |
||
65 | 'shutdown' => ['post'], |
||
66 | 'power-off' => ['post'], |
||
67 | 'power-on' => ['post'], |
||
68 | 'reset-password' => ['post'], |
||
69 | 'enable-block' => ['post'], |
||
70 | 'disable-block' => ['post'], |
||
71 | 'refuse' => ['post'], |
||
72 | 'flush-switch-graphs' => ['post'], |
||
73 | ], |
||
74 | ], |
||
75 | [ |
||
76 | 'class' => EasyAccessControl::class, |
||
77 | 'actions' => [ |
||
78 | 'monitoring-settings' => 'support', |
||
79 | 'software-settings' => 'support', |
||
80 | 'hardware-settings' => 'support', |
||
81 | 'create' => 'server.create', |
||
82 | 'update' => 'server.update', |
||
83 | 'delete' => 'server.delete', |
||
84 | 'renew' => 'server.pay', |
||
85 | 'refuse' => 'server.pay', |
||
86 | 'assign-hubs' => 'server.update', |
||
87 | 'set-units' => 'server.update', |
||
88 | 'set-rack-no' => 'server.update', |
||
89 | 'reboot' => 'server.control-power', |
||
90 | 'shutdown' => 'server.control-power', |
||
91 | 'power-on' => 'server.control-power', |
||
92 | 'power-off' => 'server.control-power', |
||
93 | 'reset' => 'server.control-power', |
||
94 | 'reinstall' => 'server.control-system', |
||
95 | 'boot-live' => 'server.control-system', |
||
96 | 'enable-wizzard' => 'server.update', |
||
97 | 'disable-wizzard' => 'server.wizzard', |
||
98 | 'enable-vnc' => 'server.control-system', |
||
99 | 'enable-block' => 'server.enable-block', |
||
100 | 'disable-block' => 'server.disable-block', |
||
101 | 'set-label' => 'server.set-label', |
||
102 | 'set-note' => 'server.set-note', |
||
103 | 'clear-resources' => 'consumption.delete', |
||
104 | 'flush-switch-graphs' => 'consumption.delete', |
||
105 | '*' => 'server.read', |
||
106 | ], |
||
107 | ], |
||
108 | ]); |
||
109 | } |
||
110 | |||
111 | 1 | public function actions() |
|
112 | { |
||
113 | 1 | return array_merge(parent::actions(), [ |
|
114 | 1 | 'index' => [ |
|
115 | 'class' => IndexAction::class, |
||
116 | 'findOptions' => ['with_requests' => true, 'with_discounts' => true], |
||
117 | 1 | 'on beforePerform' => function (Event $event) { |
|
118 | /** @var \hipanel\actions\SearchAction $action */ |
||
119 | $action = $event->sender; |
||
120 | $dataProvider = $action->getDataProvider(); |
||
121 | |||
122 | $dataProvider->query->withBindings(); |
||
123 | |||
124 | if (Yii::getAlias('@ip', false)) { |
||
125 | $dataProvider->query |
||
126 | ->joinWith(['ips']) |
||
127 | ->andWhere(['with_ips' => 1]); |
||
128 | } |
||
129 | |||
130 | if ($this->indexPageUiOptionsModel->representation === 'billing' && Yii::$app->user->can('consumption.read')) { |
||
131 | $dataProvider->query->withConsumptions()->withHardwareSales(); |
||
132 | } |
||
133 | |||
134 | $dataProvider->query |
||
135 | ->andWhere(['with_requests' => 1]) |
||
136 | ->andWhere(['with_discounts' => 1]) |
||
137 | ->select(['*']); |
||
138 | 1 | }, |
|
139 | 'filterStorageMap' => [ |
||
140 | 'name_dc' => 'server.server.name_dc', |
||
141 | 'name_like' => 'server.server.name', |
||
142 | 'label_like' => 'server.server.label', |
||
143 | 'note_like' => 'server.server.note', |
||
144 | 'order_no' => 'server.server.order_no', |
||
145 | 'dc_like' => 'server.server.dc', |
||
146 | 'ip_like' => 'server.server.ip', |
||
147 | |||
148 | 'ips' => 'hosting.ip.ip_in', |
||
149 | 'client_id' => 'client.client.id', |
||
150 | 'seller_id' => 'client.client.seller_id', |
||
151 | |||
152 | 'hwsummary_like' => 'server.server.hwsummary', |
||
153 | 'type' => 'server.server.type', |
||
154 | 'state' => 'server.server.state', |
||
155 | 'net_like' => 'server.server.net', |
||
156 | 'kvm_like' => 'server.server.kvm', |
||
157 | 'pdu_like' => 'server.server.pdu', |
||
158 | 'rack_like' => 'server.server.rack', |
||
159 | 'mac_like' => 'server.server.mac', |
||
160 | |||
161 | 'tariff_like' => 'server.server.tariff', |
||
162 | 'wizzarded_eq' => 'server.server.wizzarded', |
||
163 | ], |
||
164 | ], |
||
165 | 'search' => [ |
||
166 | 'class' => ComboSearchAction::class, |
||
167 | ], |
||
168 | 'create' => [ |
||
169 | 'class' => SmartCreateAction::class, |
||
170 | 'collection' => [ |
||
171 | 'class' => Collection::class, |
||
172 | 1 | 'model' => new ServerForm(['scenario' => 'create']), |
|
173 | 1 | 'scenario' => 'create', |
|
174 | ], |
||
175 | 1 | 'success' => Yii::t('hipanel:server', 'Server has been created'), |
|
176 | ], |
||
177 | 'update' => [ |
||
178 | 'class' => SmartUpdateAction::class, |
||
179 | 'collection' => [ |
||
180 | 'class' => Collection::class, |
||
181 | 1 | 'model' => new ServerForm(), |
|
182 | 1 | 'scenario' => 'update', |
|
183 | ], |
||
184 | 1 | 'on beforeFetch' => function (Event $event) { |
|
185 | /** @var \hipanel\actions\SearchAction $action */ |
||
186 | $action = $event->sender; |
||
187 | $dataProvider = $action->getDataProvider(); |
||
188 | if (Yii::getAlias('@ip', false)) { |
||
189 | $dataProvider->query->joinWith('ips'); |
||
190 | } |
||
191 | 1 | }, |
|
192 | 1 | 'data' => function (Action $action, array $data) { |
|
193 | $result = []; |
||
194 | foreach ($data['models'] as $model) { |
||
195 | $result['models'][] = ServerForm::fromServer($model); |
||
196 | } |
||
197 | $result['model'] = reset($result['models']); |
||
198 | |||
199 | return $result; |
||
200 | 1 | }, |
|
201 | 1 | 'success' => Yii::t('hipanel:server', 'Server has been updated'), |
|
202 | ], |
||
203 | 'assign-hubs' => [ |
||
204 | 'class' => SmartUpdateAction::class, |
||
205 | 1 | 'success' => Yii::t('hipanel:server', 'Hubs have been assigned'), |
|
206 | 1 | 'view' => 'assign-hubs', |
|
207 | 1 | 'on beforeFetch' => function (Event $event) { |
|
208 | /** @var \hipanel\actions\SearchAction $action */ |
||
209 | $action = $event->sender; |
||
210 | $dataProvider = $action->getDataProvider(); |
||
211 | $dataProvider->query->withBindings()->select(['*']); |
||
212 | 1 | }, |
|
213 | 'collection' => [ |
||
214 | 'class' => Collection::class, |
||
215 | 1 | 'model' => new AssignHubsForm(), |
|
216 | 1 | 'scenario' => 'default', |
|
217 | ], |
||
218 | 1 | 'data' => function (Action $action, array $data) { |
|
219 | $result = []; |
||
220 | foreach ($data['models'] as $model) { |
||
221 | $result['models'][] = AssignHubsForm::fromOriginalModel($model); |
||
222 | } |
||
223 | if (!$result['models']) { |
||
224 | throw new NotFoundHttpException('There are no entries available for the selected operation. The type of selected records may not be suitable for the selected operation.'); |
||
225 | } |
||
226 | $result['model'] = reset($result['models']); |
||
227 | |||
228 | return $result; |
||
229 | 1 | }, |
|
230 | ], |
||
231 | 'set-units' => [ |
||
232 | 'class' => SmartUpdateAction::class, |
||
233 | 1 | 'success' => Yii::t('hipanel:server', 'Units property was changed'), |
|
234 | 1 | 'view' => 'setUnits', |
|
235 | 1 | 'on beforeSave' => function (Event $event) { |
|
236 | /** @var \hipanel\actions\Action $action */ |
||
237 | $action = $event->sender; |
||
238 | $servers = Yii::$app->request->post('HardwareSettings'); |
||
239 | $units = ArrayHelper::remove($servers, 'units'); |
||
240 | foreach ($servers as $id => $server) { |
||
241 | $servers[$id]['units'] = $units; |
||
242 | } |
||
243 | $action->collection->load($servers); |
||
244 | 1 | }, |
|
245 | 1 | 'on beforeFetch' => function (Event $event) { |
|
246 | /** @var \hipanel\actions\SearchAction $action */ |
||
247 | $action = $event->sender; |
||
248 | /** @var ServerQuery $query */ |
||
249 | $query = $action->getDataProvider()->query; |
||
250 | $query->withHardwareSettings(); |
||
251 | 1 | }, |
|
252 | 1 | 'on beforeLoad' => function (Event $event) { |
|
253 | /** @var Action $action */ |
||
254 | $action = $event->sender; |
||
255 | |||
256 | $action->collection->setModel(new HardwareSettings(['scenario' => 'set-units'])); |
||
257 | 1 | }, |
|
258 | ], |
||
259 | 'set-rack-no' => [ |
||
260 | 'class' => SmartUpdateAction::class, |
||
261 | 1 | 'success' => Yii::t('hipanel:server', 'Rack No. was assigned'), |
|
262 | 1 | 'view' => 'setRackNo', |
|
263 | 'collection' => [ |
||
264 | 'class' => Collection::class, |
||
265 | 1 | 'model' => new AssignHubsForm(), |
|
266 | 1 | 'scenario' => 'default', |
|
267 | ], |
||
268 | 1 | 'on beforeSave' => function (Event $event) { |
|
269 | /** @var \hipanel\actions\Action $action */ |
||
270 | $action = $event->sender; |
||
271 | $servers = Yii::$app->request->post('AssignHubsForm'); |
||
272 | $rackId = ArrayHelper::remove($servers, 'rack_id'); |
||
273 | $rackPort = ArrayHelper::remove($servers, 'rack_port'); |
||
274 | foreach ($servers as $id => $server) { |
||
275 | $servers[$id]['rack_id'] = $rackId; |
||
276 | $servers[$id]['rack_port'] = $rackPort; |
||
277 | } |
||
278 | $action->collection->load($servers); |
||
279 | 1 | }, |
|
280 | 1 | 'on beforeFetch' => function (Event $event) { |
|
281 | /** @var \hipanel\actions\SearchAction $action */ |
||
282 | $action = $event->sender; |
||
283 | $dataProvider = $action->getDataProvider(); |
||
284 | $dataProvider->query->withBindings()->select(['*']); |
||
285 | 1 | }, |
|
286 | 1 | 'data' => function (Action $action, array $data) { |
|
287 | $result = []; |
||
288 | foreach ($data['models'] as $model) { |
||
289 | $result['models'][] = AssignHubsForm::fromOriginalModel($model); |
||
290 | } |
||
291 | if (!$result['models']) { |
||
292 | throw new NotFoundHttpException('There are no entries available for the selected operation. The type of selected records may not be suitable for the selected operation.'); |
||
293 | } |
||
294 | $result['model'] = reset($result['models']); |
||
295 | |||
296 | return $result; |
||
297 | 1 | }, |
|
298 | ], |
||
299 | 'hardware-settings' => [ |
||
300 | 'class' => SmartUpdateAction::class, |
||
301 | 1 | 'success' => Yii::t('hipanel:server', 'Hardware properties was changed'), |
|
302 | 1 | 'view' => 'modal/hardwareSettings', |
|
303 | 1 | 'on beforeFetch' => function (Event $event) { |
|
304 | /** @var \hipanel\actions\SearchAction $action */ |
||
305 | $action = $event->sender; |
||
306 | /** @var ServerQuery $query */ |
||
307 | $query = $action->getDataProvider()->query; |
||
308 | $query->withHardwareSettings(); |
||
309 | 1 | }, |
|
310 | 1 | 'on beforeLoad' => function (Event $event) { |
|
311 | /** @var Action $action */ |
||
312 | $action = $event->sender; |
||
313 | |||
314 | $action->collection->setModel(HardwareSettings::class); |
||
315 | 1 | }, |
|
316 | 'POST html' => [ |
||
317 | 'save' => true, |
||
318 | 'success' => [ |
||
319 | 'class' => RedirectAction::class, |
||
320 | 1 | 'url' => function () { |
|
321 | $server = Yii::$app->request->post('HardwareSettings'); |
||
322 | |||
323 | return ['@server/view', 'id' => $server['id']]; |
||
324 | 1 | }, |
|
325 | ], |
||
326 | ], |
||
327 | ], |
||
328 | 'software-settings' => [ |
||
329 | 'class' => SmartUpdateAction::class, |
||
330 | 1 | 'success' => Yii::t('hipanel:server', 'Software properties was changed'), |
|
331 | 1 | 'view' => 'modal/softwareSettings', |
|
332 | 1 | 'scenario' => 'default', |
|
333 | 1 | 'on beforeFetch' => function (Event $event) { |
|
334 | /** @var \hipanel\actions\SearchAction $action */ |
||
335 | $action = $event->sender; |
||
336 | /** @var ServerQuery $query */ |
||
337 | $query = $action->getDataProvider()->query; |
||
338 | $query->withSoftwareSettings(); |
||
339 | 1 | }, |
|
340 | 1 | 'on beforeLoad' => function (Event $event) { |
|
341 | /** @var Action $action */ |
||
342 | $action = $event->sender; |
||
343 | |||
344 | $action->collection->setModel(SoftwareSettings::class); |
||
345 | 1 | }, |
|
346 | 'POST html' => [ |
||
347 | 'save' => true, |
||
348 | 'success' => [ |
||
349 | 'class' => RedirectAction::class, |
||
350 | 1 | 'url' => function () { |
|
351 | $server = Yii::$app->request->post('SoftwareSettings'); |
||
352 | |||
353 | return ['@server/view', 'id' => $server['id']]; |
||
354 | 1 | }, |
|
355 | ], |
||
356 | ], |
||
357 | ], |
||
358 | 'monitoring-settings' => [ |
||
359 | 'class' => SmartUpdateAction::class, |
||
360 | 1 | 'success' => Yii::t('hipanel:server', 'Monitoring properties was changed'), |
|
361 | 1 | 'view' => 'modal/monitoringSettings', |
|
362 | 1 | 'scenario' => 'default', |
|
363 | 1 | 'on beforeFetch' => function (Event $event) { |
|
364 | /** @var \hipanel\actions\SearchAction $action */ |
||
365 | $action = $event->sender; |
||
366 | $query = $action->getDataProvider()->query; |
||
367 | $query->withMonitoringSettings()->select(['*']); |
||
368 | 1 | }, |
|
369 | 1 | 'on beforeLoad' => function (Event $event) { |
|
370 | /** @var Action $action */ |
||
371 | $action = $event->sender; |
||
372 | |||
373 | $action->collection->setModel(MonitoringSettings::class); |
||
374 | 1 | }, |
|
375 | 1 | 'data' => function ($action) { |
|
376 | return [ |
||
377 | 'nicMediaOptions' => $action->controller->getFullFromRef('type,nic_media'), |
||
378 | ]; |
||
379 | 1 | }, |
|
380 | 'POST html' => [ |
||
381 | 'save' => true, |
||
382 | 'success' => [ |
||
383 | 'class' => RedirectAction::class, |
||
384 | 1 | 'url' => function () { |
|
385 | $server = Yii::$app->request->post('MonitoringSettings'); |
||
386 | |||
387 | return ['@server/view', 'id' => $server['id']]; |
||
388 | 1 | }, |
|
389 | ], |
||
390 | ], |
||
391 | ], |
||
392 | 'mail-settings' => [ |
||
393 | 'class' => SmartUpdateAction::class, |
||
394 | 1 | 'success' => Yii::t('hipanel:server', 'Mail settings have been changed successfully'), |
|
395 | 1 | 'view' => 'modal/mailSettings', |
|
396 | 1 | 'scenario' => 'default', |
|
397 | 1 | 'on beforeFetch' => function (Event $event) { |
|
398 | /** @var \hipanel\actions\SearchAction $action */ |
||
399 | $action = $event->sender; |
||
400 | $query = $action->getDataProvider()->query; |
||
401 | $query->withMailSettings()->select(['*']); |
||
402 | 1 | }, |
|
403 | 1 | 'on beforeLoad' => function (Event $event) { |
|
404 | /** @var Action $action */ |
||
405 | $action = $event->sender; |
||
406 | |||
407 | $action->collection->setModel(MailSettings::class); |
||
408 | 1 | }, |
|
409 | 'POST html' => [ |
||
410 | 'save' => true, |
||
411 | 'success' => [ |
||
412 | 'class' => RedirectAction::class, |
||
413 | 1 | 'url' => function () { |
|
414 | $server = Yii::$app->request->post('MailSettings'); |
||
415 | |||
416 | return ['@server/view', 'id' => $server['id']]; |
||
417 | 1 | }, |
|
418 | ], |
||
419 | ], |
||
420 | ], |
||
421 | 'view' => [ |
||
422 | 'class' => ViewAction::class, |
||
423 | 1 | 'on beforePerform' => function (Event $event) { |
|
424 | /** @var \hipanel\actions\SearchAction $action */ |
||
425 | $action = $event->sender; |
||
426 | /** @var ServerQuery $query */ |
||
427 | $query = $action->getDataProvider()->query; |
||
428 | $query |
||
429 | ->withSoftwareSettings() |
||
430 | ->withHardwareSettings() |
||
431 | ->withBindings() |
||
432 | ->withBlocking() |
||
433 | ->withUses() |
||
434 | ->withConsumptions() |
||
435 | ->withSales() |
||
436 | ->joinWith(['switches']); |
||
437 | |||
438 | if (Yii::getAlias('@ip', false)) { |
||
439 | $query |
||
440 | ->joinWith(['ips']) |
||
441 | ->andWhere(['with_ips' => 1]); |
||
442 | } |
||
443 | |||
444 | // TODO: ipModule is not wise yet. Redo |
||
445 | $query |
||
446 | ->andWhere(['with_requests' => 1]) |
||
447 | ->andWhere(['show_deleted' => 1]) |
||
448 | ->andWhere(['with_discounts' => 1]) |
||
449 | ->select(['*']); |
||
450 | 1 | }, |
|
451 | 1 | 'data' => function ($action) { |
|
452 | /** |
||
453 | * @var Action |
||
454 | * @var self $controller |
||
455 | * @var Server $model |
||
456 | */ |
||
457 | $controller = $action->controller; |
||
458 | $model = $action->getModel(); |
||
459 | $model->vnc = $controller->getVNCInfo($model); |
||
460 | |||
461 | $panels = $controller->getPanelTypes(); |
||
462 | |||
463 | $cacheKeys = [__METHOD__, 'view', 'tariff', $model->tariff_id, Yii::$app->user->getId()]; |
||
464 | $tariff = Yii::$app->cache->getOrSet($cacheKeys, function () use ($model) { |
||
465 | return Tariff::find()->where([ |
||
466 | 'id' => $model->tariff_id, |
||
467 | 'show_final' => true, |
||
468 | 'show_deleted' => true, |
||
469 | 'with_resources' => true, |
||
470 | ])->joinWith('resources')->one(); |
||
471 | }); |
||
472 | |||
473 | $ispSupported = false; |
||
474 | if ($tariff !== null) { |
||
475 | foreach ($tariff->getResources() as $resource) { |
||
476 | if ($resource->type === 'isp' && $resource->quantity > 0) { |
||
477 | $ispSupported = true; |
||
478 | } |
||
479 | } |
||
480 | } |
||
481 | |||
482 | $osimages = $controller->getOsimages($model); |
||
483 | $groupedOsimages = ServerHelper::groupOsimages($osimages, $ispSupported); |
||
484 | |||
485 | if ($model->isLiveCDSupported()) { |
||
486 | $osimageslivecd = $controller->getOsimagesLiveCd(); |
||
487 | } |
||
488 | |||
489 | $blockReasons = $controller->getBlockReasons(); |
||
490 | |||
491 | return compact([ |
||
492 | 'model', |
||
493 | 'osimages', |
||
494 | 'osimageslivecd', |
||
495 | 'groupedOsimages', |
||
496 | 'panels', |
||
497 | 'blockReasons', |
||
498 | ]); |
||
499 | 1 | }, |
|
500 | ], |
||
501 | 'resources' => [ |
||
502 | 'class' => ViewAction::class, |
||
503 | 1 | 'view' => 'resources', |
|
504 | 1 | 'on beforePerform' => function (Event $event) { |
|
505 | /** @var \hipanel\actions\SearchAction $action */ |
||
506 | $action = $event->sender; |
||
507 | $dataProvider = $action->getDataProvider(); |
||
508 | $dataProvider->query->withUses()->select(['*']); |
||
509 | 1 | }, |
|
510 | 1 | 'data' => function ($action) { |
|
511 | $model = $action->getModel(); |
||
512 | list($chartsLabels, $chartsData) = $model->groupUsesForCharts(); |
||
513 | |||
514 | return compact('model', 'chartsData', 'chartsLabels'); |
||
515 | 1 | }, |
|
516 | ], |
||
517 | 'requests-state' => [ |
||
518 | 'class' => RequestStateAction::class, |
||
519 | 'model' => Server::class, |
||
520 | ], |
||
521 | 'set-note' => [ |
||
522 | 'class' => SmartUpdateAction::class, |
||
523 | 1 | 'view' => 'modal/_bulkSetNote', |
|
524 | 1 | 'success' => Yii::t('hipanel:server', 'Note changed'), |
|
525 | 1 | 'error' => Yii::t('hipanel:server', 'Failed to change note'), |
|
526 | ], |
||
527 | 'set-label' => [ |
||
528 | 'class' => SmartUpdateAction::class, |
||
529 | 1 | 'view' => 'modal/_bulkSetLabel', |
|
530 | 1 | 'success' => Yii::t('hipanel:server', 'Internal note changed'), |
|
531 | 1 | 'error' => Yii::t('hipanel:server', 'Failed to change internal note'), |
|
532 | ], |
||
533 | 'set-lock' => [ |
||
534 | 'class' => RenderAction::class, |
||
535 | 1 | 'success' => Yii::t('hipanel:server', 'Record was changed'), |
|
536 | 1 | 'error' => Yii::t('hipanel:server', 'Error occurred'), |
|
537 | 'POST pjax' => [ |
||
538 | 'save' => true, |
||
539 | 'success' => [ |
||
540 | 'class' => ProxyAction::class, |
||
541 | 'action' => 'index', |
||
542 | ], |
||
543 | ], |
||
544 | 'POST' => [ |
||
545 | 'save' => true, |
||
546 | 'success' => [ |
||
547 | 'class' => RenderJsonAction::class, |
||
548 | 1 | 'return' => function ($action) { |
|
549 | /** @var \hipanel\actions\Action $action */ |
||
550 | return $action->collection->models; |
||
551 | 1 | }, |
|
552 | ], |
||
553 | ], |
||
554 | ], |
||
555 | 'enable-vnc' => [ |
||
556 | 'class' => ViewAction::class, |
||
557 | 1 | 'view' => '_vnc', |
|
558 | 1 | 'data' => function ($action) { |
|
559 | $model = $action->getModel(); |
||
560 | if ($model->canEnableVNC()) { |
||
561 | $model->vnc = $this->getVNCInfo($model, true); |
||
562 | } |
||
563 | |||
564 | return []; |
||
565 | 1 | }, |
|
566 | ], |
||
567 | 'bulk-sale' => [ |
||
568 | 'class' => SmartUpdateAction::class, |
||
569 | 1 | 'scenario' => 'sale', |
|
570 | 1 | 'view' => 'modal/_bulkSale', |
|
571 | 1 | 'success' => Yii::t('hipanel:server', 'Servers were sold'), |
|
572 | 'POST pjax' => [ |
||
573 | 'save' => true, |
||
574 | 'success' => [ |
||
575 | 'class' => ProxyAction::class, |
||
576 | 'action' => 'index', |
||
577 | ], |
||
578 | ], |
||
579 | 1 | 'on beforeSave' => function (Event $event) { |
|
580 | /** @var \hipanel\actions\Action $action */ |
||
581 | $action = $event->sender; |
||
582 | $request = Yii::$app->request; |
||
0 ignored issues
–
show
|
|||
583 | |||
584 | if ($request->isPost) { |
||
585 | $values = []; |
||
586 | foreach (['client_id', 'tariff_id', 'sale_time', 'move_accounts'] as $attribute) { |
||
587 | $value = $request->post($attribute); |
||
588 | if (!empty($value)) { |
||
589 | $values[$attribute] = $value; |
||
590 | } |
||
591 | } |
||
592 | foreach ($action->collection->models as $model) { |
||
593 | foreach ($values as $attr => $value) { |
||
594 | $model->setAttribute($attr, $value); |
||
595 | } |
||
596 | } |
||
597 | } |
||
598 | 1 | }, |
|
599 | ], |
||
600 | 'set-one-type' => [ |
||
601 | 'class' => SmartUpdateAction::class, |
||
602 | 1 | 'view' => 'setOneType', |
|
603 | 1 | 'success' => Yii::t('hipanel:server', 'Type was changed'), |
|
604 | 1 | 'error' => Yii::t('hipanel:server', 'Failed to change type'), |
|
605 | 1 | 'scenario' => 'set-type', |
|
606 | 1 | 'on beforeSave' => function (Event $event) { |
|
607 | /** @var \hipanel\actions\Action $action */ |
||
608 | $action = $event->sender; |
||
609 | $servers = Yii::$app->request->post('Server'); |
||
610 | $type = ArrayHelper::remove($servers, 'type'); |
||
611 | foreach ($servers as $id => $server) { |
||
612 | $servers[$id]['type'] = $type; |
||
613 | } |
||
614 | $action->collection->setModel($this->newModel(['scenario' => 'set-type'])); |
||
615 | $action->collection->load($servers); |
||
616 | 1 | }, |
|
617 | ], |
||
618 | 'set-type' => [ |
||
619 | 'class' => SmartUpdateAction::class, |
||
620 | 1 | 'view' => '_bulkSetType', |
|
621 | 1 | 'success' => Yii::t('hipanel:server', 'Type was changed'), |
|
622 | 1 | 'error' => Yii::t('hipanel:server', 'Failed to change type'), |
|
623 | ], |
||
624 | 'reboot' => [ |
||
625 | 'class' => SmartPerformAction::class, |
||
626 | 1 | 'success' => Yii::t('hipanel:server', 'Reboot task has been successfully added to queue'), |
|
627 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the rebooting'), |
|
628 | ], |
||
629 | 'reset' => [ |
||
630 | 'class' => SmartPerformAction::class, |
||
631 | 1 | 'success' => Yii::t('hipanel:server', 'Reset task has been successfully added to queue'), |
|
632 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the resetting'), |
|
633 | ], |
||
634 | 'shutdown' => [ |
||
635 | 'class' => SmartPerformAction::class, |
||
636 | 1 | 'success' => Yii::t('hipanel:server', 'Shutdown task has been successfully added to queue'), |
|
637 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the shutting down'), |
|
638 | ], |
||
639 | 'power-off' => [ |
||
640 | 'class' => SmartPerformAction::class, |
||
641 | 1 | 'success' => Yii::t('hipanel:server', 'Power off task has been successfully added to queue'), |
|
642 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the turning power off'), |
|
643 | ], |
||
644 | 'power-on' => [ |
||
645 | 'class' => SmartPerformAction::class, |
||
646 | 1 | 'success' => Yii::t('hipanel:server', 'Power on task has been successfully added to queue'), |
|
647 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the turning power on'), |
|
648 | ], |
||
649 | 'reset-password' => [ |
||
650 | 'class' => SmartPerformAction::class, |
||
651 | 1 | 'success' => Yii::t('hipanel:server', 'Root password reset task has been successfully added to queue'), |
|
652 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the resetting root password'), |
|
653 | ], |
||
654 | 'enable-block' => [ |
||
655 | 'class' => SmartPerformAction::class, |
||
656 | 1 | 'success' => Yii::t('hipanel:server', 'Server was blocked successfully'), |
|
657 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the server blocking'), |
|
658 | 'POST html' => [ |
||
659 | 'save' => true, |
||
660 | 'success' => [ |
||
661 | 'class' => RedirectAction::class, |
||
662 | ], |
||
663 | ], |
||
664 | 1 | 'on beforeSave' => function (Event $event) { |
|
665 | /** @var \hipanel\actions\Action $action */ |
||
666 | $action = $event->sender; |
||
667 | $type = Yii::$app->request->post('type'); |
||
668 | $comment = Yii::$app->request->post('comment'); |
||
669 | if (!empty($type)) { |
||
670 | foreach ($action->collection->models as $model) { |
||
671 | $model->setAttributes([ |
||
672 | 'type' => $type, |
||
673 | 'comment' => $comment, |
||
674 | ]); |
||
675 | } |
||
676 | } |
||
677 | 1 | }, |
|
678 | ], |
||
679 | 'bulk-enable-block-modal' => [ |
||
680 | 'class' => PrepareBulkAction::class, |
||
681 | 1 | 'view' => 'modal/_bulkEnableBlock', |
|
682 | 1 | 'data' => function ($action, $data) { |
|
683 | return array_merge($data, [ |
||
684 | 'blockReasons' => $this->getBlockReasons(), |
||
685 | ]); |
||
686 | 1 | }, |
|
687 | ], |
||
688 | 'disable-block' => [ |
||
689 | 'class' => SmartPerformAction::class, |
||
690 | 1 | 'success' => Yii::t('hipanel:server', 'Server was unblocked successfully'), |
|
691 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the server unblocking'), |
|
692 | 'POST html' => [ |
||
693 | 'save' => true, |
||
694 | 'success' => [ |
||
695 | 'class' => RedirectAction::class, |
||
696 | ], |
||
697 | ], |
||
698 | 1 | 'on beforeSave' => function (Event $event) { |
|
699 | /** @var \hipanel\actions\Action $action */ |
||
700 | $action = $event->sender; |
||
701 | $type = Yii::$app->request->post('type'); |
||
702 | $comment = Yii::$app->request->post('comment'); |
||
703 | if (!empty($type)) { |
||
704 | foreach ($action->collection->models as $model) { |
||
705 | $model->setAttributes([ |
||
706 | 'comment' => $comment, |
||
707 | 'type' => $type, |
||
708 | ]); |
||
709 | } |
||
710 | } |
||
711 | 1 | }, |
|
712 | ], |
||
713 | 'bulk-disable-block-modal' => [ |
||
714 | 'class' => PrepareBulkAction::class, |
||
715 | 1 | 'view' => 'modal/_bulkDisableBlock', |
|
716 | 1 | 'data' => function ($action, $data) { |
|
717 | return array_merge($data, [ |
||
718 | 'blockReasons' => $this->getBlockReasons(), |
||
719 | ]); |
||
720 | 1 | }, |
|
721 | ], |
||
722 | 'refuse' => [ |
||
723 | 'class' => SmartPerformAction::class, |
||
724 | 1 | 'success' => Yii::t('hipanel:server', 'You have refused the service'), |
|
725 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the refusing the service'), |
|
726 | ], |
||
727 | 'enable-autorenewal' => [ |
||
728 | 'class' => SmartUpdateAction::class, |
||
729 | 1 | 'success' => Yii::t('hipanel:server', 'Server renewal enabled successfully'), |
|
730 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the renewing the service'), |
|
731 | ], |
||
732 | 'reinstall' => [ |
||
733 | 'class' => SmartUpdateAction::class, |
||
734 | 1 | 'on beforeSave' => function (Event $event) { |
|
735 | /** @var Action $action */ |
||
736 | $action = $event->sender; |
||
737 | foreach ($action->collection->models as $model) { |
||
738 | $model->osimage = Yii::$app->request->post('osimage'); |
||
739 | $model->panel = Yii::$app->request->post('panel'); |
||
740 | } |
||
741 | 1 | }, |
|
742 | 1 | 'success' => Yii::t('hipanel:server', 'Server reinstalling task has been successfully added to queue'), |
|
743 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the server reinstalling'), |
|
744 | ], |
||
745 | 'boot-live' => [ |
||
746 | 'class' => SmartPerformAction::class, |
||
747 | 1 | 'on beforeSave' => function (Event $event) { |
|
748 | /** @var Action $action */ |
||
749 | $action = $event->sender; |
||
750 | foreach ($action->collection->models as $model) { |
||
751 | $model->osimage = Yii::$app->request->post('osimage'); |
||
752 | } |
||
753 | 1 | }, |
|
754 | 1 | 'success' => Yii::t('hipanel:server', 'Live CD booting task has been successfully added to queue'), |
|
755 | 1 | 'error' => Yii::t('hipanel:server', 'Error during the booting live CD'), |
|
756 | ], |
||
757 | 'validate-hw-form' => [ |
||
758 | 'class' => ValidateFormAction::class, |
||
759 | 'collection' => [ |
||
760 | 'class' => Collection::class, |
||
761 | 1 | 'model' => new HardwareSettings(), |
|
762 | ], |
||
763 | ], |
||
764 | 'validate-crud-form' => [ |
||
765 | 'class' => ValidateFormAction::class, |
||
766 | 'collection' => [ |
||
767 | 'class' => Collection::class, |
||
768 | 1 | 'model' => new ServerForm(), |
|
769 | ], |
||
770 | ], |
||
771 | 'validate-assign-hubs-form' => [ |
||
772 | 'class' => ValidateFormAction::class, |
||
773 | 'collection' => [ |
||
774 | 'class' => Collection::class, |
||
775 | 1 | 'model' => new AssignHubsForm(), |
|
776 | ], |
||
777 | ], |
||
778 | 'validate-form' => [ |
||
779 | 'class' => ValidateFormAction::class, |
||
780 | ], |
||
781 | 'buy' => [ |
||
782 | 'class' => RedirectAction::class, |
||
783 | 1 | 'url' => Yii::$app->params['organization.url'], |
|
784 | ], |
||
785 | 'add-to-cart-renewal' => [ |
||
786 | 'class' => AddToCartAction::class, |
||
787 | 'productClass' => ServerRenewProduct::class, |
||
788 | ], |
||
789 | 'delete' => [ |
||
790 | 'class' => SmartDeleteAction::class, |
||
791 | 1 | 'success' => Yii::t('hipanel:server', 'Server was deleted successfully'), |
|
792 | 1 | 'error' => Yii::t('hipanel:server', 'Failed to delete server'), |
|
793 | ], |
||
794 | 'bulk-delete-modal' => [ |
||
795 | 'class' => PrepareBulkAction::class, |
||
796 | 'view' => 'modal/_bulkDelete', |
||
797 | ], |
||
798 | 'clear-resources' => [ |
||
799 | 'class' => SmartPerformAction::class, |
||
800 | 1 | 'view' => '_clearResources', |
|
801 | 1 | 'success' => Yii::t('hipanel:server', 'Servers resources were cleared successfully'), |
|
802 | 1 | 'error' => Yii::t('hipanel:server', 'Error occurred during server resources flushing'), |
|
803 | ], |
||
804 | 'clear-resources-modal' => [ |
||
805 | 'class' => PrepareBulkAction::class, |
||
806 | 'view' => '_clearResources', |
||
807 | ], |
||
808 | 'flush-switch-graphs' => [ |
||
809 | 'class' => SmartPerformAction::class, |
||
810 | 1 | 'view' => '_clearResources', |
|
811 | 1 | 'success' => Yii::t('hipanel:server', 'Switch graphs were flushed successfully'), |
|
812 | 1 | 'error' => Yii::t('hipanel:server', 'Error occurred during switch graphs flushing'), |
|
813 | ], |
||
814 | 'flush-switch-graphs-modal' => [ |
||
815 | 'class' => PrepareBulkAction::class, |
||
816 | 'view' => '_flushSwitchGraphs', |
||
817 | ], |
||
818 | ]); |
||
819 | } |
||
820 | |||
821 | /** |
||
822 | * Gets info of VNC on the server. |
||
823 | * |
||
824 | * @param Server $model |
||
825 | * @param bool $enable |
||
826 | * @throws ResponseErrorException |
||
827 | * @return array |
||
828 | */ |
||
829 | public function getVNCInfo($model, $enable = false) |
||
830 | { |
||
831 | if ($enable) { |
||
832 | try { |
||
833 | $vnc = Server::perform('enable-VNC', ['id' => $model->id]); |
||
834 | $vnc['endTime'] = time() + 28800; |
||
835 | Yii::$app->cache->set([__METHOD__, $model->id, $model], $vnc, 28800); |
||
836 | $vnc['enabled'] = true; |
||
837 | } catch (ResponseErrorException $e) { |
||
838 | if ($e->getMessage() !== 'vds_has_tasks') { |
||
839 | throw $e; |
||
840 | } |
||
841 | } |
||
842 | } else { |
||
843 | if ($model->statuses['serverEnableVNC'] !== null && strtotime('+8 hours', strtotime($model->statuses['serverEnableVNC'])) > time()) { |
||
844 | $vnc = Yii::$app->cache->getOrSet([__METHOD__, $model->id, $model], function () use ($model) { |
||
845 | return ArrayHelper::merge([ |
||
846 | 'endTime' => strtotime($model->statuses['serverEnableVNC']) + 28800, |
||
847 | ], Server::perform('enable-VNC', ['id' => $model->id])); |
||
848 | }, 28800); |
||
849 | } |
||
850 | $vnc['enabled'] = $model->statuses['serverEnableVNC'] === null ? false : strtotime('+8 hours', strtotime($model->statuses['serverEnableVNC'])) > time(); |
||
851 | } |
||
852 | |||
853 | return $vnc; |
||
854 | } |
||
855 | |||
856 | public function actionDrawChart() |
||
857 | { |
||
858 | $post = Yii::$app->request->post(); |
||
859 | $types = array_merge(['server_traf', 'server_traf95'], array_keys(ResourceConsumption::types())); |
||
860 | if (!in_array($post['type'], $types, true)) { |
||
861 | throw new NotFoundHttpException(); |
||
862 | } |
||
863 | |||
864 | $searchModel = new ServerUseSearch(); |
||
865 | $dataProvider = $searchModel->search([]); |
||
866 | $dataProvider->pagination = false; |
||
867 | $dataProvider->query->action('get-uses'); |
||
868 | $dataProvider->query->andWhere($post); |
||
869 | $models = $dataProvider->getModels(); |
||
870 | |||
871 | list($labels, $data) = ServerHelper::groupUsesForChart($models); |
||
872 | |||
873 | return $this->renderAjax('_consumption', [ |
||
874 | 'labels' => $labels, |
||
875 | 'data' => $data, |
||
876 | 'consumptionBase' => $post['type'], |
||
877 | ]); |
||
878 | } |
||
879 | |||
880 | /** |
||
881 | * Gets OS images. |
||
882 | * |
||
883 | * @param Server $model |
||
884 | * @throws NotFoundHttpException |
||
885 | * @return array |
||
886 | */ |
||
887 | protected function getOsimages(Server $model = null) |
||
888 | { |
||
889 | if ($model !== null) { |
||
890 | $type = $model->type; |
||
891 | } else { |
||
892 | $type = null; |
||
893 | } |
||
894 | |||
895 | $models = ServerHelper::getOsimages($type); |
||
896 | |||
897 | if ($models === null) { |
||
898 | throw new NotFoundHttpException('The requested page does not exist.'); |
||
899 | } |
||
900 | |||
901 | return $models; |
||
902 | } |
||
903 | |||
904 | protected function getOsimagesLiveCd() |
||
905 | { |
||
906 | $models = Yii::$app->cache->getOrSet([__METHOD__], function () { |
||
907 | return Osimage::findAll(['livecd' => true]); |
||
908 | }, 3600); |
||
909 | |||
910 | if ($models !== null) { |
||
911 | return $models; |
||
912 | } |
||
913 | |||
914 | throw new NotFoundHttpException('The requested page does not exist.'); |
||
915 | } |
||
916 | |||
917 | protected function getPanelTypes() |
||
918 | { |
||
919 | return ServerHelper::getPanels(); |
||
920 | } |
||
921 | |||
922 | public function actionIsOperable($id) |
||
923 | { |
||
924 | Yii::$app->response->format = Response::FORMAT_JSON; |
||
925 | |||
926 | $result = ['id' => $id, 'result' => false]; |
||
927 | |||
928 | if ($server = Server::find()->where(['id' => $id])->one()) { |
||
929 | $result['result'] = $server->isOperable(); |
||
930 | } |
||
931 | |||
932 | return $result; |
||
933 | } |
||
934 | |||
935 | protected function getFullFromRef($gtype) |
||
936 | { |
||
937 | $callingMethod = debug_backtrace()[1]['function']; |
||
938 | $result = Yii::$app->get('cache')->getOrSet([$callingMethod], function () use ($gtype) { |
||
939 | $result = ArrayHelper::map(Ref::find()->where([ |
||
940 | 'gtype' => $gtype, |
||
941 | 'select' => 'full', |
||
942 | ])->all(), 'id', function ($model) { |
||
943 | return Yii::t('hipanel:server:hub', $model->label); |
||
944 | }); |
||
945 | |||
946 | return $result; |
||
947 | }, 86400 * 24); // 24 days |
||
948 | |||
949 | return $result; |
||
950 | } |
||
951 | } |
||
952 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.