Skip to content

Commit 3451ef4

Browse files
authored
Merge pull request #96 from nexcess/os-host-readonly
[rtr] Hypervisor RO Access
2 parents 38325c0 + abfc7d8 commit 3451ef4

File tree

13 files changed

+434
-28
lines changed

13 files changed

+434
-28
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
.test/
33
coverage/
44
vendor/
5-
65
*.pyc
7-
86
phpunit.xml
97
coverage.xml
108
composer.lock
9+
env_test.sh
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
use OpenStack\Compute\v2\Models\Hypervisor;
4+
5+
require 'vendor/autoload.php';
6+
7+
$openstack = new OpenStack\OpenStack([
8+
'authUrl' => '{authUrl}',
9+
'region' => '{region}',
10+
'user' => [
11+
'id' => '{userId}',
12+
'password' => '{password}'
13+
],
14+
'scope' => ['project' => ['id' => '{projectId}']]
15+
]);
16+
17+
$compute = $openstack->computeV2(['region' => '{region}']);
18+
19+
$hypervisor = $compute->getHypervisor(['id' => '{hypervisorId}']);
20+
21+
// By default, this will return an empty Server object and NOT hit the API.
22+
// This is convenient for when you want to use the object for operations
23+
// that do not require an initial GET request. To retrieve the server's details,
24+
// run the following, which *will* call the API with a GET request:
25+
26+
$hypervisor->retrieve();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
use OpenStack\Compute\v2\Models\Hypervisor;
4+
5+
require 'vendor/autoload.php';
6+
7+
$openstack = new OpenStack\OpenStack([
8+
'authUrl' => '{authUrl}',
9+
'region' => '{region}',
10+
'user' => [
11+
'id' => '{userId}',
12+
'password' => '{password}'
13+
],
14+
'scope' => ['project' => ['id' => '{projectId}']]
15+
]);
16+
17+
$compute = $openstack->computeV2(['region' => '{region}']);
18+
19+
$hypervisors = $compute->listHypervisors();
20+
21+
foreach ($hypervisors as $hypervisor) {
22+
/**@var Hypervisor $hypervisor*/
23+
}

src/Compute/v2/Api.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,4 +641,31 @@ public function getHypervisorStatistics(): array
641641
]
642642
];
643643
}
644+
645+
public function getHypervisors(): array
646+
{
647+
return [
648+
'method' => 'GET',
649+
'path' => 'os-hypervisors',
650+
'jsonKey' => 'hypervisors',
651+
'params' => [
652+
],
653+
];
654+
}
655+
656+
public function getHypervisorsDetail(): array
657+
{
658+
$definition = $this->getHypervisors();
659+
$definition['path'] .= '/detail';
660+
return $definition;
661+
}
662+
663+
public function getHypervisor(): array
664+
{
665+
return [
666+
'method' => 'GET',
667+
'path' => 'os-hypervisors/{id}',
668+
'params' => ['id' => $this->params->urlId('hypervisor')]
669+
];
670+
}
644671
}

src/Compute/v2/Models/Hypervisor.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace OpenStack\Compute\v2\Models;
4+
5+
use OpenStack\Common\Resource\Listable;
6+
use OpenStack\Common\Resource\Retrievable;
7+
use OpenStack\Common\Resource\OperatorResource;
8+
9+
/**
10+
* @property \OpenStack\Compute\v2\Api $api
11+
*/
12+
class Hypervisor extends OperatorResource implements
13+
Retrievable,
14+
Listable
15+
{
16+
/** @var int */
17+
public $id;
18+
19+
/** @var string */
20+
public $status;
21+
22+
/** @var string */
23+
public $state;
24+
25+
/** @var string */
26+
public $host_ip;
27+
28+
/** @var int */
29+
public $free_disk_gb;
30+
31+
/** @var int */
32+
public $free_ram_mb;
33+
34+
/** @var string */
35+
public $hypervisor_hostname;
36+
37+
/** @var string */
38+
public $hypervisor_type;
39+
40+
/** @var string */
41+
public $hypervisor_version;
42+
43+
/** @var int */
44+
public $local_gb;
45+
46+
/** @var int */
47+
public $local_gb_used;
48+
49+
/** @var int */
50+
public $memory_mb;
51+
52+
/** @var int */
53+
public $memory_mb_used;
54+
55+
/** @var int */
56+
public $running_vms;
57+
58+
/** @var int */
59+
public $vcpus;
60+
61+
/** @var int */
62+
public $vcpus_used;
63+
64+
/** @var array */
65+
public $service;
66+
67+
protected $resourceKey = 'hypervisor';
68+
protected $resourcesKey = 'hypervisors';
69+
70+
/**
71+
* {@inheritDoc}
72+
*/
73+
public function retrieve()
74+
{
75+
$response = $this->execute($this->api->getHypervisor(), ['id' => (string) $this->id]);
76+
$this->populateFromResponse($response);
77+
}
78+
}

src/Compute/v2/Models/Server.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class Server extends OperatorResource implements
5151
/** @var string */
5252
public $hostId;
5353

54+
/** @var string */
55+
public $hypervisorHostname;
56+
5457
/** @var Image */
5558
public $image;
5659

@@ -86,13 +89,14 @@ class Server extends OperatorResource implements
8689
protected $markerKey = 'id';
8790

8891
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',
92+
'block_device_mapping_v2' => 'blockDeviceMapping',
93+
'accessIPv4' => 'ipv4',
94+
'accessIPv6' => 'ipv6',
95+
'tenant_id' => 'tenantId',
96+
'user_id' => 'userId',
97+
'security_groups' => 'securityGroups',
98+
'OS-EXT-STS:task_state' => 'taskState',
99+
'OS-EXT-SRV-ATTR:hypervisor_hostname' => 'hypervisorHostname',
96100
];
97101

98102
/**

src/Compute/v2/Service.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use OpenStack\Compute\v2\Models\Keypair;
1010
use OpenStack\Compute\v2\Models\Limit;
1111
use OpenStack\Compute\v2\Models\Server;
12+
use OpenStack\Compute\v2\Models\Hypervisor;
1213

1314
/**
1415
* Compute v2 service for OpenStack.
@@ -199,4 +200,33 @@ public function getHypervisorStatistics(): HypervisorStatistic
199200
$statistics->populateFromResponse($this->execute($this->api->getHypervisorStatistics(), []));
200201
return $statistics;
201202
}
203+
204+
/**
205+
* List hypervisors.
206+
*
207+
* @param bool $detailed Determines whether detailed information will be returned. If FALSE is specified, only
208+
* the ID, name and links attributes are returned, saving bandwidth.
209+
* @param array $options {@see \OpenStack\Compute\v2\Api::getHypervisors}
210+
* @param callable $mapFn A callable function that will be invoked on every iteration of the list.
211+
*
212+
* @return \Generator
213+
*/
214+
public function listHypervisors(bool $detailed = false, array $options = [], callable $mapFn = null): \Generator
215+
{
216+
$def = ($detailed === true) ? $this->api->getHypervisorsDetail() : $this->api->getHypervisors();
217+
return $this->model(Hypervisor::class)->enumerate($def, $options, $mapFn);
218+
}
219+
220+
/**
221+
* Shows details for a given hypervisor.
222+
*
223+
* @param array $options
224+
*
225+
* @return Hypervisor
226+
*/
227+
public function getHypervisor(array $options = []): Hypervisor
228+
{
229+
$hypervisor = $this->model(Hypervisor::class);
230+
return $hypervisor->populateFromArray($options);
231+
}
202232
}

tests/integration/Compute/v2/CoreTest.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use OpenStack\BlockStorage\v2\Models\Volume;
66
use OpenStack\Compute\v2\Models\Flavor;
77
use OpenStack\Compute\v2\Models\HypervisorStatistic;
8+
use OpenStack\Compute\v2\Models\Hypervisor;
89
use OpenStack\Compute\v2\Models\Image;
910
use OpenStack\Compute\v2\Models\Keypair;
1011
use OpenStack\Compute\v2\Models\Limit;
@@ -66,7 +67,7 @@ private function getNetworkService()
6667

6768
return $this->networkService;
6869
}
69-
70+
7071
private function getBlockStorageService()
7172
{
7273
if (!$this->blockStorageService) {
@@ -179,7 +180,11 @@ public function runTests()
179180

180181
// Limits
181182
$this->getLimits();
183+
184+
// Hypervisors
185+
$this->listHypervisors();
182186
$this->getHypervisorsStatistics();
187+
$this->getHypervisor();
183188

184189
// Console
185190
$this->getVncConsole();
@@ -549,6 +554,28 @@ private function deleteKeypair()
549554
$this->logStep('Deleted keypair name {name}', ['{name}' => $this->keypairName]);
550555
}
551556

557+
private function listHypervisors()
558+
{
559+
require_once $this->sampleFile([], 'hypervisors/list_hypervisors.php');
560+
561+
$this->logStep('Listed all available hypervisors');
562+
}
563+
564+
private function getHypervisor()
565+
{
566+
$replacements = [
567+
'{hypervisorId}' => '1',
568+
];
569+
570+
require_once $this->sampleFile($replacements, 'hypervisors/get_hypervisor.php');
571+
572+
/**@var Hypervisor $hypervisor */
573+
$this->assertInstanceOf(Hypervisor::class, $hypervisor);
574+
$this->assertEquals($replacements['{hypervisorId}'], $hypervisor->id);
575+
576+
$this->logStep('Retrieved details for hypervisor id {hypervisorId}', $replacements);
577+
}
578+
552579
private function getHypervisorsStatistics()
553580
{
554581
require_once $this->sampleFile([], 'hypervisors/get_hypervisors_statistics.php');
@@ -575,7 +602,7 @@ private function addSecurityGroupToServer()
575602
'{serverId}' => $this->serverId,
576603
'{secGroupName}' => 'default'
577604
];
578-
605+
579606
require_once $this->sampleFile($replacements, 'servers/add_security_group.php');
580607

581608
/**@var Server $server*/

tests/unit/Compute/v2/Fixtures/hypervisor-get.resp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,30 @@ HTTP/1.1 200 OK
22
Content-Type: application/json
33

44
{
5-
"hypervisor_statistics": {
6-
"count": 1,
7-
"vcpus_used": 0,
8-
"local_gb_used": 0,
9-
"memory_mb": 7980,
10-
"current_workload": 0,
11-
"vcpus": 8,
12-
"running_vms": 0,
13-
"free_disk_gb": 157,
14-
"disk_available_least": 140,
15-
"local_gb": 157,
16-
"free_ram_mb": 7468,
17-
"memory_mb_used": 512
18-
}
19-
}
5+
"hypervisor":{
6+
"status":"enabled",
7+
"service":{
8+
"host":"localhost.localdomain",
9+
"disabled_reason":null,
10+
"id":8
11+
},
12+
"vcpus_used":10,
13+
"hypervisor_type":"QEMU",
14+
"local_gb_used":120,
15+
"vcpus":56,
16+
"hypervisor_hostname":"localhost.localdomain",
17+
"memory_mb_used":20992,
18+
"memory_mb":97909,
19+
"current_workload":0,
20+
"state":"up",
21+
"host_ip":"1.2.3.4",
22+
"cpu_info":"{\"vendor\": \"Intel\", \"model\": \"Haswell-noTSX\", \"arch\": \"x86_64\", \"features\": [\"pge\", \"avx\", \"xsaveopt\", \"clflush\", \"sep\", \"syscall\", \"tsc_adjust\", \"vme\", \"dtes64\", \"invpcid\", \"msr\", \"sse\", \"xsave\", \"vmx\", \"erms\", \"xtpr\", \"cmov\", \"smep\", \"pcid\", \"est\", \"pat\", \"arat\", \"smx\", \"pbe\", \"lm\", \"tsc\", \"nx\", \"fxsr\", \"tm\", \"sse4.1\", \"pae\", \"sse4.2\", \"pclmuldq\", \"acpi\", \"fma\", \"tsc-deadline\", \"mmx\", \"osxsave\", \"cx8\", \"mce\", \"de\", \"tm2\", \"ht\", \"dca\", \"pni\", \"abm\", \"popcnt\", \"mca\", \"pdpe1gb\", \"apic\", \"fsgsbase\", \"f16c\", \"pse\", \"ds\", \"invtsc\", \"lahf_lm\", \"aes\", \"avx2\", \"sse2\", \"ss\", \"ds_cpl\", \"bmi1\", \"bmi2\", \"ssse3\", \"rdtscp\", \"fpu\", \"cx16\", \"pse36\", \"mtrr\", \"movbe\", \"pdcm\", \"cmt\", \"rdrand\", \"x2apic\"], \"topology\": {\"cores\": 14, \"cells\": 2, \"threads\": 2, \"sockets\": 1}}",
23+
"running_vms":4,
24+
"free_disk_gb":146,
25+
"hypervisor_version":2006000,
26+
"disk_available_least":2,
27+
"local_gb":266,
28+
"free_ram_mb":76917,
29+
"id":1
30+
}
31+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
HTTP/1.1 200 OK
2+
Content-Type: application/json
3+
4+
{
5+
"hypervisor_statistics": {
6+
"count": 1,
7+
"vcpus_used": 0,
8+
"local_gb_used": 0,
9+
"memory_mb": 7980,
10+
"current_workload": 0,
11+
"vcpus": 8,
12+
"running_vms": 0,
13+
"free_disk_gb": 157,
14+
"disk_available_least": 140,
15+
"local_gb": 157,
16+
"free_ram_mb": 7468,
17+
"memory_mb_used": 512
18+
}
19+
}

0 commit comments

Comments
 (0)