GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e77d32...a7a8a6 )
by Jamie
10s
created

Server::getVncConsole()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php declare(strict_types=1);
2
3
namespace OpenStack\Compute\v2\Models;
4
5
use OpenStack\Common\Resource\HasWaiterTrait;
6
use OpenStack\Common\Resource\Creatable;
7
use OpenStack\Common\Resource\Deletable;
8
use OpenStack\Common\Resource\Listable;
9
use OpenStack\Common\Resource\Retrievable;
10
use OpenStack\Common\Resource\Updateable;
11
use OpenStack\Common\Resource\OperatorResource;
12
use OpenStack\Common\Transport\Utils;
13
use OpenStack\BlockStorage\v2\Models\VolumeAttachment;
14
use OpenStack\Compute\v2\Enum;
15
use OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroup;
16
use Psr\Http\Message\ResponseInterface;
17
18
/**
19
 * @property \OpenStack\Compute\v2\Api $api
20
 */
21
class Server extends OperatorResource implements
22
    Creatable,
23
    Updateable,
24
    Deletable,
25
    Retrievable,
26
    Listable
27
{
28
    use HasWaiterTrait;
29
30
    /** @var string */
31
    public $id;
32
33
    /** @var string */
34
    public $ipv4;
35
36
    /** @var string */
37
    public $ipv6;
38
39
    /** @var array */
40
    public $addresses;
41
42
    /** @var \DateTimeImmutable */
43
    public $created;
44
45
    /** @var \DateTimeImmutable */
46
    public $updated;
47
48
    /** @var Flavor */
49
    public $flavor;
50
51
    /** @var string */
52
    public $hostId;
53
54
    /** @var Image */
55
    public $image;
56
57
    /** @var array */
58
    public $links;
59
60
    /** @var array */
61
    public $metadata;
62
63
    /** @var string */
64
    public $name;
65
66
    /** @var string */
67
    public $progress;
68
69
    /** @var string */
70
    public $status;
71
72
    /** @var string */
73
    public $tenantId;
74
75
    /** @var string */
76
    public $userId;
77
78
    /** @var string */
79
    public $adminPass;
80
81
    /** @var string */
82
    public $taskState;
83
84
    protected $resourceKey = 'server';
85
    protected $resourcesKey = 'servers';
86
    protected $markerKey = 'id';
87
88
    protected $aliases = [
89
        'block_device_mapping_v2' => 'blockDeviceMapping',
90
        'accessIPv4'              => 'ipv4',
91
        'accessIPv6'              => 'ipv6',
92
        'tenant_id'               => 'tenantId',
93
        'user_id'                 => 'userId',
94
        'security_groups'         => 'securityGroups',
95
        'OS-EXT-STS:task_state'   => 'taskState',
96
    ];
97
98
    /**
99
     * {@inheritDoc}
100
     *
101 2
     * @param array $userOptions {@see \OpenStack\Compute\v2\Api::postServer}
102
     */
103 2
    public function create(array $userOptions): Creatable
104 2
    {
105
        $response = $this->execute($this->api->postServer(), $userOptions);
106
        return $this->populateFromResponse($response);
107
    }
108
109
    /**
110 1
     * {@inheritDoc}
111
     */
112 1
    public function update()
113
    {
114 1
        $response = $this->execute($this->api->putServer(), $this->getAttrs(['id', 'name', 'ipv4', 'ipv6']));
115
        $this->populateFromResponse($response);
116
    }
117
118
    /**
119
     * {@inheritDoc}
120 1
     */
121
    public function delete()
122 1
    {
123 1
        $this->execute($this->api->deleteServer(), $this->getAttrs(['id']));
124
    }
125
126
    /**
127
     * {@inheritDoc}
128 1
     */
129
    public function retrieve()
130 1
    {
131
        $response = $this->execute($this->api->getServer(), $this->getAttrs(['id']));
132 1
        $this->populateFromResponse($response);
133
    }
134
135
    /**
136
     * Changes the root password for a server.
137
     *
138
     * @param string $newPassword The new root password
139
     */
140 1
    public function changePassword(string $newPassword)
141
    {
142 1
        $this->execute($this->api->changeServerPassword(), [
143 1
            'id'       => $this->id,
144
            'password' => $newPassword,
145 1
        ]);
146 1
    }
147
148
    /**
149
     * Reboots the server.
150
     *
151
     * @param string $type The type of reboot that will be performed. Either SOFT or HARD is supported.
152
     */
153 2
    public function reboot(string $type = Enum::REBOOT_SOFT)
154
    {
155 2
        if (!in_array($type, ['SOFT', 'HARD'])) {
156 1
            throw new \RuntimeException('Reboot type must either be SOFT or HARD');
157
        }
158
159 1
        $this->execute($this->api->rebootServer(), [
160 1
            'id'   => $this->id,
161 1
            'type' => $type,
162 1
        ]);
163 1
    }
164
165
    /**
166
     * Starts server
167
     */
168
    public function start()
169
    {
170 1
        $this->execute($this->api->startServer(), [
171
            'id' => $this->id,
172 1
            'os-start' => null
173 1
        ]);
174
    }
175 1
176 1
    /**
177
     * Stops server
178
     */
179
    public function stop()
180
    {
181
        $this->execute($this->api->stopServer(), [
182
            'id' => $this->id,
183
            'os-stop' => null
184 1
        ]);
185
    }
186 1
187 1
    /**
188 1
     * Rebuilds the server.
189 1
     *
190
     * @param array $options {@see \OpenStack\Compute\v2\Api::rebuildServer}
191 1
     */
192 1
    public function rebuild(array $options)
193
    {
194
        $options['id'] = $this->id;
195
        $response = $this->execute($this->api->rebuildServer(), $options);
196
197 1
        $this->populateFromResponse($response);
198
    }
199 1
200 1
    /**
201
     * Resizes the server to a new flavor. Once this operation is complete and server has transitioned
202
     * to an active state, you will either need to call {@see confirmResize()} or {@see revertResize()}.
203
     *
204
     * @param string $flavorId The UUID of the new flavor your server will be based on.
205 1
     */
206
    public function resize(string $flavorId)
207 1
    {
208 1
        $response = $this->execute($this->api->resizeServer(), [
209
            'id'       => $this->id,
210
            'flavorId' => $flavorId,
211
        ]);
212
213
        $this->populateFromResponse($response);
214
    }
215 1
216
    /**
217 1
     * Confirms a previous resize operation.
218 1
     */
219 1
    public function confirmResize()
220
    {
221
        $this->execute($this->api->confirmServerResize(), ['confirmResize' => null, 'id' => $this->id]);
222
    }
223
224
    /**
225
     * Reverts a previous resize operation.
226
     */
227
    public function revertResize()
228 2
    {
229
        $this->execute($this->api->revertServerResize(), ['revertResize' => null, 'id' => $this->id]);
230 2
    }
231
232 2
    /**
233 2
     * Gets a VNC console for a server.
234 2
     *
235
     * @param  string $type The type of VNC console: novnc|xvpvnc.
236
     *                      Defaults to novnc.
237
     *
238
     * @return array
239
     */
240
    public function getVncConsole($type = Enum::CONSOLE_NOVNC): array
241
    {
242 1
        $response = $this->execute($this->api->getVncConsole(), ['id' => $this->id, 'type' => $type]);
243
        return Utils::jsonDecode($response)['console'];
244 1
    }
245 1
246
    /**
247
     * Gets a RDP console for a server.
248
     *
249
     * @param  string $type The type of VNC console: rdp-html5 (default).
250
     *
251
     * @return array
252
     */
253
    public function getRDPConsole($type = Enum::CONSOLE_RDP_HTML5): array
254
    {
255
        $response = $this->execute($this->api->getRDPConsole(), ['id' => $this->id, 'type' => $type]);
256 1
        return Utils::jsonDecode($response)['console'];
257
    }
258 1
259 1
    /**
260
     * Gets a Spice console for a server.
261
     *
262
     * @param  string $type The type of VNC console: spice-html5.
263
     *
264
     * @return array
265
     */
266
    public function getSpiceConsole($type = Enum::CONSOLE_SPICE_HTML5): array
267
    {
268
        $response = $this->execute($this->api->getSpiceConsole(), ['id' => $this->id, 'type' => $type]);
269
        return Utils::jsonDecode($response)['console'];
270
    }
271 1
272
    /**
273 1
     * Gets a serial console for a server.
274 1
     *
275
     * @param  string $type The type of VNC console: serial.
276
     *
277
     * @return array
278
     */
279
    public function getSerialConsole($type = Enum::CONSOLE_SERIAL): array
280
    {
281
        $response = $this->execute($this->api->getSerialConsole(), ['id' => $this->id, 'type' => $type]);
282
        return Utils::jsonDecode($response)['console'];
283
    }
284 1
285
    /**
286 1
     * Creates an image for the current server.
287 1
     *
288
     * @param array $options {@see \OpenStack\Compute\v2\Api::createServerImage}
289
     */
290
    public function createImage(array $options)
291
    {
292
        $options['id'] = $this->id;
293
        $this->execute($this->api->createServerImage(), $options);
294
    }
295 1
296
    /**
297 1
     * Iterates over all the IP addresses for this server.
298 1
     *
299
     * @param array $options {@see \OpenStack\Compute\v2\Api::getAddressesByNetwork}
300
     *
301
     * @return array An array containing to two keys: "public" and "private"
302
     */
303
    public function listAddresses(array $options = []): array
304
    {
305
        $options['id'] = $this->id;
306
307
        $data = (isset($options['networkLabel'])) ? $this->api->getAddressesByNetwork() : $this->api->getAddresses();
308
        $response = $this->execute($data, $options);
309
        return Utils::jsonDecode($response)['addresses'];
310
    }
311
312
    /**
313
     * Retrieves metadata from the API.
314
     *
315
     * @return array
316
     */
317
    public function getMetadata(): array
318
    {
319
        $response = $this->execute($this->api->getServerMetadata(), ['id' => $this->id]);
320
        return $this->parseMetadata($response);
321
    }
322
323
    /**
324
     * Resets all the metadata for this server with the values provided. All existing metadata keys
325
     * will either be replaced or removed.
326
     *
327
     * @param array $metadata {@see \OpenStack\Compute\v2\Api::putServerMetadata}
328
     */
329
    public function resetMetadata(array $metadata)
330
    {
331
        $response = $this->execute($this->api->putServerMetadata(), ['id' => $this->id, 'metadata' => $metadata]);
332
        $this->metadata = $this->parseMetadata($response);
333
    }
334
335
    /**
336
     * Merges the existing metadata for the server with the values provided. Any existing keys
337
     * referenced in the user options will be replaced with the user's new values. All other
338
     * existing keys will remain unaffected.
339
     *
340
     * @param array $metadata {@see \OpenStack\Compute\v2\Api::postServerMetadata}
341
     *
342
     * @return array
343
     */
344
    public function mergeMetadata(array $metadata)
345
    {
346
        $response = $this->execute($this->api->postServerMetadata(), ['id' => $this->id, 'metadata' => $metadata]);
347
        $this->metadata = $this->parseMetadata($response);
348
    }
349
350
    /**
351
     * Retrieve the value for a specific metadata key.
352
     *
353
     * @param string $key {@see \OpenStack\Compute\v2\Api::getServerMetadataKey}
354
     *
355
     * @return mixed
356
     */
357 View Code Duplication
    public function getMetadataItem(string $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
358
    {
359
        $response = $this->execute($this->api->getServerMetadataKey(), ['id' => $this->id, 'key' => $key]);
360
        $value = $this->parseMetadata($response)[$key];
361
        $this->metadata[$key] = $value;
362
        return $value;
363
    }
364
365
    /**
366
     * Remove a specific metadata key.
367
     *
368
     * @param string $key {@see \OpenStack\Compute\v2\Api::deleteServerMetadataKey}
369
     */
370 View Code Duplication
    public function deleteMetadataItem(string $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
371
    {
372
        if (isset($this->metadata[$key])) {
373
            unset($this->metadata[$key]);
374
        }
375
376
        $this->execute($this->api->deleteServerMetadataKey(), ['id' => $this->id, 'key' => $key]);
377
    }
378
379
380
    /**
381
     * Add security group to a server (addSecurityGroup action)
382
     *
383
     * @param array $options {@see \OpenStack\Compute\v2\Api::postSecurityGroup}
384
     *
385
     * @return SecurityGroup
386
     */
387
    public function addSecurityGroup(array $options) : SecurityGroup
388
    {
389
        $options['id'] = $this->id;
390
391
        $response = $this->execute($this->api->postSecurityGroup(), $options);
392
393
        return $this->model(SecurityGroup::class)->populateFromResponse($response);
394
    }
395
396
    /**
397
     * Add security group to a server (addSecurityGroup action)
398
     *
399
     * @param array $options {@see \OpenStack\Compute\v2\Api::deleteSecurityGroup}
400
     */
401
    public function removeSecurityGroup(array $options)
402
    {
403
        $options['id'] = $this->id;
404
        $this->execute($this->api->deleteSecurityGroup(), $options);
405
    }
406
407
    public function parseMetadata(ResponseInterface $response): array
408
    {
409
        return Utils::jsonDecode($response)['metadata'];
410
    }
411
412
    /**
413
     * Returns Generator for SecurityGroups
414
     *
415
     * @return \Generator
416
     */
417
    public function listSecurityGroups(): \Generator
418
    {
419
        return $this->model(SecurityGroup::class)->enumerate($this->api->getSecurityGroups(), ['id' => $this->id]);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface OpenStack\Common\Resource\ResourceInterface as the method enumerate() does only exist in the following implementations of said interface: OpenStack\BlockStorage\v2\Models\Snapshot, OpenStack\BlockStorage\v2\Models\Volume, OpenStack\BlockStorage\v2\Models\VolumeAttachment, OpenStack\BlockStorage\v2\Models\VolumeType, OpenStack\Common\Resource\OperatorResource, OpenStack\Compute\v2\Models\Flavor, OpenStack\Compute\v2\Models\HypervisorStatistic, OpenStack\Compute\v2\Models\Image, OpenStack\Compute\v2\Models\Keypair, OpenStack\Compute\v2\Models\Server, OpenStack\Identity\v2\Models\Catalog, OpenStack\Identity\v2\Models\Endpoint, OpenStack\Identity\v2\Models\Entry, OpenStack\Identity\v2\Models\Tenant, OpenStack\Identity\v2\Models\Token, OpenStack\Identity\v3\Models\Assignment, OpenStack\Identity\v3\Models\Catalog, OpenStack\Identity\v3\Models\Credential, OpenStack\Identity\v3\Models\Domain, OpenStack\Identity\v3\Models\Endpoint, OpenStack\Identity\v3\Models\Group, OpenStack\Identity\v3\Models\Policy, OpenStack\Identity\v3\Models\Project, OpenStack\Identity\v3\Models\Role, OpenStack\Identity\v3\Models\Service, OpenStack\Identity\v3\Models\Token, OpenStack\Identity\v3\Models\User, OpenStack\Images\v2\Models\Image, OpenStack\Images\v2\Models\Member, OpenStack\Networking\v2\...ayer3\Models\FloatingIp, OpenStack\Networking\v2\...ns\Layer3\Models\Router, OpenStack\Networking\v2\...ps\Models\SecurityGroup, OpenStack\Networking\v2\...odels\SecurityGroupRule, OpenStack\Networking\v2\Models\Network, OpenStack\Networking\v2\Models\Port, OpenStack\Networking\v2\Models\Subnet, OpenStack\ObjectStore\v1\Models\Account, OpenStack\ObjectStore\v1\Models\Container, OpenStack\ObjectStore\v1\Models\Object.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
420
    }
421
422
423
    /**
424
     * Returns Generator for VolumeAttachment
425
     *
426
     * @return \Generator
427
     */
428
    public function listVolumeAttachments(): \Generator
429
    {
430
        return $this->model(VolumeAttachment::class)->enumerate($this->api->getVolumeAttachments(), ['id' => $this->id]);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface OpenStack\Common\Resource\ResourceInterface as the method enumerate() does only exist in the following implementations of said interface: OpenStack\BlockStorage\v2\Models\Snapshot, OpenStack\BlockStorage\v2\Models\Volume, OpenStack\BlockStorage\v2\Models\VolumeAttachment, OpenStack\BlockStorage\v2\Models\VolumeType, OpenStack\Common\Resource\OperatorResource, OpenStack\Compute\v2\Models\Flavor, OpenStack\Compute\v2\Models\HypervisorStatistic, OpenStack\Compute\v2\Models\Image, OpenStack\Compute\v2\Models\Keypair, OpenStack\Compute\v2\Models\Server, OpenStack\Identity\v2\Models\Catalog, OpenStack\Identity\v2\Models\Endpoint, OpenStack\Identity\v2\Models\Entry, OpenStack\Identity\v2\Models\Tenant, OpenStack\Identity\v2\Models\Token, OpenStack\Identity\v3\Models\Assignment, OpenStack\Identity\v3\Models\Catalog, OpenStack\Identity\v3\Models\Credential, OpenStack\Identity\v3\Models\Domain, OpenStack\Identity\v3\Models\Endpoint, OpenStack\Identity\v3\Models\Group, OpenStack\Identity\v3\Models\Policy, OpenStack\Identity\v3\Models\Project, OpenStack\Identity\v3\Models\Role, OpenStack\Identity\v3\Models\Service, OpenStack\Identity\v3\Models\Token, OpenStack\Identity\v3\Models\User, OpenStack\Images\v2\Models\Image, OpenStack\Images\v2\Models\Member, OpenStack\Networking\v2\...ayer3\Models\FloatingIp, OpenStack\Networking\v2\...ns\Layer3\Models\Router, OpenStack\Networking\v2\...ps\Models\SecurityGroup, OpenStack\Networking\v2\...odels\SecurityGroupRule, OpenStack\Networking\v2\Models\Network, OpenStack\Networking\v2\Models\Port, OpenStack\Networking\v2\Models\Subnet, OpenStack\ObjectStore\v1\Models\Account, OpenStack\ObjectStore\v1\Models\Container, OpenStack\ObjectStore\v1\Models\Object.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
431
    }
432
433
    /**
434
     * Attach a volume and returns volume that was attached
435
     *
436
     * @param $volumeId
437
     *
438
     * @return VolumeAttachment
439
     */
440
    public function attachVolume(string $volumeId): VolumeAttachment
441
    {
442
        $response =  $this->execute($this->api->postVolumeAttachments(), ['id' => $this->id, 'volumeId' => $volumeId]);
443
444
        return $this->model(VolumeAttachment::class)->populateFromResponse($response);
445
    }
446
447
    /**
448
     * Detach a volume
449
     *
450
     * @param $attachmentId
451
     *
452
     * @return void
453
     */
454
    public function detachVolume(string $attachmentId)
455
    {
456
        $this->execute($this->api->deleteVolumeAttachments(), ['id' => $this->id, 'attachmentId' => $attachmentId]);
457
    }
458
}
459