Skip to content

Commit b956c88

Browse files
Merge pull request #146 from casperboone/interface-attachments
Server interface attachments
2 parents 8e9a232 + 851a6b1 commit b956c88

File tree

11 files changed

+279
-0
lines changed

11 files changed

+279
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
require 'vendor/autoload.php';
4+
5+
$openstack = new OpenStack\OpenStack([
6+
'authUrl' => '{authUrl}',
7+
'region' => '{region}',
8+
'user' => [
9+
'id' => '{userId}',
10+
'password' => '{password}'
11+
],
12+
'scope' => ['project' => ['id' => '{projectId}']]
13+
]);
14+
15+
$compute = $openstack->computeV2(['region' => '{region}']);
16+
17+
$server = $compute->getServer(['id' => '{serverId}']);
18+
19+
/**@var OpenStack\Networking\v2\Models\InterfaceAttachment $interface */
20+
$interface = $server->createInterfaceAttachment([
21+
'networkId' => '{networkId}',
22+
]);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
require 'vendor/autoload.php';
4+
5+
$openstack = new OpenStack\OpenStack([
6+
'authUrl' => '{authUrl}',
7+
'region' => '{region}',
8+
'user' => [
9+
'id' => '{userId}',
10+
'password' => '{password}'
11+
],
12+
'scope' => ['project' => ['id' => '{projectId}']]
13+
]);
14+
15+
$compute = $openstack->computeV2(['region' => '{region}']);
16+
17+
/**@var OpenStack\Compute\v2\Models\Server $server */
18+
$server = $compute->getServer(['id' => '{serverId}']);
19+
20+
$server->detachInterface('{portId}');
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
require 'vendor/autoload.php';
4+
5+
$openstack = new OpenStack\OpenStack([
6+
'authUrl' => '{authUrl}',
7+
'region' => '{region}',
8+
'user' => [
9+
'id' => '{userId}',
10+
'password' => '{password}'
11+
],
12+
'scope' => ['project' => ['id' => '{projectId}']]
13+
]);
14+
15+
$compute = $openstack->computeV2(['region' => '{region}']);
16+
17+
$server = $compute->getServer(['id' => '{serverId}']);
18+
19+
$server->getInterfaceAttachment('{portId}');

src/Compute/v2/Api.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,46 @@ public function getInterfaceAttachments(): array
471471
];
472472
}
473473

474+
public function getInterfaceAttachment(): array
475+
{
476+
return [
477+
'method' => 'GET',
478+
'path' => 'servers/{id}/os-interface/{portId}',
479+
'params' => [
480+
'id' => $this->params->urlId('server'),
481+
'portId' => $this->params->portId()
482+
]
483+
];
484+
}
485+
486+
public function postInterfaceAttachment(): array
487+
{
488+
return [
489+
'method' => 'POST',
490+
'path' => 'servers/{id}/os-interface',
491+
'jsonKey' => 'interfaceAttachment',
492+
'params' => [
493+
'id' => $this->params->urlId('server'),
494+
'portId' => $this->notRequired($this->params->portId()),
495+
'networkId' => $this->notRequired($this->params->networkId()),
496+
'fixedIpAddresses' => $this->notRequired($this->params->fixedIpAddresses()),
497+
'tag' => $this->notRequired($this->params->tag()),
498+
]
499+
];
500+
}
501+
502+
public function deleteInterfaceAttachment(): array
503+
{
504+
return [
505+
'method' => 'DELETE',
506+
'path' => 'servers/{id}/os-interface/{portId}',
507+
'params' => [
508+
'id' => $this->params->urlId('image'),
509+
'portId' => $this->params->portId()
510+
]
511+
];
512+
}
513+
474514
public function getServerMetadata(): array
475515
{
476516
return [

src/Compute/v2/Models/Server.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,51 @@ public function listInterfaceAttachments(array $options = []): \Generator
336336
return $this->model(InterfaceAttachment::class)->enumerate($this->api->getInterfaceAttachments(), ['id' => $this->id]);
337337
}
338338

339+
/**
340+
* Gets an interface attachment.
341+
*
342+
* @param string $portId The unique ID of the port.
343+
* @return InterfaceAttachment
344+
*/
345+
public function getInterfaceAttachment(string $portId): InterfaceAttachment
346+
{
347+
$response = $this->execute($this->api->getInterfaceAttachment(), [
348+
'id' => $this->id,
349+
'portId' => $portId
350+
]);
351+
352+
return $this->model(InterfaceAttachment::class)->populateFromResponse($response);
353+
}
354+
355+
/**
356+
* Creates an interface attachment.
357+
*
358+
* @param array $userOptions {@see \OpenStack\Compute\v2\Api::postInterfaceAttachment}
359+
* @return InterfaceAttachment
360+
*/
361+
public function createInterfaceAttachment(array $userOptions): InterfaceAttachment
362+
{
363+
if (!isset($userOptions['networkId']) && !isset($userOptions['portId'])) {
364+
throw new \RuntimeException('networkId or portId must be set.');
365+
}
366+
367+
$response = $this->execute($this->api->postInterfaceAttachment(), array_merge($userOptions, ['id' => $this->id]));
368+
return $this->model(InterfaceAttachment::class)->populateFromResponse($response);
369+
}
370+
371+
/**
372+
* Detaches an interface attachment.
373+
*
374+
* @param string $portId
375+
*/
376+
public function detachInterface(string $portId)
377+
{
378+
$this->execute($this->api->deleteInterfaceAttachment(), [
379+
'id' => $this->id,
380+
'portId' => $portId,
381+
]);
382+
}
383+
339384
/**
340385
* Retrieves metadata from the API.
341386
*

src/Compute/v2/Params.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,46 @@ public function flavorId(): array
130130
];
131131
}
132132

133+
public function networkId(): array
134+
{
135+
return [
136+
'type' => self::STRING_TYPE,
137+
'required' => true,
138+
'sentAs' => 'net_id',
139+
'description' => 'The unique ID of a network',
140+
];
141+
}
142+
143+
public function portId(): array
144+
{
145+
return [
146+
'type' => self::STRING_TYPE,
147+
'required' => true,
148+
'sentAs' => 'port_id',
149+
'description' => 'The unique ID of a port',
150+
];
151+
}
152+
153+
public function tag(): array
154+
{
155+
return [
156+
'type' => self::STRING_TYPE,
157+
];
158+
}
159+
160+
public function fixedIpAddresses(): array
161+
{
162+
return [
163+
'type' => self::ARRAY_TYPE,
164+
'sentAs' => 'fixed_ips',
165+
'description' => 'A list of ip addresses which this interface will be associated with',
166+
'items' => [
167+
'type' => self::OBJECT_TYPE,
168+
'properties' => ['ip_address' => ['type' => self::STRING_TYPE]]
169+
],
170+
];
171+
}
172+
133173
public function metadata(): array
134174
{
135175
return [

src/Networking/v2/Models/InterfaceAttachment.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php declare(strict_types=1);
22
namespace OpenStack\Networking\v2\Models;
33

4+
use OpenStack\Common\Resource\Creatable;
45
use OpenStack\Common\Resource\Listable;
56
use OpenStack\Common\Resource\OperatorResource;
67

tests/integration/Compute/v2/CoreTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ public function runTests()
188188

189189
// Console
190190
$this->getVncConsole();
191+
192+
// Interface attachments
193+
$this->createInterfaceAttachment();
191194
} finally {
192195
// Teardown
193196
$this->deleteServer();
@@ -688,4 +691,16 @@ private function getVncConsole()
688691

689692
$this->logStep('Get VNC console for server {serverId}', $replacements);
690693
}
694+
695+
private function createInterfaceAttachment()
696+
{
697+
$replacements = [
698+
'{serverId}' => $this->serverId,
699+
'{networkId}' => $this->network->id
700+
];
701+
702+
require_once $this->sampleFile($replacements, 'servers/create_interface_attachment.php');
703+
704+
$this->logStep('Create interface attachment for server {serverId}', $replacements);
705+
}
691706
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
HTTP/1.1 200 OK
2+
Content-Type: application/json
3+
4+
{
5+
"interfaceAttachment": {
6+
"port_state": "ACTIVE",
7+
"fixed_ips": [
8+
{
9+
"subnet_id": "f8a6e8f8-c2ec-497c-9f23-da9616de54ef",
10+
"ip_address": "192.168.1.3"
11+
}
12+
],
13+
"port_id": "ce531f90-199f-48c0-816c-13e38010b442",
14+
"net_id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6",
15+
"mac_addr": "fa:16:3e:4c:2c:30"
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
HTTP/1.1 200 OK
2+
Content-Type: application/json
3+
4+
{
5+
"interfaceAttachment": {
6+
"port_state": "ACTIVE",
7+
"fixed_ips": [
8+
{
9+
"subnet_id": "026f22e0-c827-4255-baea-1d4c29483fa4",
10+
"ip_address": "10.0.0.1"
11+
}
12+
],
13+
"port_id": "901e54d5-0a91-48bf-8210-aacaa3185196",
14+
"net_id": "338a30eb-3e65-4720-bfb8-105d3507a097",
15+
"mac_addr": "ha:12:e3:bb:e7:5f"
16+
}
17+
}

0 commit comments

Comments
 (0)