Skip to content

Commit f9e5054

Browse files
committed
Add creation of interface attachments to servers
1 parent a4ffc20 commit f9e5054

File tree

8 files changed

+144
-0
lines changed

8 files changed

+144
-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+
]);

src/Compute/v2/Api.php

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

474+
public function postInterfaceAttachment(): array
475+
{
476+
return [
477+
'method' => 'POST',
478+
'path' => 'servers/{id}/os-interface',
479+
'jsonKey' => 'interfaceAttachment',
480+
'params' => [
481+
'id' => $this->params->urlId('server'),
482+
'portId' => $this->notRequired($this->params->portId()),
483+
'networkId' => $this->notRequired($this->params->networkId()),
484+
'fixedIpAddresses' => $this->notRequired($this->params->fixedIpAddresses()),
485+
'tag' => $this->notRequired($this->params->tag()),
486+
]
487+
];
488+
}
489+
474490
public function getServerMetadata(): array
475491
{
476492
return [

src/Compute/v2/Models/Server.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,22 @@ public function listInterfaceAttachments(array $options = []): \Generator
328328
return $this->model(InterfaceAttachment::class)->enumerate($this->api->getInterfaceAttachments(), ['id' => $this->id]);
329329
}
330330

331+
/**
332+
* Creates an interface attachment.
333+
*
334+
* @param array $userOptions {@see \OpenStack\Compute\v2\Api::postInterfaceAttachment}
335+
* @return InterfaceAttachment
336+
*/
337+
public function createInterfaceAttachment(array $userOptions): InterfaceAttachment
338+
{
339+
if (!isset($userOptions['networkId']) && !isset($userOptions['portId'])) {
340+
throw new \RuntimeException('networkId or portId must be set.');
341+
}
342+
343+
$response = $this->execute($this->api->postInterfaceAttachment(), array_merge($userOptions, ['id' => $this->id]));
344+
return $this->model(InterfaceAttachment::class)->populateFromResponse($response);
345+
}
346+
331347
/**
332348
* Retrieves metadata from the API.
333349
*

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": "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+
}

tests/unit/Compute/v2/Models/ServerTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,4 +443,21 @@ public function test_it_lists_interface_attachments()
443443

444444
$this->assertInstanceOf(InterfaceAttachment::class, $interfaceAttachments[0]);
445445
}
446+
447+
/** @test */
448+
public function test_it_creates_interface_attachments()
449+
{
450+
$networkId = 'fooooobarrrr';
451+
452+
$expectedJson = [
453+
'interfaceAttachment' => ['net_id' => $networkId]
454+
];
455+
456+
$this->setupMock('POST', 'servers/serverId/os-interface', $expectedJson, [], 'server-interface-attachments-post');
457+
458+
$interfaceAttachment = $this->server->createInterfaceAttachment(['networkId' => $networkId]);
459+
460+
$this->assertEquals('ACTIVE', $interfaceAttachment->portState);
461+
$this->assertEquals('10.0.0.1', $interfaceAttachment->fixedIps[0]['ip_address']);
462+
}
446463
}

0 commit comments

Comments
 (0)