Passed
Push — master ( 96a2a3...a63f8b )
by Andrii
03:28
created

Server::canControlPower()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
ccs 0
cts 6
cp 0
rs 10
c 0
b 0
f 0
cc 4
nc 6
nop 0
crap 20
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\models;
12
13
use hipanel\base\Model;
14
use hipanel\base\ModelTrait;
15
use hipanel\models\Ref;
16
use hipanel\modules\finance\models\Sale;
17
use hipanel\modules\hosting\models\Ip;
0 ignored issues
show
Bug introduced by
The type hipanel\modules\hosting\models\Ip was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use hipanel\modules\server\helpers\ServerHelper;
19
use hipanel\modules\server\models\query\ServerQuery;
20
use hipanel\modules\server\models\traits\AssignSwitchTrait;
21
use hipanel\validators\EidValidator;
22
use hipanel\validators\RefValidator;
23
use Yii;
24
use yii\base\NotSupportedException;
25
26
/**
27
 * Class Server.
28
 *
29
 * @property int $id
30
 * @property string $name
31
 *
32
 * @property-read HardwareSale[] $hardwareSales
33
 */
34
class Server extends Model implements AssignSwitchInterface
35
{
36
    use ModelTrait, AssignSwitchTrait;
0 ignored issues
show
introduced by
The trait hipanel\modules\server\m...raits\AssignSwitchTrait requires some properties which are not provided by hipanel\modules\server\models\Server: $device_name, $typeWithNo, $bindings, $switch_name, $switch_id, $port, $type
Loading history...
37
38
    const STATE_OK = 'ok';
39
    const STATE_DISABLED = 'disabled';
40
    const STATE_BLOCKED = 'blocked';
41
    const STATE_DELETED = 'deleted';
42
43
    const VIRTUAL_DEVICES = ['avds', 'svds', 'ovds'];
44
45
    const SVDS_TYPES = ['avds', 'svds'];
46
47
    const DEFAULT_PANEL = 'rcp';
48
49 1
    public function rules()
50
    {
51
        return [
52 1
            [['id', 'tariff_id', 'client_id', 'seller_id', 'mails_num'], 'integer'],
53
            [['osimage'], EidValidator::class],
54
            [['panel'], RefValidator::class],
55
            [
56
                [
57
                    'name', 'dc',
58
                    'client', 'seller',
59
                    'os', 'panel', 'rcp',
60
                    'parent_tariff', 'tariff', 'tariff_note', 'discounts',
61
                    'request_state', 'request_state_label',
62
                    'autorenewal',
63
                    'type', 'type_label', 'state', 'state_label', 'statuses',
64
                    'block_reason_label',
65
                    'running_task',
66
                    'ip', 'ips_num', 'mac',
67
                    'acs_num', 'del_acs_num', 'wizzarded',
68
                    'vnc',
69
                    'note', 'label', 'hwsummary', 'order_no',
70
                ],
71
                'safe',
72
            ],
73
            [['show_del', 'show_nic', 'show_vds', 'show_jail'], 'boolean'],
74
            [['switches', 'rack', 'net', 'kvm', 'pdu', 'ipmi'], 'safe'],
75
            [['last_expires', 'expires', 'status_time'], 'date'],
76
            [['time'], 'date', 'format' => 'php:Y-m-d H:i:s'],
77
            [
78
                ['state'],
79
                'isOperable',
80
                'on' => [
81
                    'reinstall',
82
                    'reboot',
83
                    'reset',
84
                    'shutdown',
85
                    'power-off',
86
                    'power-on',
87
                    'boot-live',
88
                    'regen-root-password',
89
                    'reset-password',
90
                ],
91
            ],
92
            [
93
                ['id'],
94
                'required',
95
                'on' => [
96
                    'refuse', 'delete', 'enable-autorenewal',
97
                    'enable-vnc', 'set-note', 'set-label',
98
                    'enable-block', 'disable-block', 'clear-resources',
99
                    'flush-switch-graphs',
100
                ],
101
            ],
102
            [
103
                ['id'],
104
                'integer',
105
                'on' => [
106
                    'refuse', 'delete', 'enable-autorenewal',
107
                    'enable-vnc', 'set-note', 'set-label',
108
                    'enable-block', 'disable-block',
109
                ],
110
            ],
111
            [['id', 'osimage'], 'required', 'on' => ['reinstall']],
112
            [['id', 'osimage'], 'required', 'on' => ['boot-live']],
113
            [['type', 'comment'], 'required', 'on' => ['enable-block', 'disable-block']],
114
115
            [['tariff_id', 'sale_time'], 'required', 'on' => ['sale']],
116
            [['move_accounts'], 'safe', 'on' => ['sale']],
117
            [['id', 'type'], 'required', 'on' => ['set-type']],
118
        ];
119
    }
120
121
    /**
122
     * Determine good server states.
123
     *
124
     * @return array
125
     */
126
    public function goodStates()
127
    {
128
        return [static::STATE_OK, static::STATE_DISABLED];
129
    }
130
131
    /**
132
     * @return bool
133
     */
134
    public function isOperable()
135
    {
136
        if ($this->running_task || !$this->isStateGood()) {
0 ignored issues
show
Bug Best Practice introduced by
The property running_task does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
137
            return false;
138
        }
139
140
        return true;
141
    }
142
143
    public function canEnableVNC()
144
    {
145
        return $this->isVNCSupported() && $this->isStateGood();
146
    }
147
148
    public function isStateGood()
149
    {
150
        return in_array($this->state, $this->goodStates(), true);
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
151
    }
152
153
    /**
154
     * Checks whether server supports VNC.
155
     *
156
     * @return bool
157
     */
158
    public function isVNCSupported()
159
    {
160
        return in_array($this->type, static::SVDS_TYPES, true);
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...
161
    }
162
163
    /**
164
     * Checks whether server supports root password change.
165
     *
166
     * @return bool
167
     */
168
    public function isPwChangeSupported()
169
    {
170
        return $this->type === 'ovds';
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...
171
    }
172
173
    /**
174
     * Checks whether server supports LiveCD.
175
     *
176
     * @return bool
177
     */
178
    public function isLiveCDSupported()
179
    {
180
        return in_array($this->type, static::SVDS_TYPES, true);
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...
181
    }
182
183
    /**
184
     * Check whether server is virtual.
185
     *
186
     * @return bool
187
     */
188
    public function isVirtualDevice()
189
    {
190
        return in_array($this->type, static::VIRTUAL_DEVICES, true);
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...
191
    }
192
193
    /**
194
     * Check whether server is dedicated.
195
     *
196
     * @return bool
197
     */
198
    public function isDedicatedDevice()
199
    {
200
        return $this->type === 'dedicated';
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...
201
    }
202
203
    public function getIsBlocked()
204
    {
205
        return $this->state === static::STATE_BLOCKED;
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
206
    }
207
208
    /**
209
     * Checks whether server can be operated not.
210
     *
211
     * @throws NotSupportedException
212
     * @return bool
213
     * @see isOperable()
214
     */
215
    public function checkOperable()
216
    {
217
        if (!$this->isOperable()) {
218
            throw new NotSupportedException(Yii::t('hipanel:server', 'Server already has a running task. Can not start new.'));
219
        }
220
221
        return true;
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227
    public function scenarioActions()
228
    {
229
        return [
230
            'reinstall' => 'resetup',
231
            'reset-password' => 'regen-root-password',
232
        ];
233
    }
234
235
    /**
236
     * During 5 days after the last expiration client is able to refuse server with full refund.
237
     * Method checks, whether 5 days passed.
238
     * @return bool
239
     */
240
    public function canFullRefuse()
241
    {
242
        if (!is_numeric($this->last_expires)) {
0 ignored issues
show
Bug Best Practice introduced by
The property last_expires does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
243
            return null; // In case server is not sold
244
        }
245
246
        return (time() - Yii::$app->formatter->asTimestamp($this->last_expires)) / 3600 / 24 < 5;
247
    }
248
249
    /**
250
     * @return bool
251
     */
252
    public function canRrd(): bool
253
    {
254
        return isset($this->ip) && isset($this->wizzarded);
0 ignored issues
show
Bug Best Practice introduced by
The property ip does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property wizzarded does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
255
    }
256
257
    public function groupUsesForCharts()
258
    {
259
        return ServerHelper::groupUsesForChart($this->uses);
0 ignored issues
show
Bug Best Practice introduced by
The property uses does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
260
    }
261
262
    public function getUses()
263
    {
264
        return $this->hasMany(ServerUse::class, ['object_id' => 'id']);
265
    }
266
267
    public function getIps()
268
    {
269
        if (Yii::getAlias('@ip', false)) {
270
            return $this->hasMany(Ip::class, ['device_id' => 'id'])->joinWith('links');
271
        }
272
273
        return [];
274
    }
275
276
    public function getSwitches()
277
    {
278
        return $this->hasMany(Server::class, ['obj_id' => 'id']);
279
    }
280
281
    public function getConsumptions()
282
    {
283
        return $this->hasMany(Consumption::class, ['object_id' => 'id'])->indexBy('type');
284
    }
285
286
    public function getBindings()
287
    {
288
        return $this->hasMany(Binding::class, ['device_id' => 'id'])->indexBy(function ($binding) {
289
            return $binding->typeWithNo;
290
        });
291
    }
292
293
    public function getSales()
294
    {
295
        return $this->hasMany(Sale::class, ['id' => 'object_id']);
296
    }
297
298
    public function getMonitoringSettings()
299
    {
300
        return $this->hasOne(MonitoringSettings::class, ['id' => 'id']);
301
    }
302
303
    public function getHardwareSettings()
304
    {
305
        return $this->hasOne(HardwareSettings::class, ['id' => 'id']);
306
    }
307
308
    public function getHardwareSales()
309
    {
310
        return $this->hasMany(HardwareSale::class, ['id' => 'id']);
311
    }
312
313
    public function getSoftwareSettings()
314
    {
315
        return $this->hasOne(SoftwareSettings::class, ['id' => 'id']);
316
    }
317
318
    public function getMailSettings()
319
    {
320
        return $this->hasOne(MailSettings::class, ['id' => 'id']);
321
    }
322
323
    public function getBinding($type)
324
    {
325
        if (!isset($this->bindings[$type])) {
0 ignored issues
show
Bug Best Practice introduced by
The property bindings does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
326
            return null;
327
        }
328
329
        return $this->bindings[$type];
330
    }
331
332
    public function getPanel()
333
    {
334
        if ($this->state === self::STATE_DISABLED) {
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
335
            return null;
336
        }
337
338
        if ($this->panel || $this->isVirtualDevice()) {
0 ignored issues
show
Bug Best Practice introduced by
The property panel does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
339
            return $this->panel;
340
        }
341
342
        return self::DEFAULT_PANEL;
343
    }
344
345
    /**
346
     * {@inheritdoc}
347
     */
348
    public function attributeLabels()
349
    {
350
        return $this->mergeAttributeLabels([
351
            'remoteid' => Yii::t('hipanel:server', 'Remote ID'),
352
            'name' => Yii::t('hipanel:server', 'Name'),
353
            'dc' => Yii::t('hipanel:server', 'DC'),
354
            'net' => Yii::t('hipanel:server', 'Switch'),
355
            'kvm' => Yii::t('hipanel:server', 'KVM'),
356
            'pdu' => Yii::t('hipanel:server', 'APC'),
357
            'rack' => Yii::t('hipanel:server', 'Rack'),
358
            'ipmi' => Yii::t('hipanel:server', 'IPMI'),
359
            'status_time' => Yii::t('hipanel:server', 'Status update time'),
360
            'block_reason_label' => Yii::t('hipanel:server', 'Block reason label'),
361
            'request_state_label' => Yii::t('hipanel:server', 'Request state label'),
362
            'mac' => Yii::t('hipanel:server', 'MAC'),
363
            'ips' => Yii::t('hipanel:server', 'IPs'),
364
            'label' => Yii::t('hipanel:server', 'Internal note'),
365
            'os' => Yii::t('hipanel:server', 'OS'),
366
            'comment' => Yii::t('hipanel:server', 'Comment'),
367
            'hwsummary' => Yii::t('hipanel:server', 'Summary'),
368
            'sale_time' => Yii::t('hipanel:server', 'Sale time'),
369
            'expires' => Yii::t('hipanel:server', 'Expires'),
370
            'tariff_id' => Yii::t('hipanel:server', 'Tariff'),
371
            'order_no' => Yii::t('hipanel:server', 'Order'),
372
            'move_accounts' => Yii::t('hipanel:server', 'Move accounts to new client'),
373
            'server' => Yii::t('hipanel:server', 'Server name'),
374
            'mails_num' => Yii::t('hipanel:server', 'Number of mailboxes'),
375
        ]);
376
    }
377
378
    public function getTypeOptions(): array
379
    {
380
        return Ref::getList('type,device,server', 'hipanel:server');
381
    }
382
383
    public function getStateOptions(): array
384
    {
385
        return [
386
            self::STATE_DISABLED    => Yii::t('hipanel:server', 'Ok, panel OFF'),
387
            self::STATE_OK          => Yii::t('hipanel:server', 'Ok'),
388
            self::STATE_BLOCKED     => Yii::t('hipanel:server', 'Blocked'),
389
        ];
390
    }
391
392
    /**
393
     * {@inheritdoc}
394
     * @return ServerQuery
395
     */
396
    public static function find($options = [])
397
    {
398
        return new ServerQuery(get_called_class(), [
399
            'options' => $options,
400
        ]);
401
    }
402
403
    /**
404
     * @return bool
405
     */
406
    public function canControlPower(): bool
407
    {
408
        $powerManagementAllowed = Yii::$app->params['module.server.power.management.allowed'];
409
410
        $userCanControlPower = Yii::$app->user->can('support') &&
0 ignored issues
show
Bug introduced by
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

410
        $userCanControlPower = Yii::$app->user->/** @scrutinizer ignore-call */ can('support') &&

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...
411
            (Yii::$app->user->can('server.control-system') ||
412
            Yii::$app->user->can('server.control-power'));
413
414
        return $powerManagementAllowed || $userCanControlPower;
415
    }
416
}
417