Issues (213)

src/controllers/ServerController.php (5 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;
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