Issues (213)

src/controllers/ServerController.php (10 issues)

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')) {
0 ignored issues
show
The method can() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
                    if ($this->indexPageUiOptionsModel->representation === 'billing' && Yii::$app->user->/** @scrutinizer ignore-call */ can('consumption.read')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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);
0 ignored issues
show
hipanel\modules\server\m...HardwareSettings::class of type string is incompatible with the type array|hiqdev\hiart\ActiveRecord expected by parameter $model of hiqdev\hiart\Collection::setModel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

314
                    $action->collection->setModel(/** @scrutinizer ignore-type */ HardwareSettings::class);
Loading history...
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);
0 ignored issues
show
hipanel\modules\server\m...SoftwareSettings::class of type string is incompatible with the type array|hiqdev\hiart\ActiveRecord expected by parameter $model of hiqdev\hiart\Collection::setModel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

344
                    $action->collection->setModel(/** @scrutinizer ignore-type */ SoftwareSettings::class);
Loading history...
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);
0 ignored issues
show
hipanel\modules\server\m...nitoringSettings::class of type string is incompatible with the type array|hiqdev\hiart\ActiveRecord expected by parameter $model of hiqdev\hiart\Collection::setModel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

373
                    $action->collection->setModel(/** @scrutinizer ignore-type */ MonitoringSettings::class);
Loading history...
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);
0 ignored issues
show
hipanel\modules\server\models\MailSettings::class of type string is incompatible with the type array|hiqdev\hiart\ActiveRecord expected by parameter $model of hiqdev\hiart\Collection::setModel(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

407
                    $action->collection->setModel(/** @scrutinizer ignore-type */ MailSettings::class);
Loading history...
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
Documentation Bug introduced by
It seems like Yii::app->request can also be of type yii\web\Request. However, the property $request is declared as type yii\console\Request. Maybe add an additional type check?

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 the id property of an instance of the Account 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.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
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()) {
0 ignored issues
show
Bug Best Practice introduced by
The property statuses does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
844
                $vnc = Yii::$app->cache->getOrSet([__METHOD__, $model->id, $model], function () use ($model) {
845
                    return ArrayHelper::merge([
846
                        'endTime' => strtotime($model->statuses['serverEnableVNC']) + 28800,
0 ignored issues
show
Bug Best Practice introduced by
The property statuses does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
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');
0 ignored issues
show
The method action() does not exist on yii\db\QueryInterface. It seems like you code against a sub-type of said class. However, the method does not exist in yii\db\ActiveQueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

867
        $dataProvider->query->/** @scrutinizer ignore-call */ 
868
                              action('get-uses');
Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
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