Skip to content

Commit 9c0ade2

Browse files
committed
Merge pull request #563 from rackspace/working
Merging working -> master in preparation for release
2 parents f79b16e + 16485f3 commit 9c0ade2

File tree

7 files changed

+125
-2
lines changed

7 files changed

+125
-2
lines changed

doc/getting-started-with-rackspace.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Okay, you're ready to spin up a server:
138138

139139
.. code-block:: php
140140
141-
use Guzzle\Http\Exception\BadResponseException;
141+
use Guzzle\Http\Exception\BadResponseException;
142142
143143
$server = $compute->server();
144144

lib/OpenCloud/Database/Service.php

+36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace OpenCloud\Database;
1919

20+
use Guzzle\Http\ClientInterface;
2021
use OpenCloud\Common\Service\NovaService;
2122
use OpenCloud\Database\Resource\Instance;
2223
use OpenCloud\Database\Resource\Configuration;
@@ -104,4 +105,39 @@ public function datastoreList($params = array())
104105

105106
return $this->resourceList('Datastore', $url);
106107
}
108+
109+
/**
110+
* {@inheritDoc}
111+
*/
112+
public function setClient(ClientInterface $client)
113+
{
114+
// The Rackspace Cloud Databases service only supports the
115+
// RC4 SSL cipher which is not supported by modern OpenSSL clients.
116+
// Until the service can support additional, more modern and secure
117+
// ciphers, this SDK has to ask curl to allow using the weaker
118+
// cipher. For more information, see https://github.com/rackspace/php-opencloud/issues/560
119+
120+
$curlOptions = $client->getConfig()->get('curl.options');
121+
$curlOptions['CURLOPT_SSL_CIPHER_LIST'] = static::getSslCipherList();
122+
$client->getConfig()->set('curl.options', $curlOptions);
123+
124+
$logMessage = 'The SDK is using a custom cipher suite when connecting '
125+
. 'to the Rackspace Cloud Databases service. This suite contains '
126+
. 'a weak cipher (RC4) so please use at your own risk. See '
127+
. 'https://github.com/rackspace/php-opencloud/issues/560 for details.';
128+
$client->getLogger()->critical($logMessage);
129+
130+
$this->client = $client;
131+
}
132+
133+
/**
134+
* @see https://github.com/rackspace/php-opencloud/issues/560#issuecomment-81790778
135+
*/
136+
public static function getSslCipherList()
137+
{
138+
return 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:'
139+
. 'ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:ECDH+3DES:'
140+
. 'DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:'
141+
. 'ECDH+RC4:DH+RC4:RSA+RC4:!aNULL:!eNULL:!MD5';
142+
}
107143
}

tests/OpenCloud/Smoke/Unit/Networking.php

+24
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,30 @@ protected function testSecurityGroupOperations()
272272
$securityGroup = $this->getService()->getSecurityGroup($securityGroup->getId());
273273
$this->stepInfo('Security Group ID: ' . $securityGroup->getId());
274274
$this->stepInfo('Security Group Name: ' . $securityGroup->getName());
275+
276+
$network1 = $this->getService()->createNetwork(array(
277+
'name' => 'test_network_for_test_port_sg'
278+
));
279+
$this->cleanupNetworkIds[] = $network1->getId();
280+
281+
$subnet1 = $this->getService()->createSubnet(array(
282+
'cidr' => '192.165.66.0/25',
283+
'networkId' => $network1->getId(),
284+
'ipVersion' => 4,
285+
'name' => 'test_subnet_for_test_port_sg'
286+
));
287+
$this->cleanupSubnetIds[] = $subnet1->getId();
288+
289+
$port1 = $this->getService()->createPort(array(
290+
'networkId' => $network1->getId(),
291+
'name' => 'test_port_for_test_port_sg'
292+
));
293+
$this->cleanupPortIds[] = $port1->getId();
294+
295+
$this->step('Apply security group to port');
296+
$port1->update(array(
297+
'securityGroups' => array($securityGroup->getId())
298+
));
275299
}
276300

277301
protected function testSecurityGroupRuleOperations()

tests/OpenCloud/Tests/Database/DatabaseTestCase.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
namespace OpenCloud\Tests\Database;
1919

2020
use OpenCloud\Tests\OpenCloudTestCase;
21+
use OpenCloud\Tests\MockLogger;
2122

2223
class DatabaseTestCase extends OpenCloudTestCase
2324
{
@@ -28,7 +29,9 @@ class DatabaseTestCase extends OpenCloudTestCase
2829

2930
public function setupObjects()
3031
{
31-
$this->service = $this->getClient()->databaseService();
32+
$client = $this->getClient();
33+
$client->setLogger(new MockLogger());
34+
$this->service = $client->databaseService();
3235

3336
$this->addMockSubscriber($this->getTestFilePath('Instance'));
3437
$this->instance = $this->service->instance('foo');
@@ -37,4 +40,9 @@ public function setupObjects()
3740
$this->datastore = $this->service->datastore('10000000-0000-0000-0000-000000000001');
3841
$this->datastoreVersion = $this->datastore->version('b00000b0-00b0-0b00-00b0-000b000000bb');
3942
}
43+
44+
protected function assertCriticalMessageWasLogged()
45+
{
46+
$this->assertNotEmpty($this->getClient()->getLogger()->getCriticalLogMessage());
47+
}
4048
}

tests/OpenCloud/Tests/Database/ServiceTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
namespace OpenCloud\Tests\Database;
2929

30+
use OpenCloud\Database\Service;
31+
3032
class ServiceTest extends DatabaseTestCase
3133
{
3234
public function test__construct()
@@ -71,4 +73,12 @@ public function testDatastoreList()
7173
{
7274
$this->assertInstanceOf(self::COLLECTION_CLASS, $this->service->datastoreList());
7375
}
76+
77+
public function testClientUsesCustomCipherSuite()
78+
{
79+
$client = $this->service->getClient();
80+
$curlOptions = $client->getConfig('curl.options');
81+
$this->assertEquals(Service::getSslCipherList(), $curlOptions['CURLOPT_SSL_CIPHER_LIST']);
82+
$this->assertCriticalMessageWasLogged();
83+
}
7484
}

tests/OpenCloud/Tests/MockLogger.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Copyright 2012-2014 Rackspace US, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace OpenCloud\Tests;
19+
20+
use OpenCloud\Common\Log\Logger;
21+
22+
class MockLogger extends Logger
23+
{
24+
protected $criticalLogMessage;
25+
26+
public function critical($message, array $context = array())
27+
{
28+
++$this->criticalLogMessage;
29+
}
30+
31+
public function getCriticalLogMessage()
32+
{
33+
return $this->criticalLogMessage;
34+
}
35+
}

tests/OpenCloud/Tests/RackspaceTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace OpenCloud\Tests;
1919

20+
use OpenCloud\Tests\MockLogger;
21+
2022
class RackspaceTest extends OpenCloudTestCase
2123
{
2224
const CREDENTIALS = <<<EOT
@@ -30,10 +32,18 @@ public function test_Credentials()
3032

3133
public function test_Factory_Methods()
3234
{
35+
// Inject mock logger
36+
$oldLogger = $this->getClient()->getLogger();
37+
$this->getClient()->setLogger(new MockLogger());
38+
3339
$this->assertInstanceOf(
3440
'OpenCloud\Database\Service',
3541
$this->getClient()->databaseService('cloudDatabases', 'DFW')
3642
);
43+
44+
// Re-inject old logger
45+
$this->getClient()->setLogger($oldLogger);
46+
3747
$this->assertInstanceOf(
3848
'OpenCloud\LoadBalancer\Service',
3949
$this->getClient()->loadBalancerService('cloudLoadBalancers', 'DFW')

0 commit comments

Comments
 (0)