From b39d797f62ac294ab1bc32a59c35f34563995a06 Mon Sep 17 00:00:00 2001 From: Iain Collins Date: Wed, 16 Oct 2013 04:55:56 +0100 Subject: [PATCH 1/4] Added methods to grant and revoke user access to a database. Fixed listFlavours(). Add inline documentation. Added example CLI script. - Added grantUserAccess() and revokeUserAccess() methods. - Added autodoc parseable documentation for all methods. - Fixed listFlavours() (wasn't working, guessing the API changed). - Added command line script to show example usage for people as lazy as I am. - Refactored the param order for the internal method setEndpoints(). Also replaced all tabs with spaces while I was tidying up the formatting. I appreciate you may hate this and reject my pull request. Sorry about that. --- example.php | 46 +++ rackspace-clouddb.class.php | 673 +++++++++++++++++++----------------- 2 files changed, 398 insertions(+), 321 deletions(-) create mode 100644 example.php diff --git a/example.php b/example.php new file mode 100644 index 0000000..922a745 --- /dev/null +++ b/example.php @@ -0,0 +1,46 @@ +#!/usr/bin/php -q +listInstances(); + +// List all database users in an instance +//$responseObject = $rcdb->listDatabaseInstanceUsers(RACKSPACE_INSTANCE_ID); + +// List all flavours (hardware profiles) +//$responseObject = $rcdb->listFlavors(); + +// Create a new database +//$responseObject = $rcdb->createDatabase(RACKSPACE_INSTANCE_ID, $newDbName); + +// Create a new user +//$responseObject = $rcdb->createUser(RACKSPACE_INSTANCE_ID,$newDbName,'inkrato-app','mkfp28mt'); + +// Grant a user access to a database +//$responseObject = $rcdb->grantUserAccess(RACKSPACE_INSTANCE_ID, $newDbName, 'inkrato-app'); + +// Revoke a users access to a database +//$responseObject = $rcdb->revokeUserAccess(RACKSPACE_INSTANCE_ID, $newDbName, 'inkrato-app'); + +// NB: Not all operations (such as creating databases or users) return a response +echo '
'.print_r($responseObject,true).'
'; + +?> \ No newline at end of file diff --git a/rackspace-clouddb.class.php b/rackspace-clouddb.class.php index fae9a1f..8867b57 100644 --- a/rackspace-clouddb.class.php +++ b/rackspace-clouddb.class.php @@ -1,327 +1,358 @@ - * @link https://github.com/variableaction/php-rackspace-clouddb -*/ -########################################################################################################### - - class RackspaceCloudDB { - - private $account; - private $authToken; - - # ----------------------------------------------------------------------------------- - # __construct() - # stores account details, generates endpoints, and generates token - # ----------------------------------------------------------------------------------- - - public function __construct($username,$apiKey,$accountID,$datacenter='ORD',$authGeo='US',$automaticallyCreateToken=true) { - - // Set Account Details - $this->account->username = $username; - $this->account->apiKey = $apiKey; - $this->account->id = $accountID; - - // Set/generate API endpoints - $this->setEndpoints($authGeo,$datacenter); - - // Automatically create token (if $automaticallyCreateToken is true) - if ($automaticallyCreateToken) { $this->createAuthToken(); } - - } - - # --------------------------------------------------------------------------------- - # setEndpoints() - # defaults to US and Chicago Datacenter (ORD) - # --------------------------------------------------------------------------------- - - private function setEndpoints($authGeo,$datacenter) { - - // ---------------------------------------------------------------------- - // Set auth endpoint - // ---------------------------------------------------------------------- - - switch ($authGeo) { - - case 'UK': - $this->api->endpoints->auth = 'https://lon.identity.api.rackspacecloud.com/v1.1/auth'; - //$this->api->endpoints->auth = 'https://lon.identity.api.rackspacecloud.com/v2.0/'; - break; - - case 'US': - default: - $this->api->endpoints->auth = 'https://identity.api.rackspacecloud.com/v1.1/auth'; - //$this->api->endpoints->auth = 'https://identity.api.rackspacecloud.com/v2.0/'; - break; - - } - - // ---------------------------------------------------------------------- - // Set datacenter endpoint - // ---------------------------------------------------------------------- - - switch ($datacenter) { - - // London - case 'LON': - $this->api->endpoints->clouddb = 'https://lon.databases.api.rackspacecloud.com/v1.0/'; - break; - - // Dallas/Ft. Worth - case 'DFW': - $this->api->endpoints->clouddb = 'https://dfw.databases.api.rackspacecloud.com/v1.0/'; - break; - - // Chicago - case 'ORD': - default: - $this->api->endpoints->clouddb = 'https://ord.databases.api.rackspacecloud.com/v1.0/'; - break; - - } - - - // Append account number for endpoint - $this->api->endpoints->clouddb = "{$this->api->endpoints->clouddb}{$this->account->id}/"; - - } - - # ----------------------------------------------------------------------------------- - # basicCURL() - # ----------------------------------------------------------------------------------- - - private function basicCURL($url,$headers=array(),$data=null,$additionalOptions=null) { - - // setup handler - $ch = curl_init($url); - - // Set options - curl_setopt_array($ch,array( - CURLOPT_HTTPHEADER => $headers, - CURLOPT_RETURNTRANSFER => 1 - )); - - // if there is data, attach it to the request - if ($data) { - curl_setopt_array($ch,array( - CURLOPT_POST => 1, - CURLOPT_POSTFIELDS => $data, - )); - } - - // add additional options if sent - if ($additionalOptions) { - curl_setopt_array($ch,$additionalOptions); - } - - // execute request - $response = curl_exec($ch); - - // close connection - curl_close($ch); - - // return reponse - return $response; - - } - - # ----------------------------------------------------------------------------------- - # createAuthToken() - # ----------------------------------------------------------------------------------- - - public function createAuthToken() { - - $this->api->endpoints->auth; - - $requestObject->credentials->username = $this->account->username; - $requestObject->credentials->key = $this->account->apiKey; - - $jsonString = json_encode($requestObject); - - $response = $this->basicCURL( - $this->api->endpoints->auth, - array('Content-Type: application/json'), - $jsonString - ); - - $objectFromResponse = json_decode($response); - - // Set auth token - $this->authToken = $objectFromResponse->auth->token->id; - - } - - # ----------------------------------------------------------------------------------- - # listFlavors() - # ----------------------------------------------------------------------------------- - - public function listFlavors() { - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/flavors/detail', - array('X-Auth-Token: '.$this->authToken,'Accept: application/json','Accept: application/json') - ); - return json_decode($response); - } - - - # ----------------------------------------------------------------------------------- - # listInstances() - # ----------------------------------------------------------------------------------- - - public function listInstances() { - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json') - - ); - - //$objectFromResponse = json_decode($response); - - return json_decode($response); - - } - - # ----------------------------------------------------------------------------------- - # createInstance() - # ----------------------------------------------------------------------------------- - - public function createInstance($instanceName,$flavor='1',$volumeSize='2') { - - $requestObject->instance->flavorRef = $this->api->endpoints->clouddb.'/flavors/'.$flavor; - $requestObject->instance->name = $instanceName; - $requestObject->instance->volume = (object) array('size' => $volumeSize); - - $jsonString = json_encode($requestObject); - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), - $jsonString - ); - - return json_decode($response); - - } - - - # ----------------------------------------------------------------------------------- - # deleteInstance() -- tested; works - # ----------------------------------------------------------------------------------- - - public function deleteInstance($instanceID) { - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances/'.$instanceID, - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), - null, - array(CURLOPT_CUSTOMREQUEST => "DELETE") - ); - return json_decode($response); - } - - # ----------------------------------------------------------------------------------- - # createDatabase() - # ----------------------------------------------------------------------------------- - - public function createDatabase($instanceID,$dbName) { - - $requestObject->databases[] = (object) array("name" => $dbName); - - $jsonString = json_encode($requestObject); - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances/'.$instanceID.'/databases', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), - $jsonString - ); - - return json_decode($response); - - } - - - # ----------------------------------------------------------------------------------- - # listDatabaseInstanceDatabases() - # ----------------------------------------------------------------------------------- - - public function listDatabaseInstanceDatabases($instanceID) { - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances/'.$instanceID.'/databases', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json') - - ); - - return json_decode($response); - - - } - - # ----------------------------------------------------------------------------------- - # listDatabaseInstanceUsers() - # ----------------------------------------------------------------------------------- - - public function listDatabaseInstanceUsers($instanceID) { - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances/'.$instanceID.'/users', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json') - - ); - - return json_decode($response); - - - } - - # ----------------------------------------------------------------------------------- - # createUser() -- creates with access to a specific database - # looks like the API response to this is just a 202 header - # ----------------------------------------------------------------------------------- - - public function createUser($instanceID,$dbName,$username,$password) { - - $requestObject->users[] = (object) array( - "databases" => array((object) array("name" => $dbName)), - "name" => $username, - "password" => $password - ); - - - $jsonString = json_encode($requestObject); - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances/'.$instanceID.'/users', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), - $jsonString - ); - - return json_decode($response); - } - - # ----------------------------------------------------------------------------------- - # restartInstance() -- tested; works - # ----------------------------------------------------------------------------------- - - public function restartInstance($instanceID) { - - $response = $this->basicCURL( - $this->api->endpoints->clouddb.'/instances/'.$instanceID.'/action', - array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), - '{"restart": {}}' - ); - - return json_decode($response); - } - - - - - } - -?> + * @author Andy Fleming + * @author Iain Collins + * @version 1.1 + * @link https://github.com/variableaction/php-rackspace-clouddb + */ + +class RackspaceCloudDB { + + private $account; + private $authToken; + + /** + * @param string $username Your Rackspace username + * @param string $apiKey Your Rackspace API Key + * @param string $accountId Your Rackspace Account ID + * @param string $datacenter Your datacenter e.g.'ORD' (Chicago - Default), 'DFW' (Dallas/Ft. Worth), 'LON' (London) + * @param string $authGeo Your authentication region e.g. 'US' (Default), 'UK' + * @param bool $automaticallyCreateToken Default true + */ + public function __construct($username,$apiKey,$accountId,$datacenter='ORD',$authGeo='US',$automaticallyCreateToken=true) { + + // Set Account Details + $this->account->username = $username; + $this->account->apiKey = $apiKey; + $this->account->id = $accountId; + + // Set/generate API endpoints + $this->setEndpoints($datacenter, $authGeo); + + // Automatically create token (if $automaticallyCreateToken is true) + if ($automaticallyCreateToken) + $this->createAuthToken(); + } + + /** + * Set endpoints for requests (where they need to go) based on region and datacenter. + * + * @param string $datacenter Your datacenter e.g.'ORD' (Chicago - Default), 'LON' (London) + * @param string $authGeo Your authentication region e.g. 'US' (Default), 'UK' + */ + private function setEndpoints($datacenter,$authGeo) { + + // Set auth endpoint based on region + switch ($authGeo) { + case 'UK': + $this->api->endpoints->auth = 'https://lon.identity.api.rackspacecloud.com/v1.1/auth'; + //$this->api->endpoints->auth = 'https://lon.identity.api.rackspacecloud.com/v2.0/'; + break; + case 'US': + default: + $this->api->endpoints->auth = 'https://identity.api.rackspacecloud.com/v1.1/auth'; + //$this->api->endpoints->auth = 'https://identity.api.rackspacecloud.com/v2.0/'; + break; + } + + // Set clouddb endpoint based on specific datacenter + switch ($datacenter) { + + case 'LON': // London + $this->api->endpoints->clouddb = 'https://lon.databases.api.rackspacecloud.com/v1.0/'; + break; + case 'DFW': // Dallas/Ft. Worth + $this->api->endpoints->clouddb = 'https://dfw.databases.api.rackspacecloud.com/v1.0/'; + break; + case 'ORD': // Chicago + default: + $this->api->endpoints->clouddb = 'https://ord.databases.api.rackspacecloud.com/v1.0/'; + break; + } + + // Append account number for endpoint + $this->api->endpoints->clouddb = "{$this->api->endpoints->clouddb}{$this->account->id}/"; + + } + + /** + * Make requests using libcurl + */ + private function basicCURL($url,$headers=array(),$data=null,$additionalOptions=null) { + + // setup handler + $ch = curl_init($url); + + // Set options + curl_setopt_array($ch,array( + CURLOPT_HTTPHEADER => $headers, + CURLOPT_RETURNTRANSFER => 1 + )); + + // if there is data, attach it to the request + if ($data) { + curl_setopt_array($ch,array( + CURLOPT_POST => 1, + CURLOPT_POSTFIELDS => $data, + )); + } + + // add additional options if sent + if ($additionalOptions) { + curl_setopt_array($ch,$additionalOptions); + } + + // execute request + $response = curl_exec($ch); + + // close connection + curl_close($ch); + + // return reponse + return $response; + + } + + /** + * Create a new authtoken used for all subsequent requests + */ + public function createAuthToken() { + + $this->api->endpoints->auth; + + $requestObject->credentials->username = $this->account->username; + $requestObject->credentials->key = $this->account->apiKey; + + $jsonString = json_encode($requestObject); + + $response = $this->basicCURL( + $this->api->endpoints->auth, + array('Content-Type: application/json'), + $jsonString + ); + + $objectFromResponse = json_decode($response); + + // Set auth token + $this->authToken = $objectFromResponse->auth->token->id; + + } + + /** + * List all available flavours. + * + * From the Rackspace documentation: + * "A flavor is an available hardware configuration for a database instance. + * Each flavor has a unique combination of memory capacity and priority for CPU time." + */ + public function listFlavors() { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/flavors', + array('X-Auth-Token: '.$this->authToken,'Accept: application/json','Accept: application/json') + ); + return json_decode($response); + } + + /** + * List all avalible clouddb instances on an account + */ + public function listInstances() { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json') + ); + return json_decode($response); + } + + /** + * Create a new clouddb instance. + * + * The $sizeInGigabytes must be between 1 and 150. It can be increased later, but not decreased. + * + * @param string $instanceName A user firendly name for the new instance + * @param int $flavour An ID of the flavour (i.e. hardware config) for this instance (default '1') + * @param int $sizeInGigabytes The size of the volume in Gigabytes (Default 1 GB, can be increased later) + */ + public function createInstance($instanceName,$flavor='1',$sizeInGigabytes='1') { + + $requestObject->instance->flavorRef = $this->api->endpoints->clouddb.'/flavors/'.$flavor; + $requestObject->instance->name = $instanceName; + $requestObject->instance->volume = (object) array('size' => $sizeInGigabytes); + + $jsonString = json_encode($requestObject); + + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + $jsonString + ); + + return json_decode($response); + } + + /** + * Delete a database instance + * + * @param string $instanceId The ID of the instance to delete + */ + public function deleteInstance($instanceId) { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId, + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + null, + array(CURLOPT_CUSTOMREQUEST => "DELETE") + ); + return json_decode($response); + } + + /** + * Delete a database instance + * + * NB: Database names cannot contain periods (MySQL allows this but Rackspace do not). + * + * @param string $instanceId An instance ID + * @param string $database The name of the new database (can contain A-z, 0-9 - and _) + */ + public function createDatabase($instanceId,$database) { + + $requestObject->databases[] = (object) array("name" => $database); + + $jsonString = json_encode($requestObject); + + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/databases', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + $jsonString + ); + + return json_decode($response); + + } + + /** + * List all databases in a given instance. + * + * @param string $instanceId An instance ID + */ + public function listDatabaseInstanceDatabases($instanceId) { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/databases', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json') + + ); + return json_decode($response); + } + + /** + * List all users in a given instance. + * + * @param string $instanceId An instance ID + */ + public function listDatabaseInstanceUsers($instanceId) { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/users', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json') + + ); + return json_decode($response); + } + + /** + * Create a user in an instance, and grant them access to a specific database. + * + * Simply returns a status code of 200 on success. + * + * @param string $instanceId An instance ID + * @param string $database A database to grant them access to + * @param string $username A username for the new user + * @param string $password A password for the new user + */ + public function createUser($instanceId,$database,$username,$password) { + $requestObject->users[] = (object) array( + "databases" => array((object) array("name" => $database)), + "name" => $username, + "password" => $password + ); + + $jsonString = json_encode($requestObject); + + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/users', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + $jsonString + ); + + return json_decode($response); + } + + /** + * Grant a user access to a specific database + * + * Simply returns a status code of 200 on success. + * + * @param string $instanceId The ID of the instance the database is in + * @param string $database The database to grant access to + * @param string $username The user to be granted access + */ + public function grantUserAccess($instanceId,$database,$username) { + + $requestObject->databases[] = (object) array("name" => $database); + + $jsonString = json_encode($requestObject); + + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/users/'.$username.'/databases', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + $jsonString, + array(CURLOPT_CUSTOMREQUEST => "PUT") + ); + + return json_decode($response); + + } + + /** + * Revoke a users access to a specific database + * + * Simply returns a status code of 200 on success. + * + * @param string $instanceId The ID of the instance the database is in + * @param string $database The database to revoke access from + * @param string $username The user to revoke access from + */ + public function revokeUserAccess($instanceId,$database,$username) { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/users/'.$username.'/databases/'.$database, + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + null, + array(CURLOPT_CUSTOMREQUEST => "DELETE") + ); + return json_decode($response); + } + + /** + * Restart an instance. + * + * @param string $instanceId The ID of the instance to restart + */ + public function restartInstance($instanceId) { + $response = $this->basicCURL( + $this->api->endpoints->clouddb.'/instances/'.$instanceId.'/action', + array('X-Auth-Token: '.$this->authToken,'Content-Type: application/json','Accept: application/json'), + '{"restart": {}}' + ); + return json_decode($response); + } + +} +?> \ No newline at end of file From 1442bbe80a81c05add52fa4a4bc6908fb21b25e6 Mon Sep 17 00:00:00 2001 From: Iain Collins Date: Wed, 16 Oct 2013 05:17:29 +0100 Subject: [PATCH 2/4] Fixed variable typo in examples. --- example.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/example.php b/example.php index 922a745..aef495e 100644 --- a/example.php +++ b/example.php @@ -25,22 +25,23 @@ // List all database users in an instance //$responseObject = $rcdb->listDatabaseInstanceUsers(RACKSPACE_INSTANCE_ID); -// List all flavours (hardware profiles) +// List all flavors (hardware profiles) //$responseObject = $rcdb->listFlavors(); // Create a new database -//$responseObject = $rcdb->createDatabase(RACKSPACE_INSTANCE_ID, $newDbName); +//$responseObject = $rcdb->createDatabase(RACKSPACE_INSTANCE_ID, $database); // Create a new user -//$responseObject = $rcdb->createUser(RACKSPACE_INSTANCE_ID,$newDbName,'inkrato-app','mkfp28mt'); +//$responseObject = $rcdb->createUser(RACKSPACE_INSTANCE_ID,$database,'inkrato-app','mkfp28mt'); // Grant a user access to a database -//$responseObject = $rcdb->grantUserAccess(RACKSPACE_INSTANCE_ID, $newDbName, 'inkrato-app'); +//$responseObject = $rcdb->grantUserAccess(RACKSPACE_INSTANCE_ID, $database, 'inkrato-app'); // Revoke a users access to a database -//$responseObject = $rcdb->revokeUserAccess(RACKSPACE_INSTANCE_ID, $newDbName, 'inkrato-app'); +//$responseObject = $rcdb->revokeUserAccess(RACKSPACE_INSTANCE_ID, $database, 'inkrato-app'); -// NB: Not all operations (such as creating databases or users) return a response +// NB: Some operations (such as creating a database or a user) don't return a +// JSON response object unless there an error occurs. echo '
'.print_r($responseObject,true).'
'; ?> \ No newline at end of file From 4d543cc84d024f6b97f52f238530cda8da09a3b6 Mon Sep 17 00:00:00 2001 From: Iain Collins Date: Mon, 6 Jan 2014 15:53:35 +0000 Subject: [PATCH 3/4] Improved examples --- example.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/example.php b/example.php index aef495e..424f125 100644 --- a/example.php +++ b/example.php @@ -28,20 +28,20 @@ // List all flavors (hardware profiles) //$responseObject = $rcdb->listFlavors(); -// Create a new database +// Create a new database (with the name defined in $database) //$responseObject = $rcdb->createDatabase(RACKSPACE_INSTANCE_ID, $database); -// Create a new user -//$responseObject = $rcdb->createUser(RACKSPACE_INSTANCE_ID,$database,'inkrato-app','mkfp28mt'); +// Create a new user ('john.smith' with the password 'p4ssw0rd') +//$responseObject = $rcdb->createUser(RACKSPACE_INSTANCE_ID,$database,'john.smith','p4assw0rd'); -// Grant a user access to a database -//$responseObject = $rcdb->grantUserAccess(RACKSPACE_INSTANCE_ID, $database, 'inkrato-app'); +// Grant a user ('john.smith') access to a database +//$responseObject = $rcdb->grantUserAccess(RACKSPACE_INSTANCE_ID, $database, 'john.smith'); // Revoke a users access to a database -//$responseObject = $rcdb->revokeUserAccess(RACKSPACE_INSTANCE_ID, $database, 'inkrato-app'); +//$responseObject = $rcdb->revokeUserAccess(RACKSPACE_INSTANCE_ID, $database, 'john.smith'); // NB: Some operations (such as creating a database or a user) don't return a // JSON response object unless there an error occurs. echo '
'.print_r($responseObject,true).'
'; -?> \ No newline at end of file +?> From 01da8916bbcdc9c5f9d096a442006d1cd3591ece Mon Sep 17 00:00:00 2001 From: Iain Collins Date: Mon, 6 Jan 2014 15:55:47 +0000 Subject: [PATCH 4/4] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21731f5..981ea0a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#php-rackspace-clouddb - *work-in-progress* +#php-rackspace-clouddb PHP Class for connecting applications to [Rackspace's Cloud Databases Service](http://www.rackspace.com/cloud/cloud_hosting_products/databases/) @@ -95,4 +95,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.