diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 000000000..69fa449dd --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..b7805cd67 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/php-opencloud.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/php-opencloud.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/php-opencloud" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/php-opencloud" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/caching-creds.rst b/doc/caching-creds.rst new file mode 100644 index 000000000..4eb5be5c8 --- /dev/null +++ b/doc/caching-creds.rst @@ -0,0 +1,44 @@ +Caching credentials +=================== + +You can speed up your API operations by caching your credentials in a +(semi-)permanent location, such as your DB or local filesystem. This +enable subsequent requests to access a shared resource, instead of +repetitively having to re-authenticate on every thread of execution. + +Tokens are valid for 24 hours, so you can effectively re-use the same +cached value for that period. If you try to use a cached version that +has expired, an authentication request will be made. + +Filesystem example +------------------ + +In this example, credentials will be saved to a file in the local +filesystem. Be sure to exclude it from your VCS. + +.. code-block:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => 'foo', + 'apiKey' => 'bar' + )); + + $cacheFile = __DIR__ . '/.opencloud_token'; + + // If the cache file exists, try importing it into the client + if (file_exists($cacheFile)) { + $data = unserialize(file_get_contents($cacheFile)); + $client->importCredentials($data); + } + + $token = $client->getTokenObject(); + + // If no token exists, or the current token is expired, re-authenticate and save the new token to disk + if (!$token || ($token && $token->hasExpired())) { + $client->authenticate(); + file_put_contents($cacheFile, serialize($client->exportCredentials())); + } + +In tests, the above code shaved about 1-2s off the execution time. diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 000000000..f49381d42 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# php-opencloud documentation build configuration file, created by +# sphinx-quickstart on Tue Mar 3 12:28:19 2015. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer + +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +lexers['php'] = PhpLexer(startinline=True, linenos=1) +lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1) +primary_domain = 'php' + +extensions = ['sphinxcontrib.phpdomain'] +templates_path = ['_templates'] +source_suffix = '.rst' +master_doc = 'index' +project = u'php-opencloud' +copyright = u'2015, Jamie Hannaford, Shaunak Kashyap' +version = '1.12' +release = '1.12.1' +exclude_patterns = ['_build'] +pygments_style = 'sphinx' +html_theme = 'default' + +if not on_rtd: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "_templates"] + +html_static_path = ['_static'] +html_use_index = True + +# Output file base name for HTML help builder. +htmlhelp_basename = 'php-openclouddoc' + +latex_documents = [ + ('index', 'php-opencloud.tex', u'php-opencloud Documentation', + u'Jamie Hannaford, Shaunak Kashyap', 'manual'), +] + +man_pages = [ + ('index', 'php-opencloud', u'php-opencloud Documentation', + [u'Jamie Hannaford, Shaunak Kashyap'], 1) +] + +texinfo_documents = [ + ('index', 'php-opencloud', u'php-opencloud Documentation', + u'Jamie Hannaford, Shaunak Kashyap', 'php-opencloud', 'One line description of project.', + 'Miscellaneous'), +] diff --git a/doc/debugging.rst b/doc/debugging.rst new file mode 100644 index 000000000..5d35d5bc1 --- /dev/null +++ b/doc/debugging.rst @@ -0,0 +1,103 @@ +Debugging +========= + +There are two important debugging strategies to use when encountering +problems with HTTP transactions. + +Strategy 1: Meaningful exception handling +----------------------------------------- + +If the API returns a ``4xx`` or ``5xx`` status code, it indicates that +there was an error with the sent request, meaning that the transaction +cannot be adequately completed. + +The Guzzle HTTP component, which forms the basis of our SDK's transport +layer, utilizes `numerous exception +classes `__ +to handle this error logic. + +The two most common exception classes are: + +- ``Guzzle\Http\Exception\ClientErrorResponseException``, which is + thrown when a ``4xx`` response occurs + +- ``Guzzle\Http\Exception\ServerErrorResponseException``, which is + thrown when a ``5xx`` response occurs + +Both of these classes extend the base ``BadResponseException`` class. + +This provides you with the granularity you need to debug and handle +exceptions. + +An example with Swift +~~~~~~~~~~~~~~~~~~~~~ + +If you're trying to retrieve a Swift resource, such as a Data Object, +and you're not completely certain that it exists, it makes sense to wrap +your call in a try/catch block: + +.. code-block:: php + + use Guzzle\Http\Exception\ClientErrorResponseException; + + try { + return $service->getObject('foo.jpg'); + } catch (ClientErrorResponseException $e) { + if ($e->getResponse()->getStatusCode() == 404) { + // Okay, the resource does not exist + return false; + } + } catch (\Exception $e) { + // Some other exception was thrown... + } + + +Both ``ClientErrorResponseException`` and +``ServerErrorResponseException`` have two methods that allow you to +access the HTTP transaction: + +.. code-block:: php + + // Find out the faulty request + $request = $e->getRequest(); + + // Display everything by casting as string + echo (string) $request; + + // Find out the HTTP response + $response = $e->getResponse(); + + // Output that too + echo (string) $response; + + +Strategy 2: Wire logging +------------------------ + +Guzzle provides a `Log +plugin `__ +that allows you to log everything over the wire, which is useful if you +don't know what's going on. + +Here's how you enable it: + +Install the plugin +~~~~~~~~~~~~~~~~~~ + +.. code-block:: bash + + composer require guzzle/guzzle + + +Add to your client +~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + use Guzzle\Plugin\Log\LogPlugin; + + $client->addSubscriber(LogPlugin::getDebugPlugin()); + + +The above will add a generic logging subscriber to your client, which +will output every HTTP transaction to `STDOUT`. diff --git a/doc/getting-started-with-openstack.rst b/doc/getting-started-with-openstack.rst new file mode 100644 index 000000000..da6c6ee24 --- /dev/null +++ b/doc/getting-started-with-openstack.rst @@ -0,0 +1,233 @@ +Getting Started with OpenStack +============================== + +Installing the SDK +------------------ + +You must install through Composer, because this library has a few +dependencies: + +.. code-block:: bash + + composer require rackspace/php-opencloud + +Once you have installed the library, you will need to load Composer's +autoloader (which registers all the required namespaces): + +.. code-block:: php + + require 'vendor/autoload.php'; + +And you're good to go! + + +Quick deep-dive: building some Nova instances +--------------------------------------------- + +In this example, you will write code that will create a Nova instance +running Ubuntu. + + +1. Setup the client and pass in your credentials +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To authenticate against Keystone: + +.. code-block:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('http://my-openstack.com:35357/v2.0/', array( + 'username' => 'foo', + 'password' => 'bar', + 'tenantName' => 'baz' + )); + +You will need to substitute in the public URL endpoint for your Keystone +service, as well as your ``username``, ``password`` and ``tenantName``. +You can also specify your ``tenantId`` instead of ``tenantName`` if you +prefer. + + +2. Pick what service you want to use +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this case, we want to use the Nova service: + +.. code-block:: php + + $compute = $client->computeService('nova', 'regionOne'); + + +The first argument is the **name** of the service as it appears in the +OpenStack service catalog. For OpenStack users, this must be retrieved +and entered in your code. If you are unsure how to retrieve the service +name, follow these steps: + +1. Setup the ``$client`` object, as above +2. Copy and run this code: + +.. code-block:: php + + $client->authenticate(); + print_r($client->getCatalog()->getItems()); + + +3. This will output all the items in your service catalog. Go through + the outputted list and find your service, making note of the "name" + field. This is the name you will need to enter as the first argument. + You will also be able to see the available regions. + +The second argument is the region. The third and last argument is the +type of URL; you may use either ``publicURL`` or ``internalURL``. + + +3. Select your server image +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instances are based on "images", which are effectively just the type of +operating system you want. Let's go through the list and find an Ubuntu +one: + +.. code-block:: php + + $images = $compute->imageList(); + + foreach ($images as $image) { + if (strpos($image->name, 'Ubuntu') !== false) { + $ubuntu = $image; + break; + } + } + +Alternatively, if you already know the image ID, you can do this much +easier: + +.. code-block:: php + + $ubuntu = $compute->image('868a0966-0553-42fe-b8b3-5cadc0e0b3c5'); + + +4. Select your flavor +--------------------- + +There are different server specs - some which offer 1GB RAM, others +which offer a much higher spec. The 'flavor' of an instance is its +hardware configuration. So if you want a 2GB instance but don't know the +ID, you have to traverse the list: + +.. code-block:: php + + $flavors = $compute->flavorList(); + + foreach ($flavors as $flavor) { + if (strpos($flavor->name, '2GB') !== false) { + $twoGbFlavor = $flavor; + break; + } + } + +Again, it's much easier if you know the ID: + +.. code-block:: php + + $twoGbFlavor = $compute->flavor('4'); + + +5. Thunderbirds are go! +----------------------- + +Okay, you're ready to spin up a server: + +.. code-block:: php + + use Guzzle\Http\Exception\BadResponseException; + + $server = $compute->server(); + + try { + $response = $server->create(array( + 'name' => 'My lovely server', + 'image' => $ubuntu, + 'flavor' => $twoGbFlavor + )); + } catch (BadResponseException $e) { + // No! Something failed. Let's find out: + printf("Request: %s\n\nResponse: %s", $e->getRequest(), $e->getResponse()); + } + +As you can see, you're creating a server called "My lovely server" - +this will take a few minutes for the build to complete. You can always +check the progress by logging into your Controller node and running: + +.. code-block:: bash + + nova list + +You can also execute a polling function immediately after the ``create`` +method that checks the build process: + +.. code-block:: php + + use OpenCloud\Compute\Constants\ServerState; + + $callback = function($server) { + if (!empty($server->error)) { + var_dump($server->error); + exit; + } else { + echo sprintf( + "Waiting on %s/%-12s %4s%%", + $server->name(), + $server->status(), + isset($server->progress) ? $server->progress : 0 + ); + } + }; + + $server->waitFor(ServerState::ACTIVE, 600, $callback); + +So, the server will be polled until it is in an ``ACTIVE`` state, with a +timeout of 600 seconds. When the poll happens, the callback function is +executed - which in this case just logs some output. + +More fun with Nova +------------------ + +Once you've booted up your instance, you can use other API operations to +monitor your Compute nodes. To list every node on record, you can +execute: + +.. code-block:: php + + $servers = $compute->serverList(); + + foreach ($servers as $server) { + // do something with each server... + echo $server->name, PHP_EOL; + } + +or, if you know a particular instance ID you can retrieve its details: + +.. code-block:: php + + $server = $compute->server('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx'); + +allowing you to update its properties: + +.. code-block:: php + + $server->update(array( + 'name' => 'New server name' + )); + +or delete it entirely: + +.. code-block:: php + + $server->delete(); + +Next steps +---------- + +Read our docs for the `Compute v2 `_ service. diff --git a/doc/getting-started-with-rackspace.rst b/doc/getting-started-with-rackspace.rst new file mode 100644 index 000000000..35317a3e6 --- /dev/null +++ b/doc/getting-started-with-rackspace.rst @@ -0,0 +1,185 @@ +Getting Started with Rackspace +============================== + +Installing the SDK +------------------ + +You must install through Composer, because this library has a few +dependencies: + +.. code-block:: bash + + composer require rackspace/php-opencloud + +Once you have installed the library, you will need to load Composer's +autoloader (which registers all the required namespaces): + +.. code-block:: php + + require 'vendor/autoload.php'; + +And you're good to go! + + +Quick deep-dive: building some Nova instances +--------------------------------------------- + +In this example, you will write code that will create a Cloud Servers instance +running Ubuntu. + + +1. Setup the client and pass in your credentials +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To authenticate against the Rackspace API and use its services: + +.. code-block:: php + + 'foo', + 'apiKey' => 'bar' + )); + +You can see in the first example that the constant +``Rackspace::US_IDENTITY_ENDPOINT`` is just a string representation of +Rackspace's identity endpoint +(``https://identity.api.rackspacecloud.com/v2.0/``). Another difference +is that Rackspace uses API key for authentication, whereas OpenStack +uses a generic password. + + +2. Pick what service you want to use +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this case, we want to use the Compute (Nova) service: + +.. code-block:: php + + $compute = $client->computeService(null, 'ORD'); + +The first argument is the **name** of the service as it appears in the +OpenStack service catalog. If in doubt, you can leave blank and it will +revert to the default name for the service. The second argument is the +region; you may use: + +- **DFW** (Dallas) +- **ORD** (Chicago) +- **IAD** (Virginia) +- **LON** (London) +- **HKG** (Hong Kong) +- **SYD** (Sydney) + +The third and last argument is the type of URL; you may use either +``publicURL`` or ``internalURL``. If you select ``internalUrl`` all API +traffic will use ServiceNet (internal IPs) and will receive a +performance boost. + +3. Select your server image +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Servers are based on "images", which are effectively just the type of +operating system you want. Let's go through the list and find an Ubuntu +one: + +.. code-block:: php + + $images = $compute->imageList(); + + foreach ($images as $image) { + if (strpos($image->name, 'Ubuntu') !== false) { + $ubuntu = $image; + break; + } + } + +Alternatively, if you already know the image ID, you can do this much +easier: + +.. code-block:: php + + $ubuntu = $compute->image('868a0966-0553-42fe-b8b3-5cadc0e0b3c5'); + + +4. Select your flavor +--------------------- + +There are different server specs - some which offer 1GB RAM, others +which offer a much higher spec. The 'flavor' of a server is its hardware +configuration. So if you want a 2GB instance but don't know the ID, you +have to traverse the list: + +.. code-block:: php + + $flavors = $compute->flavorList(); + + foreach ($flavors as $flavor) { + if (strpos($flavor->name, '2GB') !== false) { + $twoGbFlavor = $flavor; + break; + } + } + +Again, it's much easier if you know the ID: + +.. code-block:: php + + $twoGbFlavor = $compute->flavor('4'); + +5. Thunderbirds are go! +----------------------- + +Okay, you're ready to spin up a server: + +.. code-block:: php + +use Guzzle\Http\Exception\BadResponseException; + + $server = $compute->server(); + + try { + $response = $server->create(array( + 'name' => 'My lovely server', + 'image' => $ubuntu, + 'flavor' => $twoGbFlavor + )); + } catch (BadResponseException $e) { + // No! Something failed. Let's find out: + printf("Request: %s\n\nResponse: %s", $e->getRequest(), $e->getResponse()); + } + +You can also call a polling function that checks on the build process: + +.. code-block:: php + + use OpenCloud\Compute\Constants\ServerState; + + $callback = function($server) { + if (!empty($server->error)) { + var_dump($server->error); + exit; + } else { + echo sprintf( + "Waiting on %s/%-12s %4s%%", + $server->name(), + $server->status(), + isset($server->progress) ? $server->progress : 0 + ); + } + }; + + $server->waitFor(ServerState::ACTIVE, 600, $callback); + +So, the server will be polled until it is in an ``ACTIVE`` state, with a +timeout of 600 seconds. When the poll happens, the callback function is +executed - which in this case just logs some output. + +Next steps +---------- + +Read our docs for the `Compute v2 `_ service. diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 000000000..fc7c280c3 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,73 @@ +Welcome to php-opencloud! +========================= + +Installation +------------ + +You must install this library through Composer: + +.. code-block:: bash + + composer require rackspace/php-opencloud + + +If you do not have Composer installed, please consult the `official docs +`_. + +Once you have installed the library, you will need to load Composer's autoloader +(which registers all the required namespaces). To do this, place the following +line of PHP code at the top of your application's PHP files: + +.. code-block:: php + + require 'vendor/autoload.php'; + +This assumes your application's PHP files are located in the same folder as +``vendor/``. If your files are located elsewhere, please supply the path to +``vendor/autoload.php`` in the require statement above. + +Read the :doc:`getting-started-with-openstack` or +:doc:`getting-started-with-rackspace` to help you get started with basic +Compute operations. + +Services +-------- + +.. toctree:: + :glob: + :maxdepth: 1 + + services/**/index + +Usage tips +---------- + +.. toctree:: + :maxdepth: 1 + + debugging + caching-creds + iterators + regions + url-types + +Help and support +---------------- + +If you have specific problems or bugs with this SDK, please file an issue on +our official `Github `_. We also +have a `mailing list `_, +so feel free to join to keep up to date with all the latest changes and +announcements to the library. + +For general feedback and support requests, send an email to +sdk-support@rackspace.com. + +You can also find assistance via IRC on #rackspace at freenode.net. + +Contributing +------------ + +If you'd like to contribute to the project, or require help running the +unit/acceptance tests, please view the `contributing guidelines +`_. diff --git a/doc/iterators.rst b/doc/iterators.rst new file mode 100644 index 000000000..bef59e339 --- /dev/null +++ b/doc/iterators.rst @@ -0,0 +1,174 @@ +Iterators +========= + +Iterators allow you to traverse over collections of your resources in an +efficient and easy way. Currently there are two Iterators provided by +the SDK: + +- **ResourceIterator**. The standard iterator class that implements + SPL's standard + `Iterator `__, + `ArrayAccess `__ + and `Countable `__ + interfaces. In short, this allows you to traverse this object (using + ``foreach``), count its internal elements like an array (using + ``count`` or ``sizeof``), and access its internal elements like an + array (using ``$iterator[1]``). + +- **PaginatedIterator**. This is a child of ResourceIterator, and as + such inherits all of its functionality. The difference however is + that when it reaches the end of the current collection, it attempts + to construct a URL to access the API based on predictive paginated + collection templates. + +Common behaviour +---------------- + +.. code-block:: php + + $iterator = $computeService->flavorList(); + +There are two ways to traverse an iterator. The first is the longer, +more traditional way: + +.. code-block:: php + + while ($iterator->valid()) { + $flavor = $iterator->current(); + + // do stuff.. + echo $flavor->id; + + $iterator->next(); + } + +There is also a shorter and more intuitive version: + +.. code-block:: php + + foreach ($iterator as $flavor) { + // do stuff... + echo $flavor->id; + } + +Because the iterator implements PHP's native ``Iterator`` interface, it +can inherit all the native functionality of traversible data structures +with ``foreach``. + +Very important note +------------------- + +Until now, users have been expected to do this: + +.. code-block:: php + + while ($flavor = $iterator->next()) { + // ... + } + +which is **incorrect**. The single responsibility of ``next`` is to move +the internal pointer forward. It is the job of ``current`` to retrieve +the current element. + +For your convenience, these two Iterator classes are fully backward +compatible: they exhibit all the functionality you'd expect from a +correctly implemented iterator, but they also allow previous behaviour. + +Using paginated collections +--------------------------- + +For large collections, such as retrieving DataObjects from +CloudFiles/Swift, you need to use pagination. Each resource will have a +different limit per page; so once that page is traversed, there needs to +be another API call to retrieve to *next* page's resources. + +There are two key concepts: + +- **limit** is the amount of resources returned per page +- **marker** is the way you define a starting point. It is some form of + identifier that allows the collection to begin from a specific + resource + +Resource classes +~~~~~~~~~~~~~~~~ + +When the iterator returns a current element in the internal list, it +populates the relevant resource class with all the data returned to the +API. In most cases, a ``stdClass`` object will become an instance of +``OpenCloud\Common\PersistentObject``. + +In order for this instantiation to happen, the ``resourceClass`` option +must correspond to some method in the parent class that creates the +resource. For example, if we specify 'ScalingPolicy' as the +``resourceClass``, the parent object (in this case +``OpenCloud\Autoscale\Group``, needs to have some method will allows the +iterator to instantiate the child resource class. These are all valid: + +1. ``Group::scalingGroup($data);`` + +2. ``Group::getScalingGroup($data);`` + +3. ``Group::resource('ScalingGroup', $data);`` + +where ``$data`` is the standard object. This list runs in order of +precedence. + +Setting up a PaginatedIterator +------------------------------ + +.. code-block:: php + + use OpenCloud\Common\Collection\PaginatedIterator; + + $service = $client->computeService(); + + $flavors = PaginatedIterator::factory($service, array( + 'resourceClass' => 'Flavor', + 'baseUrl' => $service->getUrl('flavors') + 'limit.total' => 350, + 'limit.page' => 100, + 'key.collection' => 'flavors' + )); + + foreach ($flavors as $flavor) { + echo $flavor->getId(); + } + +As you can see, there are a lot of configuration parameters to pass in - +and getting it right can be quite fiddly, involving a lot of API +research. For this reason, using the convenience methods like +``flavorList`` is recommended because it hides the complexity. + +PaginatedIterator options +~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are certain configuration options that the paginated iterator +needs to work. These are: + ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| Name | Description | Type | Required | Default | ++=========================+===================================================================================================================================================================================================================================================+==============================+============+===============+ +| resourceClass | The resource class that is instantiated when the current element is retrieved. This is relative to the parent/service which called the iterator. | string | Yes | - | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| baseUrl | The base URL that is used for making new calls to the API for new pages | ``Guzzle\Http\Url`` | Yes | - | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| limit.total | The total amount of resources you want to traverse in your collection. The iterator will stop as this limit is reached, regardless if there are more items in the list | int | No | 10000 | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| limit.page | The amount of resources each page contains | int | No | 100 | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| key.links | Often, API responses will contain "links" that allow easy access to the next page of a resource collection. This option specifies what that JSON element is called (its key). For example, for Rackspace Compute images it is ``images_links``. | string | No | links | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| key.collection | The top-level key for the array of resources. For example, servers are returned with this data structure: ``{"servers": [...]}``. The **key.collection** value in this case would be ``servers``. | string | No | ``null`` | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| key.collectionElement | Rarely used. But it indicates the key name for each nested resource element. KeyPairs, for example, are listed like this: ``{"keypairs": [ {"keypair": {...}} ] }``. So in this case the collectionElement key would be ``keypair``. | string | No | ``null`` | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| key.marker | The value used as the marker. It needs to represent a valid property in the JSON resource objects. Often it is ``id`` or ``name``. | string | No | name | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| request.method | The HTTP method used when making API calls for new pages | string | No | GET | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| request.headers | The HTTP headers to send when making API calls for new pages | array | No | ``array()`` | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| request.body | The HTTP entity body to send when making API calls for new pages | ``Guzzle\Http\EntityBody`` | No | ``null`` | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ +| request.curlOptions | Additional cURL options to use when making API calls for new pages | array | No | ``array()`` | ++-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+------------+---------------+ diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 000000000..219d9213f --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,242 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\php-opencloud.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\php-opencloud.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/doc/regions.rst b/doc/regions.rst new file mode 100644 index 000000000..42c14595c --- /dev/null +++ b/doc/regions.rst @@ -0,0 +1,20 @@ +Rackspace regions +================= + +Below are the supported regions on the Rackspace network: + ++------+-----------+ +| code | location | ++======+===========+ +| IAD | Virginia | ++------+-----------+ +| ORD | Chicago | ++------+-----------+ +| DFW | Dallas | ++------+-----------+ +| LON | London | ++------+-----------+ +| SYD | Sydney | ++------+-----------+ +| HKG | Hong Kong | ++------+-----------+ diff --git a/doc/services/autoscale/group-config.rst b/doc/services/autoscale/group-config.rst new file mode 100644 index 000000000..5dcfb6ce4 --- /dev/null +++ b/doc/services/autoscale/group-config.rst @@ -0,0 +1,59 @@ +Group configurations +==================== + +Setup +----- + +In order to interact with the functionality of a group's configuration, +you must first retrieve the details of the group itself. To do this, you must +substitute `{groupId}` for your group's ID: + +.. code-block:: php + + $group = $service->group('{groupId}'); + + +Get group configuration +----------------------- + +.. code-block:: php + + /** @var */ + $groupConfig = $group->getGroupConfig(); + + +Edit group configuration +------------------------ + +.. code-block:: php + + $groupConfig->update(array( + 'name' => 'New name!' + )); + + +Get launch configuration +------------------------ + +.. code-block:: php + + /** @var */ + $launchConfig = $group->getLaunchConfig(); + + +Edit group/launch configuration +------------------------------- + +.. code-block:: php + + $launchConfig = $group->getLaunchConfig(); + + $server = $launchConfig->args->server; + $server->name = "BRAND NEW SERVER NAME"; + + $launchConfig->update(array + 'args' => array( + 'server' => $server, + 'loadBalancers' => $launchConfig->args->loadBalancers + ) + )); diff --git a/doc/services/autoscale/groups.rst b/doc/services/autoscale/groups.rst new file mode 100644 index 000000000..a6caf3f9d --- /dev/null +++ b/doc/services/autoscale/groups.rst @@ -0,0 +1,81 @@ +Groups +====== + +List all groups +--------------- + +.. code-block:: php + + $groups = $service->groupList(); + foreach ($group as $group) { + /** @var $group OpenCloud\Autoscale\Resources\Group */ + } + +Please consult the `iterator guide `__ for more information about +iterators. + + +Retrieve group by ID +-------------------- + +.. code-block:: php + + $group = $service->group('{groupId}'); + + +Create a new group +------------------ + +.. code-block:: php + + // Set the config object for this autoscale group; contains all of properties + // which determine its behaviour + $groupConfig = array( + 'name' => 'new_autoscale_group', + 'minEntities' => 5, + 'maxEntities' => 25, + 'cooldown' => 60, + ); + + // We need specify what is going to be launched. For now, we'll launch a new server + $launchConfig = array( + 'type' => 'launch_server', + 'args' => array( + 'server' => array( + 'flavorRef' => 3, + 'name' => 'webhead', + 'imageRef' => '0d589460-f177-4b0f-81c1-8ab8903ac7d8' + ), + 'loadBalancers' => array( + array('loadBalancerId' => 2200, 'port' => 8081), + ) + ) + ); + + // Do we want particular scaling policies? + $policy = array( + 'name' => 'scale up by 10', + 'change' => 10, + 'cooldown' => 5, + 'type' => 'webhook', + ); + + $group->create(array( + 'groupConfiguration' => $groupConfig, + 'launchConfiguration' => $launchConfig, + 'scalingPolicies' => array($policy), + )); + +Delete a group +-------------- + +.. code-block:: php + + $group->delete(); + +Get the current state of the scaling group +------------------------------------------ + +.. code-block:: php + + $group->getState(); diff --git a/doc/services/autoscale/index.rst b/doc/services/autoscale/index.rst new file mode 100644 index 000000000..1bfd20e68 --- /dev/null +++ b/doc/services/autoscale/index.rst @@ -0,0 +1,69 @@ +Auto Scale v2 +============= + +.. include:: ../common/rs-only.sample.rst + +Auto Scale service +~~~~~~~~~~~~~~~~~~ + +Now to instantiate the Auto Scale service: + +.. code-block:: php + + $service = $client->autoscaleService(); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + groups + group-config + policies + webhooks + + +Glossary +-------- + +.. glossary:: + + group + The scaling group is at the heart of an Auto Scale deployment. The scaling + group specifies the basic elements of the Auto Scale configuration. It + manages how many servers can participate in the scaling group. It also + specifies information related to load balancers if your configuration uses + a load balancer. + + group configuration + Outlines the basic elements of the Auto Scale configuration. The group + configuration manages how many servers can participate in the scaling group. + It sets a minimum and maximum limit for the number of entities that can be + used in the scaling process. It also specifies information related to load + balancers. + + launch configuration + Creates a blueprint for how new servers will be created. The launch + configuration specifies what type of server image will be started on + launch, what flavor the new server is, and which load balancer the new + server connects to. + + policy + Auto Scale uses policies to define the scaling activity that will take + place, as well as when and how that scaling activity will take place. + Scaling policies specify how to modify the scaling group and its behavior. + You can specify multiple policies to manage a scaling group. + + webhook + A webhook is a reachable endpoint that when visited will execute a scaling + policy for a particular scaling group. + +Further Links +------------- + + - `Getting Started Guide for the API `_ + - `API Developer Guide `_ + - `API release history `_ diff --git a/doc/services/autoscale/policies.rst b/doc/services/autoscale/policies.rst new file mode 100644 index 000000000..e103d328e --- /dev/null +++ b/doc/services/autoscale/policies.rst @@ -0,0 +1,81 @@ +Scaling Policies +================ + +Setup +----- + +In order to interact with the functionality of a group's scaling +policies, you must first retrieve the details of the group itself. To do this, +you must substitute `{groupId}` for your group's ID: + +.. code-block:: php + + $group = $service->group('{groupId}'); + + +Get all policies +---------------- + +.. code-block:: php + + $policies = $group->getScalingPolicies(); + + foreach ($policies as $policy) { + printf("Name: %s Type: %s\n", $policy->name, $policy->type); + } + + +Create new scaling policies +--------------------------- + +Creating policies is achieved through passing an array to the ``create`` +method. + +.. code-block:: php + + $policies = array( + array( + 'name' => 'NEW NAME', + 'change' => 1, + 'cooldown' => 150, + 'type' => 'webhook', + ) + ); + + $group->createScalingPolicies($policies); + + +Get an existing scaling policy +------------------------------ + +.. code-block:: php + + $policy = $group->getScalingPolicy('{policyId}'); + + +Update a scaling policy +----------------------- + +.. code-block:: php + + $policy = $group->getScalingPolicy('{policyId}'); + $policy->update(array( + 'name' => 'More relevant name' + )); + + +Delete a scaling policy +----------------------- + +.. code-block:: php + + $policy = $group->getScalingPolicy('{policyId}'); + $policy->delete(); + +Execute a scaling policy +------------------------ + +.. code-block:: php + + $policy = $group->getScalingPolicy('{policyId}'); + $policy->execute(); diff --git a/doc/services/autoscale/webhooks.rst b/doc/services/autoscale/webhooks.rst new file mode 100644 index 000000000..9133aa9ed --- /dev/null +++ b/doc/services/autoscale/webhooks.rst @@ -0,0 +1,62 @@ +Webhooks +======== + +Setup +----- + +In order to interact with webhooks, you must first retrieve the +details of the group and scaling policy you want to execute: + +.. code-block:: php + + $group = $service->group('{groupId}'); + $policy = $group->getScalingPolicy('{policyId}'); + +Get all webhooks +---------------- + +.. code-block:: php + + $webhooks = $policy->getWebookList(); + +Create a new webhook +-------------------- + +.. code-block:: php + + $policy->createWebhooks(array( + array( + 'name' => 'Alice', + 'metadata' => array( + 'firstKey' => 'foo', + 'secondKey' => 'bar' + ) + ) + )); + +Get webhook +----------- + +.. code-block:: php + + $webhook = $policy->getWebhook('{webhookId}'); + +Update webhook +-------------- + +.. code-block:: php + + // Update the metadata + $metadata = $webhook->metadata; + $metadata->thirdKey = 'blah'; + $webhook->update(array( + 'metadata' => $metadata + )); + + +Delete webhook +-------------- + +.. code-block: php + + $webhook->delete(); diff --git a/doc/services/common/clients.sample.rst b/doc/services/common/clients.sample.rst new file mode 100644 index 000000000..a952da730 --- /dev/null +++ b/doc/services/common/clients.sample.rst @@ -0,0 +1,22 @@ +Setup +----- + +Rackspace setup +~~~~~~~~~~~~~~~ + +.. include:: /services/common/rs-client.rst + + +OpenStack setup +~~~~~~~~~~~~~~~ + +If you're an OpenStack user, you will also need to prove a few other +configuration parameters: + +.. code-block:: php + + $client = new OpenCloud\OpenStack('{keystoneUrl}', array( + 'username' => '{username}', + 'password' => '{apiKey}', + 'tenantId' => '{tenantId}', + )); diff --git a/doc/services/common/rs-client.rst b/doc/services/common/rs-client.rst new file mode 100644 index 000000000..46f9a5291 --- /dev/null +++ b/doc/services/common/rs-client.rst @@ -0,0 +1,11 @@ +The first step is to pass in your credentials and set up a client. For +Rackspace users, you will need your username and API key: + +.. code-block:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', + )); diff --git a/doc/services/common/rs-only.sample.rst b/doc/services/common/rs-only.sample.rst new file mode 100644 index 000000000..9a1ccdf93 --- /dev/null +++ b/doc/services/common/rs-only.sample.rst @@ -0,0 +1,8 @@ +.. note:: + + This service is only available for Rackspace users. + +Setup +----- + +.. include:: /services/common/rs-client.rst diff --git a/doc/services/common/service-args.rst b/doc/services/common/service-args.rst new file mode 100644 index 000000000..c1cc754b8 --- /dev/null +++ b/doc/services/common/service-args.rst @@ -0,0 +1,11 @@ +* ``{catalogName}`` is the name of the service as it appears in the service + catalog. OpenStack users *must* set this value. For Rackspace users, a + default will be provided if you pass in ``null``. + +* ``{region}`` is the region the service will operate in. For Rackspace + users, you can select one of the following from the `supported regions page + `_. + +* ``{urlType}`` is the `type of URL `_ to use, depending on which + endpoints your catalog provides. If omitted, it will default to the public + network. diff --git a/doc/services/compute/flavors.rst b/doc/services/compute/flavors.rst new file mode 100644 index 000000000..eeb447d3c --- /dev/null +++ b/doc/services/compute/flavors.rst @@ -0,0 +1,60 @@ +Flavors +======= + +Get a flavor +------------ + +.. code-block:: php + + $flavor = $service->flavor('{flavorId}'); + + +List flavors +------------ + +.. code-block:: php + + $flavors = $service->flavorList(); + + foreach ($flavors as $flavor) { + /** @param $flavor OpenCloud\Common\Resource\FlavorInterface */ + } + + +Detailed results +~~~~~~~~~~~~~~~~ + +By default, the ``flavorList`` method returns full details on all flavors. +However, because of the overhead involved in retrieving all the details, this +function can be slower than might be expected. To disable this feature and +keep bandwidth at a minimum, just pass ``false`` as the first argument: + +.. code-block:: php + + // Name and ID only + $compute->flavorList(false); + + +Filtering +~~~~~~~~~ + +You can also refine the list of images returned by providing specific filters: + ++-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Array key | Description | ++=================+================================================================================================================================================================================================+ +| minDisk | Filters the list of flavors to those with the specified minimum number of gigabytes of disk storage. | ++-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| minRam | Filters the list of flavors to those with the specified minimum amount of RAM in megabytes. | ++-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| marker | The ID of the last item in the previous list. See the `official docs `__ for more information. | ++-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| limit | Sets the page size. See the `official docs `__ for more information. | ++-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +These are defined in an array and passed in as the second argument. For example, +to return all flavors over 4GB in RAM: + +.. code-block:: php + + $flavors = $service->flavorList(true, array('minRam' => 4)); diff --git a/doc/services/compute/images.rst b/doc/services/compute/images.rst new file mode 100644 index 000000000..fb68af7f7 --- /dev/null +++ b/doc/services/compute/images.rst @@ -0,0 +1,82 @@ +Images +====== + +.. note:: + + **Images on Rackspace servers:** with standard servers, the entire disk + (OS and data) is captured in the image. With Performance servers, only the s + ystem disk is captured in the image. The data disks should be backed up using + Cloud Backup or Cloud Block Storage to ensure availability in case you need + to rebuild or restore a server. + + +List images +----------- + +Below is the simplest usage for retrieving a list of images: + +.. code-block:: php + + $images = $service->imageList(); + + foreach ($images as $image) { + + } + +Detailed results +~~~~~~~~~~~~~~~~ + +By default, the only fields returned in a list call are `id` and `name`, but +you can enable more detailed information to be result by passing in `true` as +the first argument of the call, like so: + +.. code-block:: php + + $images = $service->imageList(true); + + +Filtering +~~~~~~~~~ + +You can also refine the list of images returned by providing specific filters: + ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Array key | Description | ++=================+====================================================================================================================================================================================================================================================================================================================================================+ +| server | Filters the list of images by server. Specify the server reference by ID or by full URL. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| name | Filters the list of images by image name. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| status | Filters the list of images by status. In-flight images have a status of ``SAVING`` and the conditional progress element contains a value from 0 to 100, which indicates the percentage completion. For a full list, please consult the ``OpenCloud\Compute\Constants\ImageState`` class. Images with an ``ACTIVE`` status are available for use. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| changes-since | Filters the list of images to those that have changed since the changes-since time. See the `official docs `__ for more information. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| marker | The ID of the last item in the previous list. See the `official docs `__ for more information. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| limit | Sets the page size. See the `official docs `__ for more information. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| type | Filters base Rackspace images or any custom server images that you have created. Can either be ``BASE`` or ``SNAPSHOT``. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +These are defined in an array and passed in as the second argument. For example, +to filter images for a particular server: + +.. code-block:: php + + $images = $service->imageList(false, array('server' => '{serverId}')); + + +Retrieve details about an image +------------------------------- + +.. code-block:: php + + $image = $service->image('{imageId}'); + + +Delete an image +--------------- + +.. code-block:: php + + $image->delete(); diff --git a/doc/services/compute/index.rst b/doc/services/compute/index.rst new file mode 100644 index 000000000..ee27bce8e --- /dev/null +++ b/doc/services/compute/index.rst @@ -0,0 +1,55 @@ +Compute v2 +========== + +.. include:: ../common/clients.sample.rst + +Compute service +~~~~~~~~~~~~~~~ + +Now to instantiate the Compute service: + +.. code-block:: php + + $service = $client->computeService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + images + flavors + servers + keypairs + + +Glossary +-------- + +.. glossary:: + + image + An image is a collection of files for a specific operating system that you + use to create or rebuild a server. Rackspace provides prebuilt images. You + can also create custom images from servers that you have launched. + + flavor + A flavor is a named definition of certain server parameters such as + the amount of RAM and disk space available. (There are other parameters + set via the flavor, such as the amount of disk space and the number of + virtual CPUs, but a discussion of those is too in-depth for a simple + Getting Started Guide like this one.) + + server + A server is a virtual machine instance in the Cloud Servers environment. + + +Further Links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/compute/keypairs.rst b/doc/services/compute/keypairs.rst new file mode 100644 index 000000000..f7e67b113 --- /dev/null +++ b/doc/services/compute/keypairs.rst @@ -0,0 +1,65 @@ +Keypairs +======== + +Generate a new keypair +---------------------- + +This operation creates a new keypair under a provided name; the public key +value is automatically generated for you. + +.. code-block:: php + + // Instantiate empty object + $keypair = $service->keypair(); + + // Send to API + $keypair->create(array( + 'name' => 'jamie_keypair_1' + )); + + // Save these! + $pubKey = $keypair->getPublicKey(); + $priKey = $keypair->getPrivateKey(); + + +Upload existing keypair +----------------------- + +This operation creates a new keypair according to a provided name and public +key value. This is useful when the public key already exists on your local +filesystem. + +.. code-block:: php + + $keypair = $service->keypair(); + + // $key needs to be the string content of the key file, not the filename + $content = file_get_contents('~/.ssh/id_rsa.pub'); + + $keypair->create(array( + 'name' => 'main_key', + 'publicKey' => $content + )); + +List keypairs +------------- + +To list all existing keypairs: + +.. code-block:: php + + $keys = $service->listKeypairs(); + + foreach ($keys as $key) { + + } + + +Delete keypairs +--------------- + +To delete a specific keypair: + +.. code-block:: php + + $keypair->delete(); diff --git a/doc/services/compute/servers.rst b/doc/services/compute/servers.rst new file mode 100644 index 000000000..229e8e4ff --- /dev/null +++ b/doc/services/compute/servers.rst @@ -0,0 +1,197 @@ +Servers +======= + +Get server +---------- + +The easiest way to retrieve a specific server is by its unique ID: + +.. code-block:: php + + $server = $service->server('{serverId}'); + + +List servers +------------ + +You can list servers in two different ways: + +- return an *overview* of each server (ID, name and links) +- return *detailed information* for each server + +Knowing which option to use might help save unnecessary bandwidth and +reduce latency. + +.. code-block:: php + + // overview + $servers = $service->serverList(); + + // detailed + $servers = $service->serverList(true); + +URL parameters for filtering servers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +| Name | Description | Type | ++==========================+====================================================================================================================================================================================================================================================================================================================+=================================================+ +| image | The image ID | string | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +| flavor | The flavor ID | string | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +| name | The server name | string | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +| status | The server status. Servers contain a status attribute that indicates the current server state. You can filter on the server status when you complete a list servers request, and the server status is returned in the response body. For a full list, please consult ``OpenCloud\Compute\Constants\ServerState`` | string | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +| changes-since | Value for checking for changes since a previous request | A valid ISO 8601 dateTime (2011-01-24T17:08Z) | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ +| RAX-SI:image_schedule | If scheduled images enabled or not. If the value is TRUE, the list contains all servers that have an image schedule resource set on them. If the value is set to FALSE, the list contains all servers that do not have an image schedule. | bool | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ + +Create server +------------- + +Using an image +~~~~~~~~~~~~~~ + +Now we're ready to create our instance: + +.. code-block:: php + + $server = $compute->server(); + + $server->create(array( + 'name' => 'My lovely server', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + )); + +It's always best to be defensive when executing functionality over HTTP; +you can achieve this best by wrapping calls in a try/catch block. It +allows you to debug your failed operations in a graceful and efficient +manner. + +Using a bootable volume +~~~~~~~~~~~~~~~~~~~~~~~ + +Firstly we need to find our volume using their IDs. + +.. code-block:: php + + $bootableVolume = $client->volumeService()->volume('{volumeId}'); + +Now we're ready to create our instance: + +.. code-block:: php + + $server = $compute->server(); + + $response = $server->create(array( + 'name' => 'My lovely server', + 'volume' => $bootableVolume, + 'flavorId' => '{flavorId}' + )); + +It's always best to be defensive when executing functionality over HTTP; +you can achieve this best by wrapping calls in a try/catch block. It +allows you to debug your failed operations in a graceful and efficient +manner. + +Create parameters +~~~~~~~~~~~~~~~~~ + ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| Name | Description | Type | Required | ++=============================+=================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+===========+==============================+ +| name | The server name. The name that you specify in a create request becomes the initial host name of the server. After the server is built, if you change the server name in the API or change the host name directly, the names are not kept in sync. | string | Yes | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| flavor | A populated ``OpenCloud\Compute\Resource\Flavor`` object representing your chosen flavor | object | Yes | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| image | A populated ``OpenCloud\Compute\Resource\Image`` object representing your chosen image | object | No, if volume is specified | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| volume | A populated ``OpenCloud\Volume\Resource\Volume`` object representing your chosen bootable volume | object | No, if image is specified | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| volumeDeleteOnTermination | ``true`` if the bootable volume should be deleted when the server is terminated; ``false``, otherwise | boolean | No; default = ``false`` | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| OS-DCF:diskConfig | The disk configuration value. You can use two options: ``AUTO`` or ``MANUAL``. \ ``AUTO`` means the server is built with a single partition the size of the target flavor disk. The file system is automatically adjusted to fit the entire partition. This keeps things simple and automated. ``AUTO`` is valid only for images and servers with a single partition that use the EXT3 file system. This is the default setting for applicable Rackspace base images.\ ``MANUAL`` means the server is built using whatever partition scheme and file system is in the source image. If the target flavor disk is larger, the remaining disk space is left unpartitioned. This enables images to have non-EXT3 file systems, multiple partitions, and so on, and enables you to manage the disk configuration. | string | No | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| networks | An array of populated ``OpenCloud\Compute\Resource\Network`` objects that indicate which networks your instance resides in. | array | No | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| metadata | An array of arbitrary data (key-value pairs) that adds additional meaning to your server. | array | No | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| keypair | You can install a registered keypair onto your newly created instance, thereby providing scope for keypair-based authentication. | array | No | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| personality | Files that you can upload to your newly created instance's filesystem. | array | No | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ + +Creating a server with keypairs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to provision an instance with a saved keypair (allowing you to SSH +in without passwords), you create your server using the same operation +as usual, with one extra parameter: + +.. code-block:: php + + $server = $compute->server(); + + $server->create(array( + 'name' => 'New server', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + 'keypair' => 'main_key' + )); + +So, as you can see, you specify the **name** of an existing keypair that +you previously created on the API. + + +Creating a server with personality files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Before you execute the create operation, you can add "personality" files +to your ``OpenCloud\Compute\Resource\Server`` object. These files are +structured as a flat array. + +.. code-block:: php + + $server->addFile('/var/test_file', 'FILE CONTENT'); + +As you can see, the first parameter represents the filename, and the +second is a string representation of its content. When the server is +created these files will be created on its local filesystem. For more +information about server personality files, please consult the `official +documentation `__. + +Update server +------------- + +You can update certain attributes of an existing server instance. These +attributes are detailed in the next section. + +.. code-block:: php + + $server->update(array( + 'name' => 'NEW SERVER NAME' + )); + +Updatable attributes +~~~~~~~~~~~~~~~~~~~~ + ++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| name | description | ++==============+==================================================================================================================================================+ +| name | The name of the server. If you edit the server name, the server host name does not change. Also, server names are not guaranteed to be unique. | ++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| accessIPv4 | The IP version 4 address. | ++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| accessIPv6 | The IP version 6 address. | ++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Delete server +------------- + +.. code-block:: php + + $server->delete(); diff --git a/doc/services/database/configurations.rst b/doc/services/database/configurations.rst new file mode 100644 index 000000000..f50619914 --- /dev/null +++ b/doc/services/database/configurations.rst @@ -0,0 +1,127 @@ +Configurations +============== + +Creating a configuration +------------------------ + +.. code-block:: php + + /** @var $configuration OpenCloud\Database\Resource\Configuration **/ + $configuration = $service->configuration(); + + $configuration->create(array( + 'name' => 'example-configuration-name', + 'description' => 'An example configuration', + 'values' => array( + 'collation_server' => 'latin1_swedish_ci', + 'connect_timeout' => 120 + ), + 'datastore' => array( + 'type' => '10000000-0000-0000-0000-000000000001', + 'version' => '1379cc8b-4bc5-4c4a-9e9d-7a9ad27c0866' + ) + )); + +`Get the executable PHP script for this example `__ + + +Listing configurations +---------------------- + +You can list out all the configurations you have created as shown below: + +.. code-block:: php + + $configurations = $service->configurationList(); + foreach ($configurations as $configuration) { + /** @var $configuration OpenCloud\Database\Resource\Configuration **/ + } + +`Get the executable PHP script for this example `__ + + +Retrieving a configuration +-------------------------- + +You can retrieve a specific configuration, using its ID, as shown below: + +.. code-block:: php + + $configuration = $service->configuration('{configId}'); + /** @var OpenCloud\Database\Resource\Configuration **/ + +`Get the executable PHP script for this example `__ + + +Updating a configuration +------------------------ + +You have two choices when updating a configuration: + +* you can `patch a configuration <#patching-a-configuration>`__ to change only +some configuration parameters +* you can `entirely replace a configuration <#replacing-a-configuration>`__ to +replace all configuration parameters with new ones + + +Patching a configuration +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can patch a configuration as shown below: + +.. code-block:: php + + $configuration->patch(array( + 'values' => array( + 'connect_timeout' => 30 + ) + )); + +`Get the executable PHP script for this example `__ + + +Replacing a configuration +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can replace a configuration as shown below: + +.. code-block:: php + + $configuration->update(array( + 'values' => array( + 'collation_server' => 'utf8_general_ci', + 'connect_timeout' => 60 + ) + )); + +`Get the executable PHP script for this example `__ + + +Deleting a configuration +------------------------ + +.. code-block:: php + + $configuration->delete(); + +`Get the executable PHP script for this example `__ + +.. note:: + + You cannot delete a configuration if it is in use by a running instance. + + +Listing instances using a configuration +--------------------------------------- + +You can list all instances using a specific configuration, using its ID, +as shown below: + +.. code-block:: php + + $instances = $configuration->instanceList(); + foreach ($instances as $instance) { + /** @var $instance OpenCloud\Database\Resource\Instance **/ + } + +`Get the executable PHP script for this example `__ diff --git a/doc/services/database/databases.rst b/doc/services/database/databases.rst new file mode 100644 index 000000000..83d07c5e2 --- /dev/null +++ b/doc/services/database/databases.rst @@ -0,0 +1,60 @@ +Databases +========= + +Setup +----- + +In order to interact with the functionality of databases, you must first +retrieve the details of the instance itself. To do this, you must substitute +`{instanceId}` for your instance's ID: + +.. code-block:: php + + $instance = $service->instance('{instanceId}'); + + +Creating a new database +----------------------- + +To create a new database, you must supply it with a name; you can +optionally specify its character set and collating sequence: + +.. code-block:: php + + // Create an empty object + $database = $instance->database(); + + // Send to API + $database->create(array( + 'name' => 'production', + 'character_set' => 'utf8', + 'collate' => 'utf8_general_ci' + )); + +You can find values for ``character_set`` and ``collate`` at `the MySQL +website `__. + + +Deleting a database +------------------- + +.. code-block:: php + + $database->delete(); + +.. note:: + + This is a destructive operation: all your data will be wiped away and will + not be retrievable. + + +Listing databases +----------------- + +.. code-block:: php + + $databases = $service->databaseList(); + + foreach ($databases as $database) { + /** @param $database OpenCloud\Database\Resource\Database */ + } diff --git a/doc/services/database/datastores.rst b/doc/services/database/datastores.rst new file mode 100644 index 000000000..ad6d90e85 --- /dev/null +++ b/doc/services/database/datastores.rst @@ -0,0 +1,59 @@ +Datastores +========== + +Listing datastores +------------------ + +You can list out all the datastores available as shown below: + +.. code-block:: php + + $datastores = $service->datastoreList(); + foreach ($datastores as $datastore) { + /** @var $datastore OpenCloud\Database\Resource\Datastore **/ + } + +`Get the executable PHP script for this example `__ + + +Retrieving a datastore +---------------------- + +You can retrieve a specific datastore's information, using its ID, as +shown below: + +.. code-block:: php + + /** @var OpenCloud\Database\Resource\Datastore **/ + $datastore = $service->datastore('{datastoreId}'); + +`Get the executable PHP script for this example `__ + + +Listing datastore versions +-------------------------- + +You can list out all the versions available for a specific datastore, as +shown below: + +.. code-block:: php + + $versions = $datastore->versionList(); + foreach ($versions as $version) { + /** @var $version OpenCloud\Database\Resource\DatastoreVersion **/ + } + +`Get the executable PHP script for this example `__ + + +Retrieving a datastore version +------------------------------ + +You a retrieve a specific datastore version, using its ID, as shown +below: + +.. code-block:: php + + $datastoreVersion = $datastore->version('{versionId}'); + +`Get the executable PHP script for this example `__ diff --git a/doc/services/database/index.rst b/doc/services/database/index.rst new file mode 100644 index 000000000..32888e27d --- /dev/null +++ b/doc/services/database/index.rst @@ -0,0 +1,77 @@ +Databases v1 +============ + +.. include:: ../common/clients.sample.rst + +Databases service +~~~~~~~~~~~~~~~~~ + +Now to instantiate the Databases service: + +.. code-block:: php + + $service = $client->databaseService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + instances + databases + users + datastores + + +Glossary +-------- + +.. glossary:: + + configuration group + A configuration group is a collection of key/value pairs which configure a + database instance. Some directives are capable of being applied dynamically, + while other directives require a server restart to take effect. The + configuration group can be applied to an instance at creation or applied to + an existing instance to modify the behavior of the running datastore on the + instance. + + flavor + 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. + + instance + A database instance is an isolated MySQL instance in a single tenant + environment on a shared physical host machine. Also referred to as + instance. + + database + A database is a local MySQL database running on an instance. + + user + A user is a local MySQL user that can access a database running on an + instance. + + datastore + The database engine running on your instance. Currently, there is support + for MySQL 5.6, MySQL 5.1, Percona 5.6 and MariaDB 10. + + volume + A volume is user-specified storage that contains the database engine data + directory. Volumes are automatically provisioned on shared Internet Small + Computer System Interface (iSCSI) storage area networks (SAN) that provide + for increased performance, scalability, availability and manageability. + Applications with high I/O demands are performance optimized and data is + protected through both local and network RAID-10. + + +Further Links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/database/instances.rst b/doc/services/database/instances.rst new file mode 100644 index 000000000..6f3afc1e0 --- /dev/null +++ b/doc/services/database/instances.rst @@ -0,0 +1,155 @@ +Instances +========= + +Create a new instance +--------------------- + +.. code-block:: php + + // Create an empty object + $instance = $service->instance(); + + // Send to the API + $instance->create(array( + 'name' => '{name}', + 'flavor' => $service->flavor('{flavorId}'), + 'volume' => array('size' => 4) // 4GB of volume disk + )); + +`Get the executable PHP script for this sample `__ + + +Waiting for the instance to build +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The SDK provides a blocking operation that will wait until your instance resource +has transitioned into an ``ACTIVE`` state. During this period, it will +continuously poll the API and break the loop when the state has been achieved: + +.. code-block:: php + + $instance->waitFor('ACTIVE', null, function ($instance) { + // This will be executed continuously + printf("Database instance build status: %s\n", $instance->status); + }); + + +Connecting an instance to a load balancer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The instance created in the previous step can only be accessed from the +Rackspace private network (aka ``SERVICENET``). If you have a cloud +server instance in the same region as the database server instance, you +will be able to connect to the database from that cloud server instance. + +If, however, you would like to access the database from the Internet, +you will need to create a load balancer with an IP address that is +routable from the Internet and attach the database server instance as a +back-end node of this load balancer. + +.. code-block:: php + + $lbService = $client->loadBalancerService(null, '{region}'); + + // Create empty object + $loadBalancer = $lbService->loadBalancer(); + + // Associate this LB with the instance as a "node" + $loadBalancer->addNode($instance->hostname, 3306); + $loadBalancer->addVirtualIp('PUBLIC'); + + // Configure other parameters and send to the API + $loadBalancer->create(array( + 'name' => 'DB Load Balancer', + 'port' => 3306, + 'protocol' => 'MYSQL', + )); + + // Wait for the resource to create + $loadBalancer->waitFor('ACTIVE', null, function ($loadBalancer) { + printf("Load balancer build status: %s\n", $loadBalancer->status); + }); + + foreach ($loadBalancer->virtualIps as $vip) { + if ($vip->type == 'PUBLIC') { + printf("Load balancer public %s address: %s\n", $vip->ipVersion, $vip->address); + } + } + +In the example above, a load balancer is created with the database +server instance as its only back-end node. Further, this load balancer +is configured to listen for MySQL connections on port 3306. Finally a +virtual IP address (VIP) is configured in the ``PUBLIC`` network address +space so that this load balancer may receive connections from the +Internet. + +Once the load balancer is created and becomes ``ACTIVE``, it's +Internet-accessible IP addresses are printed out. If you connect to any +of these IP addresses on port 3306 using the MySQL protocol, you will be +connected to the database created in step 3. + + +Retrieving an instance +---------------------- + +.. code-block:: php + + $instance = $service->instance('{instanceId}'); + +`Get the executable PHP script for this example `__ + + +Updating an instance +-------------------- + +An instance can be updated to use a specific `configuration `__ as shown below. + +.. code-block:: php + + $instance->update(array( + 'configuration' => '{configurationId}' + )); + +.. note:: + + If any parameters in the associated configuration require a restart, then you + will need to `restart the instance <#restarting-an-instance>`__ after the update. + + +Deleting an instance +-------------------- + +.. code-block:: php + + $instance->delete(); + + +Restarting an instance +---------------------- + +.. code-block:: php + + $instance->restart(); + + +Resizing an instance's RAM +-------------------------- + +To change the amount of RAM allocated to the instance: + +.. code-block:: php + + $flavor = $service->flavor('{flavorId}'); + $instance->resize($flavor); + + +Resizing an instance's volume +----------------------------- + +You can also independently change the volume size to increase the disk +space: + +.. code-block:: php + + // Increase to 8GB disk + $instance->resizeVolume(8); diff --git a/doc/services/database/users.rst b/doc/services/database/users.rst new file mode 100644 index 000000000..0343c4904 --- /dev/null +++ b/doc/services/database/users.rst @@ -0,0 +1,67 @@ +Users +===== + +Setup +----- + +Finally, in order to interact with the functionality of databases, you must +first retrieve the details of the instance itself. To do this, you must +substitute `{instanceId}` for your instance's ID: + +.. code-block:: php + + $instance = $service->instance('{instanceId}'); + + +Creating users +-------------- + +Database users exist at the ``Instance`` level, but can be associated +with a specific ``Database``. They are represented by the +``OpenCloud\Database\Resource\User`` class. + +.. code-block:: php + + // New instance of OpenCloud\Database\Resource\User + $user = $instance->user(); + + // Send to API + $user->create(array( + 'name' => 'Alice', + 'password' => 'fooBar' + 'databases' => array('production') + )); + + +Deleting a user +--------------- + +.. code-block:: php + + $user->delete(); + + +The root user +------------- + +By default, Cloud Databases does not enable the root user. In most +cases, the root user is not needed, and having one can leave you open to +security violations. However, if you do want to enable access to the root user: + +.. code-block:: php + + $rootUser = $instance->enableRootUser(); + + +This returns a regular ``User`` object with the ``name`` attribute set +to ``root`` and the ``password`` attribute set to an auto-generated +password. + + +Check if root user is enabled +----------------------------- + +.. code-block:: php + + // true for yes, false for no + $instance->isRootEnabled(); diff --git a/doc/services/dns/domains.rst b/doc/services/dns/domains.rst new file mode 100644 index 000000000..0a7b83b96 --- /dev/null +++ b/doc/services/dns/domains.rst @@ -0,0 +1,288 @@ +Domains +======= + +Get domain +---------- + +To retrieve a specific domain, you will need the domain's **id**, not +its domain name: + +.. code-block:: php + + $domain = $service->domain('{domainId}'); + + +If you are having trouble remembering or accessing the domain ID, you +can do a domain list search for your domain and then access its ID. + + +List domains +------------ + +These calls provide a list of all DNS domains manageable by a given +account. The resulting list is flat, and does not break the domains down +hierarchically by subdomain. All representative domains are included in +the list, even if a domain is conceptually a subdomain of another domain +in the list. + +.. code-block:: php + + $domains = $service->domainList(); + + # Return detailed information for each domain + $domains = $service->domainList(true); + + +Filter parameters +~~~~~~~~~~~~~~~~~ + +You can filter the search by using the ``name`` parameter in a key/value array +supplied as a method argument. For example, to retrieve domains named ``foo.com``, +along with any subdomains like ``bar.foo.com``: + +.. code-block:: php + + $hoolaDomains = $service->domainList(array( + 'name' => 'foo.com' + )); + +Filter criteria may consist of: + +* Any letter (A-Za-z) +* Numbers (0-9) +* Hyphen ("-") +* 1 to 63 characters + +Filter criteria should not include any of the following characters: + + ' + , \| ! " £ $ % & / ( ) = ? ^ \* ç ° § ; : \_ > ] [ @ à, é, ò + + +Finding a domain ID +~~~~~~~~~~~~~~~~~~~ + +Once you have a list of domains, to retrieve a domain's ID: + +.. code-block:: php + + foreach ($domains as $domain) { + $id = $domain->id; + } + + +List domain changes +------------------- + +This call shows all changes to the specified domain since the specified +date/time. To list all available changes for a domain for the current day: + +.. code-block:: php + + $changes = $domain->changes(); + + +For more granular control, you can manually define the ``since`` parameter like +so: + +.. code-block:: php + + $since = date('c', strtotime('last week')); + $changes = $domain->changes($since); + +Once you have a set of changes, you can iterate over them like so: + +.. code-block:: php + + foreach ($changes->changes as $change) { + printf("Domain: %s\nAction: %s\nTarget: %s", $change->domain, $change->action, $change->targetType); + + foreach ($change->changeDetails as $detail) { + printf("Details: %s was changed from %s to %s", $detail->field, $detail->oldValue, $detail->newValue); + } + } + + +Create domain +------------- + +The first thing you will need to do is instantiate a new object and set the +primary ``A`` record for the DNS domain, like so: + +.. code-block:: php + + // get empty object + $domain = $service->domain(); + + // add A record + $aRecord = $domain->record(array( + 'type' => 'A', + 'name' => 'example.com', + 'data' => '192.0.2.17', + 'ttl' => 3600 + )); + + $domain->addRecord($aRecord); + +You also have the option of adding more types of DNS records such as ``CNAME``, +``MX`` and ``NS`` records. This step is completely optional and depends on +your requirements: + +.. code-block:: php + + // add CNAME record + $cRecord = $domain->record(array( + 'type' => 'CNAME', + 'name' => 'www.example.com', + 'data' => 'example.com', + 'ttl' => 3600 + )); + $domain->addRecord($cRecord); + + // add MX record + $mxRecord = $domain->record(array( + 'type' => 'MX', + 'data' => 'mail.example.com', + 'name' => 'example.com', + 'ttl' => 3600, + 'priority' => 5 + )); + $domain->addRecord($mxRecord); + + // add NS record + $nsRecord = $domain->record(array( + 'type' => 'NS', + 'data' => 'dns1.stabletransit.com', + 'name' => 'example.com', + 'ttl' => 5400 + )); + $domain->addRecord($nsRecord); + +You can also add sub-domains to your new DNS domain. Again, this is completely +optional: + +.. code-block:: php + + $subdomain = $domain->subdomain(array( + 'emailAddress' => 'foo@example.com', + 'name' => 'dev.example.com', + 'comment' => 'Dev portal' + )); + $domain->addSubdomain($subdomain); + +Once you've finished configuring how your DNS domain will work, you're ready +to specify the essential details and send it to the API for creation: + +.. code-block:: php + + $domain->create(array( + 'emailAddress' => 'webmaster@example.com', + 'ttl' => 3600, + 'name' => 'example.com', + 'comment' => 'Optional comment' + )); + + +Clone domain +------------ + +This call will duplicate an existing domain under a new name. By default, all +records and, optionally, subdomains are duplicated as well. + +The method signature you will need to use is: + +.. function:: cloneDomain( $newDomainName[, $subdomains[, $comments[, $email[, $records]]]] ) + + Clone a domain + + :param string $newDomainName: The name of the new domain entry + :param bool $subdomains: Set to ``true`` to clone all the subdomains for this domain + :param bool $comments: Set to ``true`` to replace occurrences of the reference domain name with the new domain name in comments on the cloned (new) domain. + :param bool $email: Set to ``true`` to replace occurrences of the reference domain name with the new domain name in data fields (of records) on the cloned (new) domain. Does not affect NS records. + :param bool $records: Set to ``true`` to replace occurrences of the reference domain name with the new domain name in data fields (of records) on the cloned (new) domain. Does not affect NS records. + + +For example: + +.. code-block:: php + + $asyncResponse = $domain->cloneDomain('new-name.com', true, false, true, false); + + +Export domain +------------- + +This call provides access to the `BIND `_ +(Berkeley Internet Name Domain) 9 for the requested domain. This call is for a +single domain only, and as such, does not traverse up or down the domain +hierarchy for details: + +.. code-block:: php + + $asyncResponse = $domain->export(); + + $body = $asyncResponse->waitFor('COMPLETED'); + echo $body['contents']; + + +Import domain +------------- + +This operation will create a new DNS domain according to a `BIND `_ +(Berkeley Internet Name Domain) 9 formatted value. + +In order for the BIND value to be considered valid, it needs to adhere to the +following rules: + +* Each record starts on a new line and on the first column. If a record will + not fit on one line, use the BIND\_9 line continuation convention where you put + a left parenthesis and continue the one record on the next line and put a right + parenthesis when the record ends. For example: + + example2.net. 3600 IN SOA dns1.stabletransit.com. (sample@rackspace.com. 1308874739 3600 3600 3600 3600) + +* The attribute values of a record must be separated by a single blank or tab. + No other white space characters. + +* If there are any NS records, the data field should not be + ``dns1.stabletransit.com`` or ``dns2.stabletransit.com``. They will result in + "duplicate record" errors. + +For example: + +.. code-block:: php + + $bind9Data = <<import($bind9Data); + + +Modify domain +------------- + +Only the TTL, email address and comment attributes of a domain can be modified. +Records cannot be added, modified, or removed through this API operation - you +will need to use the `add records `__, `modify records +`__ or `remove records `__ +operations respectively. + +.. code-block:: php + + $domain->update(array( + 'ttl' => ($domain->ttl + 100), + 'emailAddress' => 'new_dev@foo.com' + )); + + +Delete domain +------------- + +.. code-block:: php + + $domain->delete(); diff --git a/doc/services/dns/index.rst b/doc/services/dns/index.rst new file mode 100644 index 000000000..39db3d675 --- /dev/null +++ b/doc/services/dns/index.rst @@ -0,0 +1,59 @@ +DNS v1 +====== + +.. include:: ../common/rs-only.sample.rst + +DNS service +~~~~~~~~~~~ + +Now to instantiate the DNS service: + +.. code-block:: php + + $service = $client->dnsService(); + + +Operations +---------- + +.. toctree:: + + records + domains + limits + reverse-dns + + +Glossary +-------- + + domain + A domain is an entity/container of all DNS-related information containing + one or more records. + + record + A DNS record belongs to a particular domain and is used to specify + information about the domain. There are several types of DNS records. Each + record type contains particular information used to describe that record's + purpose. Examples include mail exchange (MX) records, which specify the + mail server for a particular domain, and name server (NS) records, which + specify the authoritative name servers for a domain. + + subdomain + Subdomains are domains within a parent domain, and subdomains cannot be + registered. Subdomains allow you to delegate domains. Subdomains can + themselves have subdomains, so third-level, fourth-level, fifth-level, and + deeper levels of nesting are possible. + + pointer records + DNS usually determines an IP address associated with a domain name. + Reverse DNS is the opposite process: resolving a domain name from an IP + address. This is usually achieved with a domain name pointer. + + +Further Links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/dns/limits.rst b/doc/services/dns/limits.rst new file mode 100644 index 000000000..289c3888d --- /dev/null +++ b/doc/services/dns/limits.rst @@ -0,0 +1,57 @@ +Limits +====== + +List all limits +--------------- + +This call provides a list of all applicable limits for the specified account. + +.. code:: php + + $limits = $service->limits(); + + +Absolute limits +~~~~~~~~~~~~~~~ + +There are some absolute limits imposed on your account - such as how +many domains you can create and how many records you can create for each +domain: + +.. code:: php + + $absoluteLimits = $limits->absolute; + + // Domain limit + echo $absoluteLimits->domains; + + // Record limit per domain + echo $absoluteLimits->{'records per domain'}; + + +List limit types +---------------- + +To find out the different limit types you can query, run: + +.. code:: php + + $limitTypes = $service->limitTypes(); + +will return: + +:: + + array(3) { + [0] => string(10) "RATE_LIMIT" + [1] => string(12) "DOMAIN_LIMIT" + [2] => string(19) "DOMAIN_RECORD_LIMIT" + } + +Query a specific limit +---------------------- + +.. code:: php + + $limit = $service->limits('DOMAIN_LIMIT'); + echo $limit->absolute->limits->value; diff --git a/doc/services/dns/records.rst b/doc/services/dns/records.rst new file mode 100644 index 000000000..26e17ee5e --- /dev/null +++ b/doc/services/dns/records.rst @@ -0,0 +1,113 @@ +Records +======= + +Setup +----- + +In order to interact with the functionality of records, you must first +retrieve the details of the domain itself. To do this, you must substitute +`{domainId}` for your domain's ID: + +.. code-block:: php + + $domain = $service->domain('{domainId}'); + + +Get record +---------- + +In order to retrieve details for a specific DNS record, you will need +its **id**: + +.. code:: php + + $record = $domain->record('{recordId}'); + +If you do not have this ID at your disposal, you can traverse the record +collection and do a string comparison (detailed below). + + +List records +------------ + +This call lists all records configured for the specified domain. + +.. code:: php + + $records = $domain->recordList(); + + foreach ($records as $record) { + printf("Record name: %s, ID: %s, TTL: %s\n", $record->name, $record->id, $record->ttl); + } + + +Query parameters +~~~~~~~~~~~~~~~~ + +You can pass in an array of query parameters for greater control over +your search: + ++------------+--------------+------------------------+ +| Name | Data type | Description | ++============+==============+========================+ +| ``type`` | ``string`` | The record type | ++------------+--------------+------------------------+ +| ``name`` | ``string`` | The record name | ++------------+--------------+------------------------+ +| ``data`` | ``string`` | Data for this record | ++------------+--------------+------------------------+ + + +Find a record ID from its name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For example: + +.. code:: php + + $records = $domain->recordList(array( + 'name' => 'imap.example.com', + 'type' => 'MX' + )); + + foreach ($records as $record) { + $recordId = $record->id; + } + + +Add record +---------- + +This call adds a new record to the specified domain: + +.. code:: php + + $record = $domain->record(array( + 'type' => 'A', + 'name' => 'example.com', + 'data' => '192.0.2.17', + 'ttl' => 3600 + )); + + $record->create(); + + +Please be aware that records that are added with a different hostname +than the parent domain might fail silently. + +Modify record +------------- + +.. code:: php + + $record = $domain->record('{recordId}'); + $record->ttl -= 100; + $record->update(); + + +Delete record +------------- + +.. code:: php + + $record->delete(); diff --git a/doc/services/dns/reverse-dns.rst b/doc/services/dns/reverse-dns.rst new file mode 100644 index 000000000..4d0eb671c --- /dev/null +++ b/doc/services/dns/reverse-dns.rst @@ -0,0 +1,92 @@ +Reverse DNS +=========== + + +Get PTR record +-------------- + +PTR records refer to a parent device: either a Cloud Server or a Cloud +Load Balancer with a public virtual IP address. You must supply a fully +formed resource object in order to retrieve either one's PTR record: + +.. code:: php + + /** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */ + + $ptr = $service->ptrRecord(array( + 'parent' => $parent + )); + +So, in the above example, the ``$parent`` object could be an instance of +``OpenCloud\Compute\Resource\Server`` or +``OpenCloud\LoadBalancer\Resource\LoadBalancer`` - because they both +implement ``OpenCloud\DNS\Resource\HadPtrRecordsInterface``. Please +consult the `server documentation <../compute>`__ and `load +balancer documentation <../load-balancer>`__ for more +detailed usage instructions. + + +List PTR records +---------------- + +.. code:: php + + /** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */ + + $ptrRecords = $service->ptrRecordList($parent); + + foreach ($ptrRecords as $ptrRecord) { + + } + + +Add PTR record +-------------- + +.. code:: php + + $parent = $computeService->server('foo-server-id'); + + $ptr = $dnsService->ptrRecord(array( + 'parent' => $parent, + 'ttl' => 3600, + 'name' => 'example.com', + 'type' => 'PTR', + 'data' => '192.0.2.7' + )); + + $ptr->create(); + +Here is a table that explains the above attributes: + ++-----------+------------------------------------------------------------------------------------+------------+ +| Name | Description | Required | ++===========+====================================================================================+============+ +| type | Specifies the record type as "PTR". | Yes | ++-----------+------------------------------------------------------------------------------------+------------+ +| name | Specifies the name for the domain or subdomain. Must be a valid domain name. | Yes | ++-----------+------------------------------------------------------------------------------------+------------+ +| data | The data field for PTR records must be a valid IPv4 or IPv6 IP address. | Yes | ++-----------+------------------------------------------------------------------------------------+------------+ +| ttl | If specified, must be greater than 300. Defaults to 3600 if no TTL is specified. | No | ++-----------+------------------------------------------------------------------------------------+------------+ +| comment | If included, its length must be less than or equal to 160 characters. | No | ++-----------+------------------------------------------------------------------------------------+------------+ + + +Modify PTR record +----------------- + +.. code:: php + + $ptr->update(array( + 'ttl' => $ptr->ttl * 2 + )); + + +Delete PTR record +----------------- + +.. code:: php + + $ptr->delete(); diff --git a/doc/services/identity/index.rst b/doc/services/identity/index.rst new file mode 100644 index 000000000..6cb4dfdf4 --- /dev/null +++ b/doc/services/identity/index.rst @@ -0,0 +1,55 @@ +Identity v2 +=========== + +.. include:: ../common/clients.sample.rst + +Identity service +~~~~~~~~~~~~~~~~ + +Now to instantiate the Identity service: + +.. code-block:: php + + $service = $client->identityService(); + + +Operations +---------- + +.. toctree:: + + tokens + users + tenants + +Glossary +-------- + +.. glossary:: + + token + A token is an opaque string that represents an authorization to access + cloud resources. Tokens may be revoked at any time and are valid for a + finite duration. + + tenant + A tenant is a container used to group or isolate resources and/or + identity objects. Depending on the service operator, a tenant may map to + a customer, account, organization, or project. + + user + A user is a digital representation of a person, system, or service who + consumes cloud services. Users have credentials and may be assigned + tokens; based on these credentials and tokens, the authentication + service validates that incoming requests are being made by the user who + claims to be making the request, and that the user has the right to + access the requested resources. Users may be directly assigned to a + particular tenant and behave as if they are contained within that + tenant. + + +Further Links +------------- + +- `Quickstart for the API `_ +- `API Developer Guide `_ diff --git a/doc/services/identity/roles.rst b/doc/services/identity/roles.rst new file mode 100644 index 000000000..614518b9b --- /dev/null +++ b/doc/services/identity/roles.rst @@ -0,0 +1,78 @@ +Roles +===== + +A role is a personality that a user assumes when performing a specific +set of operations. A role includes a set of rights and privileges. A +user assuming a role inherits the rights and privileges associated with +the role. A token that is issued to a user includes the list of roles +the user can assume. When a user calls a service, that service +determines how to interpret a user's roles. A role that grants access to +a list of operations or resources within one service may grant access to +a completely different list when interpreted by a different service. + +Useful object properties/methods +-------------------------------- + ++---------------+------------------------+------------------------+ +| Property | Getter | Setter | ++===============+========================+========================+ +| id | ``getId()`` | ``setId()`` | ++---------------+------------------------+------------------------+ +| name | ``getName()`` | ``setName()`` | ++---------------+------------------------+------------------------+ +| description | ``getDescription()`` | ``setDescription()`` | ++---------------+------------------------+------------------------+ + +List roles +---------- + +This call lists the global roles available within a specified service. + +.. code-block:: php + + $roles = $service->getRoles(); + + foreach ($roles as $role) { + // ... + } + + +Get role +-------- + +This call lists detailed information (id, name, description) for a +specified role. + +.. code-block:: php + + $role = $service->getRole('{roleId}'); + + +Add/delete user roles +--------------------- + +.. code-block:: php + + $user = $service->getUser('{userId}'); + + $roleId = '{roleId}'; + + // add role to user + $user->addRole($roleId); + + // remove role from user + $user->removeRole($roleId); + + +List user global roles +---------------------- + +This call returns a list of global roles associated with a user: + +.. code-block:: php + + $roles = $user->getRoles(); + + foreach ($roles as $role) { + // ... + } diff --git a/doc/services/identity/tenants.rst b/doc/services/identity/tenants.rst new file mode 100644 index 000000000..a27417cca --- /dev/null +++ b/doc/services/identity/tenants.rst @@ -0,0 +1,26 @@ +Tenants +======= + +List tenants +------------ + +.. code-block:: php + + $tenants = $service->getTenants(); + + foreach ($tenants as $tenant) { + // ... + } + +Tenant object properties and methods +------------------------------------ + +Once you have a ``OpenCloud\Identity\Resource\Tenant`` object, you can retrieve +information like so: + +.. code-block:: php + + $tenant->getId(); + $tenant->getName(); + $tenant->getDescription(); + $tenant->isEnabled(); diff --git a/doc/services/identity/tokens.rst b/doc/services/identity/tokens.rst new file mode 100644 index 000000000..e4601c7c4 --- /dev/null +++ b/doc/services/identity/tokens.rst @@ -0,0 +1,101 @@ +Tokens +====== + +Create token (authenticate) +--------------------------- + +In order to generate a token, you must pass in the JSON template that is +sent to the API. This is because Rackspace's operation expects a +slightly different entity body than OpenStack Keystone. + +To do this, and then generate a token: + +.. code-block:: php + + $json = $client->getCredentials(); + + /** @var $response Guzzle\Http\Message\Response */ + $response = $service->generateToken($json); + $jsonBody = $response->json(); + +When a token is generated by the API, there are a few things returned: + +* a `service catalog `_ + outlining all of the services you can interact with, + including their names, service types, and endpoint URLs. Which services + make up your catalog, and how your catalog is structured, will depend on + your service provider. + +* details about your token, such as its ID, created and expiration date + +* details about your user account + +* details about your tenant + +Interacting with the service catalog +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you have the ``$jsonBody``, you can construct a ``Catalog`` object for +easier interaction: + +.. code-block:: php + + $data = $jsonBody->access->serviceCatalog; + $catalog = OpenCloud\Common\Service\Catalog::factory($data); + + foreach ($catalog->getItems() as $service) { + /** @param $service OpenCloud\Common\Service\CatalogItem */ + printf("Catalog item: Name [%s] Type [%s]\n", $service->getName(), $service->getType()); + + foreach ($service->getEndpoints() as $endpoint) { + printf(" Endpoint provided: Region [%s] PublicURL [%s] PrivateURL [%s]\n", + $endpoint->getRegion(), $endpoint->getPublicUrl(), $endpoint->getPrivateUrl()); + } + } + +Interacting with tokens +~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $data = $jsonBody->access->token; + $token = $service->resource('Token', $data); + + printf("Token ID: %s - Token expiry %s", $token->getId(), $token->getExpires()); + + if ($token->hasExpired()) { + // ... + } + +Interacting with users +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $data = $jsonBody->access->user; + $user = $service->resource('User', $data); + +To see which methods you can call on ``$user`` (which implements +``OpenCloud\Identity\Resource\User``), see our :doc:`user documentation ` +which accompanies this guide. + + +Interacting with tenants +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $data = $jsonBody->access->tenant; + $tenant = $service->resource('Tenant', $data); + +To see which methods you can call on ``$tenant`` (which implements +``OpenCloud\Identity\Resource\Tenant``), see our :doc:`user documentation ` +which accompanies this guide. + + +Revoke token (destroy session) +------------------------------ + +.. code-block:: php + + $service->revokeToken('{tokenId}'); diff --git a/doc/services/identity/users.rst b/doc/services/identity/users.rst new file mode 100644 index 000000000..b55236a74 --- /dev/null +++ b/doc/services/identity/users.rst @@ -0,0 +1,161 @@ +Users +===== + + +Object properties/methods +------------------------- + ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| Property | Description | Getter | Setter | ++=================+===============================================================================================================================================================================================================================================================================================================================+============================================+===============================================================================================================+ +| id | The unique ID for this user | ``getId()`` | ``setId()`` | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| username | Username for this user | ``getUsername()`` | ``setUsername()`` | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| email | User's email address | ``getEmail()`` | ``setEmail()`` | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| enabled | Whether or not this user can consume API functionality | ``getEnabled()`` or ``isEnabled()`` | ``setEnabled()`` | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| password | Either a user-defined string, or an automatically generated one, that provides security when authenticating. | ``getPassword()`` only valid on creation | ``setPassword()`` to set local property only. To set password on API (retention), use ``updatePassword()``. | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| defaultRegion | Default region associates a user with a specific regional datacenter. If a default region has been assigned for this user and that user has **NOT** explicitly specified a region when creating a service object, the user will obtain the service from the default region. | ``getDefaultRegion()`` | ``setDefaultRegion()`` | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| domainId | Domain ID associates a user with a specific domain which was assigned when the user was created or updated. A domain establishes an administrative boundary for a customer and a container for a customer's tenants (accounts) and users. Generally, a domainId is the same as the primary tenant id of your cloud account. | ``getDomainId()`` | ``setDomainId()`` | ++-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------+ + +List users +---------- + +.. code-block:: php + + $users = $service->getUsers(); + + foreach ($users as $user) { + // ... + } + + +Retrieve a user by username +--------------------------- + +.. code-block:: php + + $user = $service->getUser('jamie'); + + +Retrieve a user by user ID +-------------------------- + +.. code-block:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + $user = $service->getUser('{userId}', UserConst::MODE_ID); + + +Retrieve a user by email address +-------------------------------- + +.. code-block:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + $user = $service->getUser('{emailAddress}', UserConst::MODE_EMAIL); + + +Create user +----------- + +There are a few things to bear in mind when creating a user: + +* This operation is available only to users who hold the + ``identity:user-admin`` role. This admin can create a user who holds + the ``identity:default`` user role. + +* The created user **will** have access to APIs but **will not** have + access to the Cloud Control Panel. + +* A maximum of 100 account users can be added per account. + +* If you attempt to add a user who already exists, an HTTP error 409 + results. + + +The ``username`` and ``email`` properties are required for creating a +user. Providing a ``password`` is optional; if omitted, one will be +automatically generated and provided in the response. + + +.. code-block:: php + + use Guzzle\Http\Exception\ClientErrorResponseException; + + $user = $service->createUser(array( + 'username' => 'newUser', + 'email' => 'foo@bar.com' + )); + + // show generated password + echo $user->getPassword(); + + +Update user +----------- + +When updating a user, specify which attribute/property you want to +update: + +.. code-block:: php + + $user->update(array( + 'email' => 'new_email@bar.com' + )); + + +Updating a user password +------------------------ + +Updating a user password requires calling a distinct method: + +.. code-block:: php + + $user->updatePassword('password123'); + + +Delete user +----------- + +.. code-block:: php + + $user->delete(); + + +List credentials +---------------- + +This operation allows you to see your non-password credential types for +all authentication methods available. + +.. code-block:: php + + $creds = $user->getOtherCredentials(); + + +Get user API key +---------------- + +.. code-block:: php + + echo $user->getApiKey(); + + +Reset user API key +------------------ + +When resetting an API key, a new one will be automatically generated for +you: + +.. code-block:: php + + $user->resetApiKey(); + echo $user->getApiKey(); diff --git a/doc/services/image/images.rst b/doc/services/image/images.rst new file mode 100644 index 000000000..ec1a17c34 --- /dev/null +++ b/doc/services/image/images.rst @@ -0,0 +1,84 @@ +Images +====== + +List images +----------- + +.. code-block:: php + + $images = $service->listImages(); + + foreach ($images as $image) { + /** @param $image OpenCloud\Image\Resource\Image */ + } + + +Get image details +----------------- + +.. code-block:: php + + /** @param $image OpenCloud\Image\Resource\Image */ + $image = $service->getImage('{imageId}'); + + +A note on schema classes +~~~~~~~~~~~~~~~~~~~~~~~~ + +Both ``OpenCloud\Image\Resource\Image`` and ``OpenCloud\Image\Resource\Member`` +extend the ``AbstractSchemaResource`` class, which offers some unique functionality. + +Because these resources are inherently dynamic - i.e. they are modelled +on dynamic JSON schema - you need to access their state in a different way +than conventional getter/setter methods, and even class properties. For this +reason, they implement SPL's native +`ArrayAccess `_ +interface which allows you to access their state as a conventional +array: + +.. code-block:: php + + $image = $service->getImage('{imageId}'); + + $id = $image['id']; + $tags = $image['tags']; + + +Update image +------------ + +You can only update your own custom images - you cannot update or delete +base images. The way in which you may update your image is dictated by +its `schema `__. + +Although you should be able to add new and replace existing properties, +always prepare yourself for a situation where it might be forbidden: + +.. code-block:: php + + use OpenCloud\Common\Exceptions\ForbiddenOperationException; + + try { + $image->update(array( + 'name' => 'foo', + 'newProperty' => 'bar' + )); + } catch (ForbiddenOperationException $e) { + // A 403 Forbidden was returned + } + +There are three operations that can take place for each Image property: + +* If a ``false`` or ``null`` value is provided, a ``REMOVE`` operation + will occur, removing the property from the JSON document +* If a non-false value is provided and the property does not exist, an + ``ADD`` operation will add it to the document +* If a non-false value is provided and the property does exist, a + ``REPLACE`` operation will modify the property in the document + +Delete image +------------ + +.. code-block:: php + + $image->delete(); diff --git a/doc/services/image/index.rst b/doc/services/image/index.rst new file mode 100644 index 000000000..a7331b430 --- /dev/null +++ b/doc/services/image/index.rst @@ -0,0 +1,50 @@ +Images v1 +========= + +.. include:: ../common/clients.sample.rst + +Images service +~~~~~~~~~~~~~~ + +Now to instantiate the Images service: + +.. code-block:: php + + $service = $client->imageService(null, '{region}'); + + +Operations +---------- + +.. toctree:: + + images + schemas + sharing + tags + + +Glossary +-------- + + image + A virtual machine image is a single file which contains a virtual disk + that has an installed bootable operating system. In the Cloud Images + API, an image is represented by a JSON-encoded data structure (the image + schema) and its raw binary data (the image file). + + schema + The Cloud Images API supplies JSON documents describing the JSON-encoded + data structures that represent domain objects, so that a client knows + exactly what to expect in an API response. + + tag + An image tag is a string of characters used to identify a specific image + or images. + + +Further Links +------------- + + - `Getting Started Guide for the API `_ + - `API Developer Guide `_ diff --git a/doc/services/image/schemas.rst b/doc/services/image/schemas.rst new file mode 100644 index 000000000..c1b85b8de --- /dev/null +++ b/doc/services/image/schemas.rst @@ -0,0 +1,163 @@ +JSON schemas +============ + +Schema types +------------ + +There are currently four types of schema: Images schema, Image schema, +Members schema, and Member schema. + +Example response from the API +----------------------------- + +A sample response from the API, for an Images schema might be: + +.. code-block:: json + + { + "name": "images", + "properties": { + "images": { + "items": { + "type": "array", + "name": "image", + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "visibility": {"enum": ["public", "private"]}, + "status": {"type": "string"}, + "protected": {"type": "boolean"}, + "tags": { + "type": "array", + "items": {"type": "string"} + }, + "checksum": {"type": "string"}, + "size": {"type": "integer"}, + "created_at": {"type": "string"}, + "updated_at": {"type": "string"}, + "file": {"type": "string"}, + "self": {"type": "string"}, + "schema": {"type": "string"} + }, + "additionalProperties": {"type": "string"}, + "links": [ + {"href": "{self}", "rel": "self"}, + {"href": "{file}", "rel": "enclosure"}, + {"href": "{schema}", "rel": "describedby"} + ] + } + }, + "schema": {"type": "string"}, + "next": {"type": "string"}, + "first": {"type": "string"} + }, + "links": [ + {"href": "{first}", "rel": "first"}, + {"href": "{next}", "rel": "next"}, + {"href": "{schema}", "rel": "describedby"} + ] + } + +The top-level schema is called ``images``, and contains an array of +links and a properties object. Inside this properties object we see the +structure of this top-level ``images`` object. So we know that it will +take this form: + +.. code-block:: json + + { + "images": [something...] + } + +Within this object, we can see that it contains an array of anonymous +objects, each of which is called ``image`` and has its own set of nested +properties: + +.. code-block:: json + + { + "images": [ + { + [object 1...] + }, + { + [object 2...] + }, + { + [object 3...] + } + ] + } + +The structure of these nested objects are defined as another schema - +i.e. a *subschema*. We know that each object has an ID property +(string), a name property (string), a visibility property (can either be +``private`` or ``public``), etc. + +.. code-block:: json + + { + "images": [ + { + "id": "foo", + "name": "bar", + "visibility": "private", + // etc. + }, + { + "id": "foo", + "name": "bar", + "visibility": "private", + // etc. + }, + { + "id": "foo", + "name": "bar", + "visibility": "private", + // etc. + } + ] + } + +Each nested property of a schema is represented by the +``OpenCloud\Image\Resource\Schema\Property`` class. + +If you would like to find out more about schemas, Guzzle has good +documentation about `service +descriptions `__, +which is fairly analogous. + +JSON Patch +---------- + +The Glance API has a unique way of updating certain dynamic resources: +they use JSON Patch method, as outlined in `RFC +6902 `__. + +Requests need to use the +``application/openstack-images-v2.1-json-patch`` content-type. + +In order for the operation to occur, the request entity body needs to +contain a very particular structure: + +.. code-block:: json + + [ + {"op": "replace", "path": "/name", "value": "Fedora 17"}, + {"op": "replace", "path": "/tags", "value": ["fedora", "beefy"]} + ] + +* The ``op`` key refers to the type of Operation (see + ``OpenCloud\Image\Enum\OperationType`` for a full list). + +* The ``path`` key is a JSON pointer to the document property you want to + modify or insert. JSON pointers are defined in `RFC + 6901 `__. + +* The ``value`` key is the value. + +Because this is all handled for you behind the scenes, we will not go +into exhaustive depth about how this operation is handled. You can +browse the source code, consult the various RFCs and the `official +documentation `__ +for additional information. diff --git a/doc/services/image/sharing.rst b/doc/services/image/sharing.rst new file mode 100644 index 000000000..5edf63ab4 --- /dev/null +++ b/doc/services/image/sharing.rst @@ -0,0 +1,127 @@ +Sharing images +============== + +Images can be created and deleted by image producers, updated by image +consumers, and listed by both image producers and image consumers: + ++-------------+-----------------+-----------------+ +| Operation | Producer can? | Consumer can? | ++=============+=================+=================+ +| Created | Yes | No | ++-------------+-----------------+-----------------+ +| Deleted | Yes | No | ++-------------+-----------------+-----------------+ +| Updated | No | Yes | ++-------------+-----------------+-----------------+ +| Listed | Yes | Yes | ++-------------+-----------------+-----------------+ + +The producer shares an image with the consumer by making the consumer a +*member* of that image. The consumer then accepts or rejects the image +by changing the member status. Once accepted, the image appears in the +consumer's image list. + +Typical workflow +---------------- + +1. The producer posts the availability of specific images on a public + website. + +2. A potential consumer provides the producer with his/her tenant ID and + email address. + +3. The producer `creates a new Image Member <>`__ with the consumer's + details + +4. The producer notifies the consumer via email that the image has been + shared and provides the image's ID. + +5. If the consumer wishes the image to appear in his/her image list, the + consumer `updates their own Member status <>`__ to ``ACCEPTED``. + +Additional notes +~~~~~~~~~~~~~~~~ + +- If the consumer subsequently wishes to hide the image, the consumer + can change their Member status to ``REJECTED``. + +- If the consumer wishes to hide the image, but is open to the + possibility of being reminded by the producer that the image is + available, the consumer can change their Member status to + ``PENDING``. + +- Image producers add or remove image members, but may not modify the + member status of an image member. + +- Image consumers change their own member status, but may not add or + remove themselves as an image member. + +- Image consumers can boot from any image shared by the image producer, + regardless of the member status, as long as the image consumer knows + the image ID. + +Setup +----- + +All member operations are executed against an `Image `__, so you will +need to set one up first: + +.. code-block:: php + + $image = $service->getImage('{imageId}'); + + +List image members +------------------ + +This operation is available for both producers and consumers. + +.. code-block:: php + + $members = $image->listMembers(); + + foreach ($members as $member) { + /** @param $member OpenCloud\Image\Resource\Member */ + } + + +Create image member +------------------- + +This operation is only available for producers. + +.. code-block:: php + + /** @param $response Guzzle\Http\Message\Response */ + $response = $image->createMember('{tenantId}'); + + +Delete image member +------------------- + +This operation is only available for producers. + +.. code-block:: php + + /** @param $member OpenCloud\Image\Resource\Member */ + $member = $image->getMember('{tenantId}'); + $member->delete(); + + +Update image member status +-------------------------- + +This operation is only available for consumers. + +.. code-block:: php + + use OpenCloud\Images\Enum\MemberStatus; + + /** @param $member OpenCloud\Image\Resource\Member */ + $member = $image->getMember('{tenantId}'); + + $member->updateStatus(MemberStatus::ACCEPTED); + +The acceptable states you may pass in are made available to you through +the constants defined in the ``OpenCloud\Images\Enum\MemberStatus`` +class. diff --git a/doc/services/image/tags.rst b/doc/services/image/tags.rst new file mode 100644 index 000000000..0a376e6de --- /dev/null +++ b/doc/services/image/tags.rst @@ -0,0 +1,29 @@ +Image tags +========== + +Setup +----- + +All member operations are executed against an `Image `__, so you will +need to set one up first: + +.. code-block:: php + + $image = $service->getImage('{imageId}'); + + +Add image tag +------------- + +.. code-block:: php + + /** @param $response Guzzle\Http\Message\Response */ + $response = $image->addTag('jamie_dev'); + +Delete image tag +---------------- + +.. code-block:: php + + /** @param $response Guzzle\Http\Message\Response */ + $response = $image->deleteTag('jamie_dev'); diff --git a/doc/services/load-balancer/access.rst b/doc/services/load-balancer/access.rst new file mode 100644 index 000000000..4387dd8de --- /dev/null +++ b/doc/services/load-balancer/access.rst @@ -0,0 +1,79 @@ +Allowed Domains +=============== + +List Allowed Domains +-------------------- + +You can list all allowed domains using a load balancer service object. +An instance of ``OpenCloud\Common\Collection\PaginatedIterator`` is +returned. + +.. code-block:: php + + $allowedDomains = $service->allowedDomainList(); + + foreach ($allowedDomains as $allowedDomain) { + /** @var $allowedDomain OpenCloud\LoadBalancer\Resource\AllowedDomain **/ + } + + +Access Lists +============ + +Access Lists allow fine-grained network access to a load balancer's VIP. Using +access lists, network traffic to a load balancer's VIP can be allowed or denied +from a single IP address, multiple IP addresses or entire network subnets. + +Note that ``ALLOW`` network items will take precedence over ``DENY`` network +items in an access list. + +To reject traffic from all network items except those with the ``ALLOW`` +type, add a ``DENY`` network item with the address of ``0.0.0.0/0``. + +.. include:: lb-setup.sample.rst + + +View Access List +---------------- + +You can view a load balancer's access list: + +.. code-block:: php + + $accessList = $loadBalancer->accessList(); + + foreach ($accessList as $networkItem) { + /** @var $networkItem OpenCloud\LoadBalancer\Resource\Access **/ + } + + +Add Network Items To Access List +-------------------------------- + +You can add network items to a load balancer's access list very easily: + +.. code-block:: php + + $loadBalancer->createAccessList(array( + (object) array( + 'type' => 'ALLOW', + 'address' => '206.160.165.1/24' + ), + (object) array( + 'type' => 'DENY', + 'address' => '0.0.0.0/0' + ) + )); + +In the above example, we allowed access for 1 IP address, and used the +"0.0.0.0" wildcard to blacklist all other traffic. + + +Remove Network Item From Access List +------------------------------------ + +You an remove a network item from a load balancer's access list: + +.. code-block:: php + + $networkItem->delete(); diff --git a/doc/services/load-balancer/caching.rst b/doc/services/load-balancer/caching.rst new file mode 100644 index 000000000..6678e048a --- /dev/null +++ b/doc/services/load-balancer/caching.rst @@ -0,0 +1,35 @@ +Content Caching +=============== + +When content caching is enabled on a load balancer, recently-accessed files are +stored on the load balancer for easy retrieval by web clients. Requests to the +load balancer for these files are serviced by the load balancer itself, which +reduces load off its back-end nodes and improves response times as well. + + +.. include:: lb-setup.sample.rst + + +Check Configuration +------------------- + +.. code-block:: php + + // TRUE if enabled, FALSE if not + $contentCaching = $loadBalancer->hasContentCaching(); + + +Enable Content Caching +---------------------- + +.. code-block:: php + + $loadBalancer->enableContentCaching(true); + + +Disable Content Caching +----------------------- + +.. code-block:: php + + $loadBalancer->enableContentCaching(false); diff --git a/doc/services/load-balancer/errors.rst b/doc/services/load-balancer/errors.rst new file mode 100644 index 000000000..041c19d45 --- /dev/null +++ b/doc/services/load-balancer/errors.rst @@ -0,0 +1,44 @@ +Error Pages +=========== + +.. include:: lb-setup.sample.rst + +An error page is the html file that is shown to the end user when an error in +the service has been thrown. By default every virtual server is provided with +the default error file. It is also possible to set a custom error page for a +load balancer. + + +View Error Page Content +----------------------- + +.. code-block:: php + + $errorPage = $loadBalancer->errorPage(); + $errorPageContent = $errorPage->content; + + /** @var $errorPageContent string **/ + +In the example above the value of ``$errorPageContent`` is the HTML for +that page. This could either be the HTML of the default error page or of +your custom error page. + + +Set Custom Error Page +--------------------- + +.. code-block:: php + + $errorPage = $loadBalancer->errorPage(); + $errorPage->update(array( + 'content' => '' + )); + + +Delete Custom Error Page +------------------------ + +.. code-block:: php + + $errorPage = $loadBalancer->errorPage(); + $errorPage->delete(); diff --git a/doc/services/load-balancer/index.rst b/doc/services/load-balancer/index.rst new file mode 100644 index 000000000..9ea7614ad --- /dev/null +++ b/doc/services/load-balancer/index.rst @@ -0,0 +1,96 @@ +Load Balancer v1 +================ + +.. include:: ../common/rs-only.sample.rst + + +Load Balancer service +~~~~~~~~~~~~~~~~~~~~~ + +Now to instantiate the Load Balancer service: + +.. code-block:: php + + $service = $client->loadBalancerService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + load-balancer + nodes + virtual-ips + access + caching + errors + logging + monitors + metadata + sessions + ssl + stats + + +Glossary +-------- + + allowed domain + Allowed domains are a restricted set of domain names that are allowed to add + load balancer nodes. + + content caching + When content caching is enabled on a load balancer, recently-accessed files + are stored on the load balancer for easy retrieval by web clients. Requests to + the load balancer for these files are serviced by the load balancer itself, + which reduces load off its back-end nodes and improves response times as well. + + health monitor + The load balancing service includes a health monitoring operation which + periodically checks your back-end nodes to ensure they are responding + correctly. If a node is not responding, it is removed from rotation until the + health monitor determines that the node is functional. In addition to being + performed periodically, the health check also is performed against every node + that is added to ensure that the node is operating properly before allowing it + to service traffic. Only one health monitor is allowed to be enabled on a load + balancer at a time. + + load balancer + A load balancer is a device that distributes incoming network + traffic amongst multiple back-end systems. These back-end systems are + called the nodes of the load balancer. + + metadata + Metadata can be associated with each load balancer and each node for the + client's personal use. It is defined using key-value pairs where the key + and value consist of alphanumeric characters. A key is unique per load + balancer. + + node + A node is a backend device that provides a service on specified IP and port. + An example of a load balancer node might be a web server serving HTTP + traffic on port 8080. A load balancer typically has multiple nodes attached + to it so it can distribute incoming network traffic amongst them. + + session persistence + Session persistence is a feature of the load balancing service that forces + multiple requests, of the same protocol, from clients to be directed to the + same node. This is common with many web applications that do not inherently + share application state between back-end servers. + + virtual IP + A virtual IP (VIP) makes a load balancer accessible by clients. The + load balancing service supports either a public VIP address + (``PUBLIC``), routable on the public Internet, or a ServiceNet VIP + address (``SERVICENET``), routable only within the region in which the + load balancer resides. + + +Further Links +------------- + +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/load-balancer/lb-setup.sample.rst b/doc/services/load-balancer/lb-setup.sample.rst new file mode 100644 index 000000000..d82c80a1f --- /dev/null +++ b/doc/services/load-balancer/lb-setup.sample.rst @@ -0,0 +1,9 @@ +Setup +----- + +In order to interact with this feature you must first retrieve a particular +load balancer, like so: + +.. code-block:: php + + $loadBalancer = $service->loadBalancer('{id}'); diff --git a/doc/services/load-balancer/load-balancer.rst b/doc/services/load-balancer/load-balancer.rst new file mode 100644 index 000000000..7071794df --- /dev/null +++ b/doc/services/load-balancer/load-balancer.rst @@ -0,0 +1,165 @@ +Load Balancer +============= + +.. note:: + + Many of the examples in this document use two cloud servers as nodes for + the load balancer. The variables ``$serverOne`` and ``$serverTwo`` refer + to these two cloud servers. + + +Create Load Balancer +-------------------- + +The first step is to instantiate an empty object, like so: + +.. code-block:: php + + $loadBalancer = $service->loadBalancer(); + +In essence, all a load balancer does is evenly distribute traffic between +various back-end nodes - which can be Compute or Database instances. So we will +need to add a few when creating our load balancer: + +.. code-block:: php + + $serverOneNode = $loadBalancer->node(); + $serverOneNode->address = $serverOne->addresses->private[0]->addr; + $serverOneNode->port = 8080; + $serverOneNode->condition = 'ENABLED'; + + $serverTwoNode = $loadBalancer->node(); + $serverTwoNode->address = $serverTwo->addresses->private[0]->addr; + $serverTwoNode->port = 8080; + $serverTwoNode->condition = 'ENABLED'; + + +All that remains is apply final configuration touches, such as name and the +port number, before submitting to the API: + +.. code-block:: php + + $loadBalancer->addVirtualIp('PUBLIC'); + $loadBalancer->create(array( + 'name' => 'My load balancer', + 'port' => 80, + 'protocol' => 'HTTP', + 'nodes' => array($serverOneNode, $serverTwoNode), + 'algorithm' => 'ROUND_ROBIN', + )); + +For a full list of available `protocols <#protocols>`_ and `algorithms <#algorithms>`_ +please see the sections below. + + +List Load Balancer Details +-------------------------- + +You can retrieve a single load balancer's details by using its ID: + +.. code-block:: php + + /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ + $loadBalancer = $service->loadBalancer('{loadBalancerId}'); + + +List Load Balancers +~~~~~~~~~~~~~~~~~~~ + +You can retrieve a list of all your load balancers: + +.. code-block:: php + + $loadBalancers = $service->loadBalancerList(); + + foreach ($loadBalancers as $loadBalancer) { + /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ + } + + +Update a Load Balancer +---------------------- + +You can update one or more of the following load balancer attributes: + +- ``name``: The name of the load balancer +- ``algorithm``: The algorithm used by the load balancer to distribute + traffic amongst its nodes. See also: `Load balancing + algorithms <#algorithms>`__. +- ``protocol``: The network protocol used by traffic coming in to the + load balancer. See also: `Protocols <#protocols>`__. +- ``port``: The network port on which the load balancer listens for + incoming traffic. +- ``halfClosed``: Enable or Disable Half-Closed support for the load + balancer. +- ``timeout``: The timeout value for the load balancer to communicate + with its nodes. +- ``httpsRedirect``: Enable or disable HTTP to HTTPS redirection for + the load balancer. When enabled, any HTTP request will return status + code 301 (Moved Permanently), and the requestor will be redirected to + the requested URL via the HTTPS protocol on port 443. For example, + http://example.com/page.html would be redirected to https:// + example.com/page.html. Only available for HTTPS protocol (``port`` = + 443), or HTTP Protocol with a properly configured SSL Termination + (\`secureTrafficOnly=true, securePort=443). See also: `SSL + Termination <#ssl-termination>`__. + +.. code-block:: php + + $loadBalancer->update(array( + 'name' => 'New name', + 'algorithm' => 'ROUND_ROBIN' + )); + + +Remove Load Balancer +~~~~~~~~~~~~~~~~~~~~ + +When you no longer have a need for the load balancer, you can remove it: + +.. code-block:: php + + $loadBalancer->delete(); + + +Protocols +--------- + +When a load balancer is created a network protocol must be specified. +This network protocol should be based on the network protocol of the +back-end service being load balanced. Common protocols are ``HTTP``, ``HTTPS`` +and ``MYSQL``. A full list is available `here `_. + +List Load Balancing Protocols +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can list all supported network protocols like so: + +.. code-block:: php + + $protocols = $service->protocolList(); + + foreach ($protocols as $protocol) { + /** @var $protocol OpenCloud\LoadBalancer\Resource\Protocol **/ + } + + +Algorithms +---------- + +Load balancers use an **algorithm** to determine how incoming traffic is +distributed amongst the back-end nodes. A full list is available `here +`_. + +List Load Balancing Algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can programmatically list all supported load balancing algorithms: + +.. code-block:: php + + $algorithms = $service->algorithmList(); + + foreach ($algorithms as $algorithm) { + /** @var $algorithm OpenCloud\LoadBalancer\Resource\Algorithm **/ + } diff --git a/doc/services/load-balancer/logging.rst b/doc/services/load-balancer/logging.rst new file mode 100644 index 000000000..29c37aee2 --- /dev/null +++ b/doc/services/load-balancer/logging.rst @@ -0,0 +1,33 @@ +Connection Logging +================== + +The connection logging feature allows logs to be delivered to a Cloud Files +account every hour. For HTTP-based protocol traffic, these are Apache-style +access logs. For all other traffic, this is connection and transfer logging. + +.. include:: lb-setup.sample.rst + + +Check Configuration +------------------- + +.. code-block:: php + + // TRUE if enabled, FALSE if not + $connectionLogging = $loadBalancer->hasConnectionLogging(); + + +Enable Connection Logging +------------------------- + +.. code-block:: php + + $loadBalancer->enableConnectionLogging(true); + + +Disable Connection Logging +-------------------------- + +.. code-block:: php + + $loadBalancer->enableConnectionLogging(false); diff --git a/doc/services/load-balancer/metadata.rst b/doc/services/load-balancer/metadata.rst new file mode 100644 index 000000000..2b38de129 --- /dev/null +++ b/doc/services/load-balancer/metadata.rst @@ -0,0 +1,46 @@ +Metadata +======== + +.. include:: lb-setup.sample.rst + +List metadata +------------- + +.. code-block:: php + + $metadataList = $loadBalancer->metadataList(); + + foreach ($metadataList as $metadataItem) { + printf("Key: %s, Value: %s", $metadataItem->key, $metadataItem->value); + } + + +Add metadata +------------ + +.. code-block:: php + + $metadataItem = $loadBalancer->metadata(); + $metadataItem->create(array( + 'key' => 'foo', + 'value' => 'bar' + )); + + +Modify metadata +--------------- + +.. code-block:: php + + $metadataItem = $loadBalancer->metadata('foo'); + $metadataItem->update(array( + 'value' => 'baz' + )); + + +Remove metadata +--------------- + +.. code-block:: php + + $metadataItem->delete(); diff --git a/doc/services/load-balancer/monitors.rst b/doc/services/load-balancer/monitors.rst new file mode 100644 index 000000000..9c463f270 --- /dev/null +++ b/doc/services/load-balancer/monitors.rst @@ -0,0 +1,43 @@ +Health Monitors +=============== + +.. include:: lb-setup.sample.rst + +Retrieve monitor details +------------------------ + +.. code-block:: php + + /** @var $healthMonitor OpenCloud\LoadBalancer\Resource\HealthMonitor **/ + + $healthMonitor = $loadBalancer->healthMonitor(); + + printf( + "Monitoring type: %s, delay: %s, timeout: %s, attempts before deactivation: %s", + $healthMonitor->type, $healthMonitor->delay, $healthMonitor->timeout + ); + +For a full list, with explanations, of required and optional attributes, +please consult the `official +documentation `__ + + +Update monitor +-------------- + +.. code-block:: php + + $healthMonitor->update(array( + 'delay' => 120, + 'timeout' => 60, + 'type' => 'CONNECT' + 'attemptsBeforeDeactivation' => 3 + )); + + +Delete monitor +-------------- + +.. code-block:: php + + $healthMonitor->delete(); diff --git a/doc/services/load-balancer/nodes.rst b/doc/services/load-balancer/nodes.rst new file mode 100644 index 000000000..dfaadc404 --- /dev/null +++ b/doc/services/load-balancer/nodes.rst @@ -0,0 +1,124 @@ +Nodes +===== + +.. include:: lb-setup.sample.rst + +List Nodes +---------- + +You can list the nodes attached to a load balancer: + +.. code-block:: php + + $nodes = $loadBalancer->nodeList(); + + foreach ($nodes as $node) { + /** @var $node OpenCloud\LoadBalancer\Resource\Node **/ + } + + +Add Nodes +--------- + +You can attach additional nodes to a load balancer. Assume +``$loadBalancer`` already has two nodes attached to it - ``$serverOne`` +and ``$serverTwo`` - and you want to attach a third node to it, say +``$serverThree``, which provides a service on port 8080. + +**Important:** Remember to call ``$loadBalancer->addNodes()`` after all +the calls to ``$loadBalancer->addNode()`` as shown below. + +.. code-block:: php + + $address = $serverThree->addresses->private[0]->addr; + $loadBalancer->addNode($address, 8080); + $loadBalancer->addNodes(); + + +The signature for ``addNodes`` is as follows: + +.. function:: addNodes($address, $port[, $condition = 'ENABLED'[, $type = null[, $weight = null]]]) + + Add a node to a load balancer + + :param string $address: the IP address of the node + :param integer $port: the port number of the node + :param string $condition: the initial condition of the code. Defaults to ``ENABLED`` + :param string $type: either ``PRIMARY`` or ``SECONDARY`` + :param integer $weight: the node weight (for round-robin algorithm) + +The ``addNode`` method accepts three more optional parameters, in +addition to the two shown above: + +Modify Nodes +------------ + +You can modify one or more of the following node attributes: + +- ``condition``: The condition of the load balancer: + + - ``ENABLED`` – Node is ready to receive traffic from the load + balancer. + - ``DISABLED`` – Node should not receive traffic from the load + balancer. + - ``DRAINING`` – Node should process any traffic it is already + receiving but should not receive any further traffic from the load + balancer. + +- ``type``: The type of the node: + + - ``PRIMARY`` – Nodes defined as PRIMARY are in the normal rotation + to receive traffic from the load balancer. + - ``SECONDARY`` – Nodes defined as SECONDARY are only in the + rotation to receive traffic from the load balancer when all the + primary nodes fail. + +- ``weight``: The weight, between 1 and 100, given to node when + distributing traffic using either the ``WEIGHTED_ROUND_ROBIN`` or the + ``WEIGHTED_LEAST_CONNECTIONS`` load balancing algorithm. + +.. code-block:: php + + use OpenCloud\LoadBalancer\Enum\NodeCondition; + use OpenCloud\LoadBalancer\Enum\NodeType; + + $node->update(array( + 'condition' => NodeCondition::DISABLED, + 'type' => NodeType::SECONDARY + )); + + +Remove Nodes +------------ + +There are two ways to remove a node. The first way is on an +``OpenCloud\LoadBalancer\Resource\Node`` instance, like so: + + +.. code-block:: php + + $node->delete(); + +The second is with an ``OpenCloud\LoadBalancer\Resource\LoadBalancer`` +instance and the node's ID, like so: + +.. code-block:: php + + $loadBalancer->removeNode('{nodeId}'); + +where '{nodeId}' is the integer ID of the node itself - this is a required value. + + +View Node Service Events +------------------------ + +You can view events associated with the activity between a node and a +load balancer: + +.. code-block:: php + + $nodeEvents = $loadBalancer->nodeEventList(); + + foreach ($nodeEvents as $nodeEvent) { + /** @var $nodeEvent OpenCloud\LoadBalancer\Resource\NodeEvent **/ + } diff --git a/doc/services/load-balancer/sessions.rst b/doc/services/load-balancer/sessions.rst new file mode 100644 index 000000000..3d7f71cfe --- /dev/null +++ b/doc/services/load-balancer/sessions.rst @@ -0,0 +1,53 @@ +Session Persistence +=================== + +There are two types (or modes) of session persistence: + ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Name | Description | ++===================+===================================================================================================================================================================================================================================+ +| ``HTTP_COOKIE`` | A session persistence mechanism that inserts an HTTP cookie and is used to determine the destination back-end node. This is supported for HTTP load balancing only. | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``SOURCE_IP`` | A session persistence mechanism that will keep track of the source IP address that is mapped and is able to determine the destination back-end node. This is supported for HTTPS pass-through and non-HTTP load balancing only. | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. include:: lb-setup.sample.rst + + +List Session Persistence Configuration +-------------------------------------- + +.. code-block:: php + + $sessionPersistence = $loadBalancer->sessionPersistence(); + + /** @var $sessionPersistenceType null | 'HTTP_COOKIE' | 'SOURCE_IP' **/ + $sessionPersistenceType = $sessionPersistence->persistenceType; + +In the example above: + +- If session persistence is enabled, the value of + ``$sessionPersistenceType`` is the type of session persistence: + either ``HTTP_COOKIE`` or ``SOURCE_IP``. +- If session persistence is disabled, the value of + ``$sessionPersistenceType`` is ``null``. + + +Enable Session Persistence +-------------------------- + +.. code-block:: php + + $sessionPersistence = $loadBalancer->sessionPersistence(); + $sessionPersistence->update(array( + 'persistenceType' => 'HTTP_COOKIE' + )); + + +Disable Session Persistence +--------------------------- + +.. code-block:: php + + $sessionPersistence = $loadBalancer->sessionPersistence(); + $sessionPersistence->delete(); diff --git a/doc/services/load-balancer/ssl.rst b/doc/services/load-balancer/ssl.rst new file mode 100644 index 000000000..12b28a6af --- /dev/null +++ b/doc/services/load-balancer/ssl.rst @@ -0,0 +1,52 @@ +SSL Termination +=============== + +The SSL Termination feature allows a load balancer user to terminate SSL +traffic at the load balancer layer versus at the web server layer. A +user may choose to configure SSL Termination using a key and an SSL +certificate or an (Intermediate) SSL certificate. + +When SSL Termination is configured on a load balancer, a secure shadow +server is created that listens only for secure traffic on a +user-specified port. This shadow server is only visible to and +manageable by the system. Existing or updated attributes on a load +balancer with SSL Termination will also apply to its shadow server. For +example, if Connection Logging is enabled on an SSL load balancer, it +will also be enabled on the shadow server and Cloud Files logs will +contain log files for both. + +.. include:: lb-setup.sample.rst + + +View configuration +------------------ + +.. code-block:: php + + /** @var $sslConfig OpenCloud\LoadBalancer\Resource\SSLTermination **/ + $sslConfig = $loadBalancer->SSLTermination(); + + +Update configuration +-------------------- + +.. code-block:: php + + $sslConfig->update(array( + 'enabled' => true, + 'securePort' => 443, + 'privateKey' => $key, + 'certificate' => $cert + )); + +For a full list, with explanations, of required and optional attributes, +please consult the `official +documentation `__ + + +Delete configuration +-------------------- + +.. code-block:: php + + $sslConfig->delete(); diff --git a/doc/services/load-balancer/stats.rst b/doc/services/load-balancer/stats.rst new file mode 100644 index 000000000..65077643f --- /dev/null +++ b/doc/services/load-balancer/stats.rst @@ -0,0 +1,59 @@ +Statistics and Usage Reports +============================ + +.. include:: lb-setup.sample.rst + +Retrieve LB stats +----------------- + +You can retrieve detailed stats about your load balancer, including the +following information: + +- ``connectTimeOut`` – Connections closed by this load balancer because + the 'connect_timeout' interval was exceeded. +- ``connectError`` – Number of transaction or protocol errors in this + load balancer. +- ``connectFailure`` – Number of connection failures in this load balancer. +- ``dataTimedOut`` – Connections closed by this load balancer because + the 'timeout' interval was exceeded. +- ``keepAliveTimedOut`` – Connections closed by this load balancer + because the 'keepalive_timeout' interval was exceeded. +- ``maxConn`` – Maximum number of simultaneous TCP connections this + load balancer has processed at any one time. + +.. code-block:: php + + /** @var $stats OpenCloud\LoadBalancer\Resource\Stats **/ + $stats = $loadBalancer->stats(); + + +Usage Reports +------------- + +The load balancer usage reports provide a view of all transfer activity, +average number of connections, and number of virtual IPs associated with +the load balancing service. Current usage represents all usage recorded +within the preceding 24 hours. Values for both incomingTransfer and +outgoingTransfer are expressed in bytes transferred. + +The optional startTime and endTime parameters can be used to filter all +usage. If the startTime parameter is supplied but the endTime parameter +is not, then all usage beginning with the startTime will be provided. +Likewise, if the endTime parameter is supplied but the startTime +parameter is not, then all usage will be returned up to the endTime +specified. + +.. code-block:: php + + # View billable LBs + $billable = $service->billableLoadBalancerList(); + + foreach ($billable as $loadBalancer) { + /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ + + # View usage + /** @var $usage OpenCloud\LoadBalancer\Resource\UsageRecord **/ + $usage = $loadBalancer->usage(); + + echo $usage->averageNumConnections, PHP_EOL; + } diff --git a/doc/services/load-balancer/virtual-ips.rst b/doc/services/load-balancer/virtual-ips.rst new file mode 100644 index 000000000..fa0add613 --- /dev/null +++ b/doc/services/load-balancer/virtual-ips.rst @@ -0,0 +1,74 @@ +Virtual IPs +=========== + +.. include:: lb-setup.sample.rst + + +List Virtual IPs +---------------- + +You can list the VIPs associated with a load balancer like so: + +.. code-block:: php + + $vips = $loadBalancer->virtualIpList(); + + foreach ($vips as $vip) { + /** @var $vip of OpenCloud\LoadBalancer\Resource\VirtualIp **/ + } + + +Get existing VIP +---------------- + +To retrieve the details of an existing VIP on a load balancer, you will need +its ID: + +.. code-block:: + + $vip = $loadBalancer->virtualIp('{virtualIpId}'); + + +Add Virtual IPv6 +---------------- + +You can add additional IPv6 VIPs to a load balancer using the following method: + +.. code-block:: php + + use OpenCloud\LoadBalancer\Enum\IpType; + + $loadBalancer->addVirtualIp(IpType::PUBLIC, 6); + +the first argument is the type of network your IP address will server traffic in +- and can either be ``PUBLIC`` or ``PRIVATE``. The second argument is the version +of IP address, either ``4`` or ``6``. + + +Add Virtual IPv4 +---------------- + +Similar to above: + +.. code-block:: php + + use OpenCloud\LoadBalancer\Enum\IpType; + + $loadBalancer->addVirtualIp(IpType::PUBLIC, 4); + + +Remove Virtual IP +----------------- + +You can remove a VIP from a load balancer. + +.. code-block:: php + + $vip->remove(); + + +.. note:: + + A load balancer must have at least one VIP associated with it. If you try to + remove a load balancer's last VIP, a ``ClientErrorResponseException`` will be + thrown. diff --git a/doc/services/monitoring/agents.rst b/doc/services/monitoring/agents.rst new file mode 100644 index 000000000..f4c673608 --- /dev/null +++ b/doc/services/monitoring/agents.rst @@ -0,0 +1,188 @@ +Agents +====== + +The Monitoring Agent resides on the host server being monitored. The +agent allows you to gather on-host metrics based on agent checks and +push them to Cloud Monitoring where you can analyze them, use them with +the Cloud Monitoring infrastructure (such as alarms), and archive them. + +For more information about this feature, including a brief overview of +its core design principles and security layers, see the `official API +documentation `__. + +Retrieve details about an agent +------------------------------- + +.. code-block:: php + + $agent = $service->getAgent('{agentId}'); + + +List agents +----------- + +.. code-block:: php + + $agents = $service->getAgents(); + + foreach ($agents as $agent) { + echo $agent->getLastConnected(); + } + + +List connections +---------------- + +.. code-block:: php + + $connections = $agent->getConnections(); + + +Get connection +-------------- + +.. code-block:: php + + /** @var \OpenCloud\CloudMonitoring\Resource\AgentConnection */ + $connection = $agent->getConnection('{connectionId}'); + + +Once you have access to an agent's ``OpenCloud\CloudMonitoring\Resource\AgentConnection`` +object, these are the attributes you can access: + ++--------------------+---------------------------+ +| Name | Method | ++====================+===========================+ +| id | ``getId()`` | ++--------------------+---------------------------+ +| guid | ``getGuid()`` | ++--------------------+---------------------------+ +| agent_id | ``getAgentId()`` | ++--------------------+---------------------------+ +| endpoint | ``getEndpoint()`` | ++--------------------+---------------------------+ +| process_version | ``getProcessVersion()`` | ++--------------------+---------------------------+ +| bundle_version | ``getBundleVersion()`` | ++--------------------+---------------------------+ +| agent_ip | ``getAgentIp()`` | ++--------------------+---------------------------+ + +Agent tokens +============ + +Agent tokens are used to authenticate Monitoring agents to the +Monitoring Service. Multiple agents can share a single token. + +Retrieve an agent token +----------------------- + +.. code-block:: php + + $agentToken = $service->getAgentToken('{tokenId}'); + + +Create agent token +------------------ + +.. code-block:: php + + $newToken = $service->getAgentToken(); + $newToken->create(array('label' => 'Foobar')); + + +List agent tokens +----------------- + +.. code-block:: php + + $agentTokens = $service->getAgentTokens(); + + foreach ($agentTokens as $token) { + echo $token->getLabel(); + } + + +Update agent token +------------------ + +.. code-block:: php + + $token->update(array( + 'label' => 'New label' + )); + + +Update agent token +------------------ + +.. code-block:: php + + $token->delete(); + + +Agent Host Information +====================== + +An agent can gather host information, such as process lists, network +configuration, and memory usage, on demand. You can use the +host-information API requests to gather this information for use in +dashboards or other utilities. + +Setup +----- + +.. code-block:: php + + $host = $service->getAgentHost(); + + +Get some metrics +---------------- + +.. code-block:: php + + $cpuInfo = $host->info('cpus'); + $diskInfo = $host->info('disks'); + $filesystemInfo = $host->info('filesystems'); + $memoryInfo = $host->info('memory'); + $networkIntInfo = $host->info('network_interfaces'); + $processesInfo = $host->info('processes'); + $systemInfo = $host->info('system'); + $userInfo = $host->info('who'); + + // What CPU models do we have? + foreach ($cpuInfo as $cpuMetric) { + echo $cpuMetric->model, PHP_EOL; + } + + // How many disks do we have? + echo $diskInfo->count(); + + // What's the available space on our ext4 filesystem? + foreach ($filesystemInfo as $filesystemMetric) { + if ($filesystemMetric->sys_type_name == 'ext4') { + echo $filesystemMetric->avail; + } + } + +Agent targets +============= + +Each agent check type gathers data for a related set of target devices +on the server where the agent is installed. For example, +``agent.network`` gathers data for network devices. The actual list of +target devices is specific to the configuration of the host server. By +focusing on specific targets, you can efficiently narrow the metric data +that the agent gathers. + +List agent targets +------------------ + +.. code-block:: php + + $targets = $service->getAgentTargets(); + + foreach ($targets as $target) { + echo $target->getType(); + } diff --git a/doc/services/monitoring/alarms.rst b/doc/services/monitoring/alarms.rst new file mode 100644 index 000000000..297a57407 --- /dev/null +++ b/doc/services/monitoring/alarms.rst @@ -0,0 +1,99 @@ +Alarms +====== + +Alarms bind alerting rules, entities, and notification plans into a +logical unit. Alarms are responsible for determining a state (``OK``, +``WARNING`` or ``CRITICAL``) based on the result of a Check, and +executing a notification plan whenever that state changes. You create +alerting rules by using the alarm DSL. For information about using the +alarm language, refer to the `reference +documentation `__. + +Setup +----- + +In order to interact with this feature, you must first retrieve an entity by +its ID: + +.. code-block:: php + + $entity = $service->getEntity('{entityId}'); + +and then a particular check, about which you can configure alarms: + +.. code-block:: php + + $check = $entity->getCheck('{checkId}'); + +For more information about these resource types, please consult the documentation +about `entities `_ and `checks `_. + +Retrieve alarm +-------------- + +.. code-block:: php + + $alarm = $check->getAlarm('{alarmId}'); + + +Once you have access to a ``OpenCloud\Monitoring\Resource\Alarm`` object, these +are the attributes you can access: + ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| Name | Description | Required? | Method | ++==========================+=============================================================================+=============+=================================+ +| check_id | The ID of the check to alert on. | Required | ``getCheckId()`` | ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| notification_plan_id | The ID of the notification plan to execute when the state changes. | Optional | ``getNotificationPlanId()`` | ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| criteria | The alarm DSL for describing alerting conditions and their output states. | Optional | ``getCriteria()`` | ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| disabled | Disable processing and alerts on this alarm | Optional | ``isDisabled()`` <``bool``\ > | ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| label | A friendly label for an alarm. | Optional | ``getLabel()`` | ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| metadata | Arbitrary key/value pairs. | Optional | ``getMetadata()`` | ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ + + +Create Alarm +------------ + +.. code-block:: php + + $alarm = $check->getAlarm(); + $alarm->create(array( + 'check_id' => 'chAAAA', + 'criteria' => 'if (metric["duration"] >= 2) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);', + 'notification_plan_id' => 'npAAAAA' + )); + + +List Alarms +----------- + +.. code-block:: php + + $alarms = $entity->getAlarms(); + + foreach ($alarms as $alarm) { + echo $alarm->getId(); + } + + +Update Alarm +------------ + +.. code-block:: php + + $alarm->update(array( + 'criteria' => 'if (metric["duration"] >= 5) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);' + )); + + +Delete alarm +------------ + +.. code-block:: php + + $alarm->delete(); diff --git a/doc/services/monitoring/changelogs.rst b/doc/services/monitoring/changelogs.rst new file mode 100644 index 000000000..a6b26af25 --- /dev/null +++ b/doc/services/monitoring/changelogs.rst @@ -0,0 +1,18 @@ +Changelogs +========== + +The monitoring service records changelogs for alarm statuses. Changelogs +are accessible as a Time Series Collection. By default the API queries +the last 7 days of changelog information. + + +View Changelog +-------------- + +.. code-block:: php + + $changelog = $service->getChangelog(); + + foreach ($changelog as $item) { + $entity = $item->getEntityId(); + } diff --git a/doc/services/monitoring/checks.rst b/doc/services/monitoring/checks.rst new file mode 100644 index 000000000..73474c170 --- /dev/null +++ b/doc/services/monitoring/checks.rst @@ -0,0 +1,228 @@ +Checks +====== + + +A check is one of the foundational building blocks of the monitoring +system. The check determines the parts or pieces of the entity that you +want to monitor, the monitoring frequency, how many monitoring zones are +originating the check, and so on. When you create a new check in the +monitoring system, you specify the following information: + +- A name for the check +- The check's parent entity +- The type of check you're creating +- Details of the check +- The monitoring zones that will launch the check + +The check, as created, will not trigger alert messages until you create +an alarm to generate notifications, to enable the creation of a single +alarm that acts upon multiple checks (e.g. alert if any of ten different +servers stops responding) or multiple alarms off of a single check. +(e.g. ensure both that a HTTPS server is responding and that it has a +valid certificate). + +Create a check +-------------- + +There are various attributes available to you when creating a new monitoring +check: + +.. code-block:: php + + $params = array( + 'type' => 'remote.http', + 'details' => array( + 'url' => 'http://example.com', + 'method' => 'GET' + ), + 'monitoring_zones_poll' => array('mzlon'), + 'period' => '100', + 'timeout' => '30', + 'target_alias' => 'default', + 'label' => 'Website check 1' + ); + +For a full list of available attributes, consult the list below. + +Attributes +~~~~~~~~~~ + ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| Name | Description | Required? | Data type | ++============+=============================================================================================================+=============+==========================================+ +| type | The type of check. | Required | Valid check type. String (1..25 chars) | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| details | Details specific to the check type. | Optional | Array | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| disabled | Disables the check. | Optional | Boolean | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| label | A friendly label for a check. | Optional | String (1..255 chars) | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| metadata | Arbitrary key/value pairs. | Optional | Array | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| period | The period in seconds for a check. The value must be greater than the minimum period set on your account. | Optional | Integer (30..1800) | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ +| timeout | The timeout in seconds for a check. This has to be less than the period. | Optional | Integer (2..1800) | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ + +Optional attributes to be used with remote checks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------------------------+ +| Name | Description | Required? | Data type | ++===========================+========================================================================================================================================================+=============+============================================================+ +| monitoring_zones_poll | List of monitoring zones to poll from. Note: This argument is only required for remote (non-agent) checks | Optional | Array | ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------------------------+ +| target_alias | A key in the entity's ``ip_addresses`` hash used to resolve this check to an IP address. This parameter is mutually exclusive with target\_hostname. | Optional | String (1..64 chars) | ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------------------------+ +| target_hostname | The hostname this check should target. This parameter is mutually exclusive with ``target_alias``. | Optional | Valid FQDN, IPv4 or IPv6 address. String (1..256 chars). | ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------------------------+ +| target_resolver | Determines how to resolve the check target. | Optional | ``IPv4`` or ``IPv6`` | ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------------------------+ + + +Test parameters +--------------- + +Sometimes it can be useful to test out the parameters before sending them as a +create call. To do this, pass in the ``$params`` like so: + +.. code-block:: php + + $response = $entity->testNewCheckParams($params); + + echo $response->timestamp; // When was it executed? + echo $response->available; // Was it available? + echo $response->status; // Status code + + +Send parameters +~~~~~~~~~~~~~~~ + +Once you are satisfied with your configuration parameters, you can complete the +operation and send it to the API like so: + +.. code-block:: php + + $entity->createCheck($params); + + +Test existing Check +------------------- + +.. code-block:: php + + // Set arg to TRUE for debug information + $response = $check->test(true); + + echo $response->debug_info; + + +List Checks +----------- + +.. code-block:: php + + $checks = $entity->getChecks(); + + foreach ($checks as $check) { + echo $check->getId(); + } + + +Update Check +------------ + +.. code-block:: php + + $check->update(array('period' => 500)); + + +Delete check +------------ + +.. code-block:: php + + $check->delete(); + + +Check types +=========== + +Each check within the Rackspace Cloud Monitoring has a designated check +type. The check type instructs the monitoring system how to check the +monitored resource. **Note:** Users cannot create, update or delete +check types. + +Check types for commonly encountered web protocols, such as HTTP +(``remote.http``), IMAP (``remote.imap-banner``) , SMTP +(``remote.stmp``), and DNS (``remote.dns``) are provided. Monitoring +commonly encountered infrastructure servers like MySQL +(``remote.mysql-banner``) and PostgreSQL (``remote.postgresql-banner``) +are also available. Monitoring custom server uptime can be accomplished +with the remote.tcp banner check to check for a protocol-defined banner +at the beginning of a connection. Gathering metrics from server software +to create alerts against can be accomplished using the remote.http check +type and the 'extract' attribute to define the format. + +In addition to the standard Cloud Monitoring check types, you can also +use agent check types if the Monitoring Agent is installed on the server +you are monitoring. For a list of available check types, see the +`official API +documentation `__. + +Checks generate metrics that alarms will alert based upon. The metrics +generated often times depend on the check's parameters. For example, +using the 'extract' attribute on the remote.http check, however the +default metrics will always be present. To determine the exact metrics +available, the Test Check API is provided. + +Find an existing check's type +----------------------------- + +If you want to see the type for an existing Check resource: + +.. code-block:: php + + /** @var \OpenCloud\CloudMonitoring\Resource\CheckType */ + $checkType = $check->getCheckType(); + + +List all possible check types +----------------------------- + +.. code-block:: php + + $checkTypes = $service->getCheckTypes(); + + foreach ($checkTypes as $checkType) { + echo $checkType->getId(); + } + + +Retrieve details about a Type by its ID +--------------------------------------- + +Alternatively, you can retrieve a specific type based on its ID: + +.. code-block:: php + + $checkTypeId = 'remote.dns'; + $checkType = $service->getCheckType($checkTypeId); + + +Attributes +---------- + +Once you have access to a ``OpenCloud\CloudMonitoring\Resource\CheckType`` object, +you can query these attributes: + ++------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------------------+ +| Name | Description | Data type | Method | ++========================+==========================================================================================================================================================================================+=============+===============================+ +| type | The name of the supported check type. | String | ``getType()`` | ++------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------------------+ +| fields | Check type fields. | Array | ``getFields()`` | ++------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------------------+ +| supported_platforms | Platforms on which an agent check type is supported. This is advisory information only - the check may still work on other platforms, or report that check execution failed at runtime | Array | ``getSupportedPlatforms()`` | ++------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------------------+ diff --git a/doc/services/monitoring/entities.rst b/doc/services/monitoring/entities.rst new file mode 100644 index 000000000..7e4132af1 --- /dev/null +++ b/doc/services/monitoring/entities.rst @@ -0,0 +1,77 @@ + Entities +========= + +An entity is the target of what you are monitoring. For example, you can +create an entity to monitor your website, a particular web service, or +your Rackspace server. Note that an entity represents only one item in +the monitoring system -- if you wanted to monitor each server in a +cluster, you would create an entity for each of the servers. You would +not create a single entity to represent the entire cluster. + +An entity can have multiple checks associated with it. This allows you +to check multiple services on the same host by creating multiple checks +on the same entity, instead of multiple entities each with a single +check. + +Create Entity +------------- + +.. code-block:: php + + $service->createEntity(array( + 'label' => 'Brand New Entity', + 'ip_addresses' => array( + 'default' => '127.0.0.4', + 'b' => '127.0.0.5', + 'c' => '127.0.0.6', + 'test' => '127.0.0.7' + ), + 'metadata' => array( + 'all' => 'kinds', + 'of' => 'stuff', + 'can' => 'go', + 'here' => 'null is not a valid value' + ) + )); + + +Retrive an entity +----------------- + +.. code-block:: php + + $entity = $service->getEntity('{entityId}'); + + +Attributes +~~~~~~~~~~ + ++-----------------+-------------------------------------------------------------------------+-----------------------------------------------------+------------------------+ +| Name | Description | Data type | Method | ++=================+=========================================================================+=====================================================+========================+ +| label | Defines a name for the entity. | String (1..255 chars) | ``getLabel()`` | ++-----------------+-------------------------------------------------------------------------+-----------------------------------------------------+------------------------+ +| agent_id | Agent to which this entity is bound to. | String matching the regex: ``/^[-\.\w]{1,255}$/`` | ``getAgentId()`` | ++-----------------+-------------------------------------------------------------------------+-----------------------------------------------------+------------------------+ +| ip_addresses | Hash of IP addresses that can be referenced by checks on this entity. | Array | ``getIpAddresses()`` | ++-----------------+-------------------------------------------------------------------------+-----------------------------------------------------+------------------------+ +| metadata | Arbitrary key/value pairs that are passed during the alerting phase. | ``OpenCloud\Common\Metadata`` | ``getMetadata()`` | ++-----------------+-------------------------------------------------------------------------+-----------------------------------------------------+------------------------+ + + +Update an entity +---------------- + +.. code-block:: php + + $entity->update(array( + 'label' => 'New label for my entity' + )); + + +Delete entity +------------- + +.. code-block:: php + + $entity->delete(); diff --git a/doc/services/monitoring/index.rst b/doc/services/monitoring/index.rst new file mode 100644 index 000000000..0a7225e36 --- /dev/null +++ b/doc/services/monitoring/index.rst @@ -0,0 +1,97 @@ +Monitoring v1 +============= + +.. include:: ../common/rs-only.sample.rst + +Monitoring service +~~~~~~~~~~~~~~~~~~ + +Now to instantiate the Monitoring service: + +.. code-block:: php + + $service = $client->monitoringService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + +Operations +---------- + +.. toctree:: + + entities + checks + alarms + agents + changelogs + metrics + notifications + views + zones + +Glossary +-------- + +.. glossary:: + + agent + A monitoring daemon that resides on the server being monitored. The agent + gathers metrics based on agent checks and pushes them to Cloud Monitoring. + The agent provides insight into your servers with checks for information + such as load average and network usage. The agent acts as a single small + service that runs scheduled checks and pushes metrics to the rest of Cloud + Monitoring so the metrics can be analyzed, trigger alerts, and be archived. + These metrics are gathered via checks using agent check types, and can be + used with the other Cloud Monitoring primitives such as alarms. + + agent token + An authentication token used to identify the agent when it communicates + with Cloud Monitoring. + + alarm + An alarm contains a set of rules that determine when the monitoring system + sends a notification. You can create multiple alarms for the different + checks types associated with an entity. For example, if your entity is a + web server that hosts your company's website, you can create one alarm to + monitor the server itself, and another alarm to monitor the website. + + check + Checks explicitly specify how you want to monitor an entity. Once you've + created an entity, you can configure one or more checks for it. A check is + the foundational building block of the monitoring system, and is always + associated with an entity. The check specifies the parts or pieces of the + entity that you want to monitor, the monitoring frequency, how many + monitoring zones are launching the check, and so on. It contains the + specific details of how you are monitoring the entity. + + entity + The object or resource that you want to monitor. It can be any object or + device that you want to monitor. It's commonly a web server, but it might + also be a website, a web page or a web service. + + monitoring zone + A monitoring zone is the "launch point" of a check. When you create a + check, you specify which monitoring zone(s) you want to launch the check + from. This concept of a monitoring zone is similar to that of a datacenter, + however in the monitoring system, you can think of it more as a geographical + region. + + notification + A notification is an informational message sent to one or more addresses + by the monitoring system when an alarm is triggered. You can set up + notifications to alert a single individual or an entire team. Rackspace + Cloud Monitoring currently supports webhooks and email for sending + notifications. + + notification plan + A notification plan contains a set of notification rules to execute when an + alarm is triggered. A notification plan can contain multiple notifications + for each of the following states: + + +Further links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/monitoring/metrics.rst b/doc/services/monitoring/metrics.rst new file mode 100644 index 000000000..0b412a6a3 --- /dev/null +++ b/doc/services/monitoring/metrics.rst @@ -0,0 +1,143 @@ + Metrics +======== + +When Monitoring checks run, they generate metrics. These metrics are +stored as full resolution data points in the Cloud Monitoring system. +Full resolution data points are periodically rolled up (condensed) into +coarser data points. + +Depending on your needs, you can use the metrics API to fetch individual +data points (fine-grained) or rolled up data points (coarse-grained) +over a period of time. + + +Data Granularity +---------------- + +Cloud Monitoring supports several granularities of data: full resolution +data and rollups computed at 5, 20, 60, 240 and 1440 minute intervals. + +When you fetch metrics data points, you specify several parameters to +control the granularity of data returned: + +- A time range for the points +- Either the number of points you want returned OR the resolution of + the data you want returned + +When you query by points, the API selects the resolution that will +return you the number of points you requested. The API makes the +assumption of a 30 second frequency, performs the calculation, and +selects the appropriate resolution. + +**Note:** Because the API performs calculations to determine the points +returned for a particular resolution, the number of points returned may +differ from the specific number of points you request. + +Consider that you want to query data for a 48-hour time range between +the timestamps ``from=1354647221000`` and ``to=1358794421000`` ( +**specified in Unix time, based on the number of milliseconds that have +elapsed since January 1, 1970** ). The following table shows the number +of points that the API returns for a given resolution. + +Specifying resolution to retrieve data in 48 hour period +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++-----------------------------+-------------------------+ +| You specify resolution... | API returns points... | ++=============================+=========================+ +| FULL | 5760 | ++-----------------------------+-------------------------+ +| MIN5 | 576 | ++-----------------------------+-------------------------+ +| MIN20 | 144 | ++-----------------------------+-------------------------+ +| MIN60 | 48 | ++-----------------------------+-------------------------+ +| MIN240 | 12 | ++-----------------------------+-------------------------+ +| MIN1440 | 2 | ++-----------------------------+-------------------------+ + +Specifying number of points to retrieve data in 48 hour period +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++--------------------------------------+-----------------------------+ +| You specify points in the range... | API calculates resolution | ++======================================+=============================+ +| 3168-∞ | FULL | ++--------------------------------------+-----------------------------+ +| 360-3167 | MIN5 | ++--------------------------------------+-----------------------------+ +| 96-359 | MIN20 | ++--------------------------------------+-----------------------------+ +| 30-95 | MIN60 | ++--------------------------------------+-----------------------------+ +| 7-29 | MIN240 | ++--------------------------------------+-----------------------------+ +| 0-6 | MIN1440 | ++--------------------------------------+-----------------------------+ + +Data Point Expiration +~~~~~~~~~~~~~~~~~~~~~ + +Cloud Monitoring expires data points according to the following +schedule: + ++--------------+--------------+ +| Resolution | Expiration | ++==============+==============+ +| FULL | 2 days | ++--------------+--------------+ +| MIN5 | 7 days | ++--------------+--------------+ +| MIN20 | 15 days | ++--------------+--------------+ +| MIN60 | 30 days | ++--------------+--------------+ +| MIN240 | 60 days | ++--------------+--------------+ +| MIN1440 | 365 days | ++--------------+--------------+ + +Setup +------ + +In order to interact with this feature, you must first retrieve an entity by +its ID: + +.. code-block:: php + + $entity = $service->getEntity('{entityId}'); + +and then a particular check, about which you can configure alarms: + +.. code-block:: php + + $check = $entity->getCheck('{checkId}'); + +For more information about these resource types, please consult the documentation +about `entities `_ and `checks `_. + + +List all metrics +---------------- + +.. code-block:: php + + $metrics = $check->getMetrics(); + + foreach ($metrics as $metric) { + echo $metric->getName(); + } + + +Fetch data points +----------------- + +.. code-block:: php + + $data = $check->fetchDataPoints('mzdfw.available', array( + 'resolution' => 'FULL', + 'from' => 1369756378450, + 'to' => 1369760279018 + )); diff --git a/doc/services/monitoring/notifications.rst b/doc/services/monitoring/notifications.rst new file mode 100644 index 000000000..d7e289ad5 --- /dev/null +++ b/doc/services/monitoring/notifications.rst @@ -0,0 +1,319 @@ +Notifications +============= + +A notification is a destination to send an alarm; it can be a variety of +different types, and will evolve over time. + +For instance, with a webhook type notification, Cloud Monitoring posts +JSON formatted data to a user-specified URL on an alert condition (Check +goes from ``OK`` -> ``CRITICAL`` and so on). + +Get notification +---------------- + +.. code-block:: php + + $notification = $service->getNotification('{id}'); + +Once you have access to a ``OpenCloud\Monitoring\Resource\Notification`` object, +these are the attributes available for use: + ++-----------+---------------------------------------------------------------------------+-----------------------------------------------------------+--------------------+ +| Name | Description | Data type | Method | ++===========+===========================================================================+===========================================================+====================+ +| details | A hash of notification specific details based on the notification type. | Array | ``getDetails()`` | ++-----------+---------------------------------------------------------------------------+-----------------------------------------------------------+--------------------+ +| label | Friendly name for the notification. | String (1..255 chars) | ``getLabel()`` | ++-----------+---------------------------------------------------------------------------+-----------------------------------------------------------+--------------------+ +| type | The notification type to send. | String. Either ``webhook``, ``email``, or ``pagerduty`` | ``getType()`` | ++-----------+---------------------------------------------------------------------------+-----------------------------------------------------------+--------------------+ + +Creating notifications +---------------------- + +The first thing to do when creating a new notification is configure the +parameters which will define the behaviour of your resource: + +.. code-block:: php + + $params = array( + 'label' => 'My webhook #1', + 'type' => 'webhook', + 'details' => array( + 'url' => 'http://example.com' + ) + ); + + +Test parameters +~~~~~~~~~~~~~~~ + +Once this is done, it is often useful to test them out to check whether they +will result in a successful creation: + +.. code-block:: php + + // Test it + $response = $notification->testParams($params); + + if ($response->status == 'Success') { + echo $response->message; + } + + +Send parameters +~~~~~~~~~~~~~~~ + +When you're happy with the parameters you've defined, you can complete the +operation by sending them to the API like so: + +.. code-block:: php + + $notification->create($params); + + +Test existing notification +-------------------------- + +.. code-block:: php + + $response = $notification->testExisting(true); + echo $response->debug_info; + + +List Notifications +------------------ + +.. code-block:: php + + $notifications = $service->getNotifications(); + + foreach ($notifications as $notification) { + echo $notification->getId(); + } + + +Update a Notification +--------------------- + +.. code-block:: php + + $notification->update(array( + 'label' => 'New notification label' + )); + + +Delete a Notification +--------------------- + +.. code-block:: php + + $notification->delete(); + + +Notification types +================== + +Rackspace Cloud Monitoring currently supports the following notification types: + +Webhook +~~~~~~~ + +Industry-standard web hooks, where JSON is posted to a configurable URL. +It has these attributes: + ++-----------+------------------------------------------+---------------+ +| Name | Description | Data type | ++===========+==========================================+===============+ +| address | Email address to send notifications to | Valid email | ++-----------+------------------------------------------+---------------+ + +Email +~~~~~ + +Email alerts where the message is delivered to a specified address. It +has these attributes: + ++--------+-----------------------------------+-------------+ +| Name | Description | Data type | ++========+===================================+=============+ +| url | An HTTP or HTTPS URL to POST to | Valid URL | ++--------+-----------------------------------+-------------+ + + +Setup +----- + +If you've already set up a main Notification object, and want to access +functionality for this Notification's particular Notification Type, you +can access its property: + +.. code-block:: php + + $type = $notification->getNotificationType(); + +Alternatively, you can retrieve an independent resource using the ID: + +.. code-block:: php + + $typeId = 'pagerduty'; + $type = $service->getNotificationType($typeId); + + +List all possible notification types +------------------------------------ + +.. code-block:: php + + $types = $service->getNotificationTypes(); + + foreach ($types as $type) { + echo sprintf('%s %s', $type->getName(), $type->getDescription()); + } + + +Notification plans +================== + +A notification plan contains a set of notification actions that +Rackspace Cloud Monitoring executes when triggered by an alarm. +Rackspace Cloud Monitoring currently supports webhook and email +notifications. + +Each notification state can contain multiple notification actions. For +example, you can create a notification plan that hits a webhook/email to +notify your operations team if a warning occurs. However, if the warning +escalates to an Error, the notification plan could be configured to hit +a different webhook/email that triggers both email and SMS messages to +the operations team. The notification plan supports the following +states: + +- Critical +- Warning +- OK + +A notification plan, ``npTechnicalContactsEmail``, is provided by +default which will email all of the technical contacts on file for an +account whenever there is a state change. + +Get a notification plan +----------------------- + +.. code-block:: php + + $plan = $service->getNotificationPlan('{planId}'); + +Once you have access to a ``OpenCloud\\Monitoring\\Resource\\NotificationPlan`` +object, you can access these resources: + ++-------------------+--------------------------------------------------------------------+-------------+-------------------------+--------------------------+ +| Name | Description | Required? | Data type | Method | ++===================+====================================================================+=============+=========================+==========================+ +| label | Friendly name for the notification plan. | Required | String (1..255 chars) | ``getLabel()`` | ++-------------------+--------------------------------------------------------------------+-------------+-------------------------+--------------------------+ +| critical_state | The notification list to send to when the state is ``CRITICAL``. | Optional | Array | ``getCriticalState()`` | ++-------------------+--------------------------------------------------------------------+-------------+-------------------------+--------------------------+ +| ok_state | The notification list to send to when the state is ``OK``. | Optional | Array | ``getOkState()`` | ++-------------------+--------------------------------------------------------------------+-------------+-------------------------+--------------------------+ +| warning_state | The notification list to send to when the state is ``WARNING``. | Optional | Array | ``getWarningState()`` | ++-------------------+--------------------------------------------------------------------+-------------+-------------------------+--------------------------+ + +Create Notification Plan +------------------------ + +.. code-block:: php + + $plan->create(array( + 'label' => 'New Notification Plan', + 'critical_state' => array('ntAAAA'), + 'ok_state' => array('ntBBBB'), + 'warning_state' => array('ntCCCC') + )); + + +Update notification plan +------------------------ + +.. code-block:: php + + $plan->update(array( + 'label' => 'New label for my plan' + )); + + +Delete notification plan +------------------------ + +.. code-block:: php + + $plan->delete(); + + +Alarm Notification History +========================== + +The monitoring service keeps a record of notifications sent for each +alarm. This history is further subdivided by the check on which the +notification occurred. Every attempt to send a notification is recorded, +making this history a valuable tool in diagnosing issues with unreceived +notifications, in addition to offering a means of viewing the history of +an alarm's statuses. + +Alarm notification history is accessible as a Time Series Collection. By +default alarm notification history is stored for 30 days and the API +queries the last 7 days of information. + +Setup +------ + +In order to interact with this feature, you must first retrieve an entity by +its ID: + +.. code-block:: php + + $entity = $service->getEntity('{entityId}'); + +and then a particular check, about which you can configure alarms: + +.. code-block:: php + + $check = $entity->getCheck('{checkId}'); + +and finally, retrieve the alarm: + +.. code-block:: php + + $alarm = $check->getAlarm('{alarmId}'); + +For more information about these resource types, please consult the documentation +about `entities `_ and `checks `_. + + +Discover which Checks have a Notification History +------------------------------------------------- + +This operation list checks for which alarm notification history is +available: + +.. code-block:: php + + $checks = $alarm->getRecordedChecks(); + + +List Alarm Notification History for a particular Check +------------------------------------------------------ + +.. code-block:: php + + $checkHistory = $alarm->getNotificationHistoryForCheck('chAAAA'); + + +Get a particular Notification History item +------------------------------------------ + +.. code-block:: php + + $checkId = 'chAAAA'; + $itemUuid = '646ac7b0-0b34-11e1-a0a1-0ff89fa2fa26'; + + $singleItem = $history->getNotificationHistoryItem($checkId, $itemUuid); diff --git a/doc/services/monitoring/views.rst b/doc/services/monitoring/views.rst new file mode 100644 index 000000000..e83b97154 --- /dev/null +++ b/doc/services/monitoring/views.rst @@ -0,0 +1,21 @@ +Views +===== + +Views contain a combination of data that usually includes multiple, +different objects. The primary purpose of a view is to save API calls +and make data retrieval more efficient. Instead of doing multiple API +calls and then combining the result yourself, you can perform a single +API call against the view endpoint. + + +List all Views +-------------- + +.. code-block:: php + + $views = $service->getViews(); + + foreach ($views as $view) { + $entity = $view->getEntity(); + echo $view->getTimestamp(); + } diff --git a/doc/services/monitoring/zones.rst b/doc/services/monitoring/zones.rst new file mode 100644 index 000000000..bb588a303 --- /dev/null +++ b/doc/services/monitoring/zones.rst @@ -0,0 +1,57 @@ +Zones +===== + +A monitoring zone is a location that Rackspace Cloud Monitoring collects +data from. Examples of monitoring zones are "US West", "DFW1" or "ORD1". +It is an abstraction for a general location from which data is +collected. + +An "endpoint," also known as a "collector," collects data from the +monitoring zone. The endpoint is mapped directly to an individual +machine or a virtual machine. A monitoring zone contains many endpoints, +all of which will be within the IP address range listed in the response. +The opposite is not true, however, as there may be unallocated IP +addresses or unrelated machines within that IP address range. + +A check references a list of monitoring zones it should be run from. + +Get details about a zone +------------------------ + +.. code-block:: php + + $zone = $monitoringService->getMonitoringZone('{zoneId}'); + ++-----------------+------------------+-----------------------------------+------------------------+ +| Name | Description | Data type | Method | ++=================+==================+===================================+========================+ +| country_code | Country Code | String longer than 2 characters | ``getCountryCode()`` | ++-----------------+------------------+-----------------------------------+------------------------+ +| label | Label | String | ``getLabel()`` | ++-----------------+------------------+-----------------------------------+------------------------+ +| source_ips | Source IP list | Array | ``getSourceIps()`` | ++-----------------+------------------+-----------------------------------+------------------------+ + + List all zones +--------------- + +.. code-block:: php + + $zones = $service->getMonitoringZones(); + + +Perform a traceroute +-------------------- + +.. code-block:: php + + $traceroute = $zone->traceroute(array( + 'target' => 'http://test.com', + 'target_resolver' => 'IPv4' + )); + + // How many hops? + echo count($traceroute); + + // What was the first hop's IP? + echo $traceroute[0]->ip; diff --git a/doc/services/networking/index.rst b/doc/services/networking/index.rst new file mode 100644 index 000000000..335f6a10c --- /dev/null +++ b/doc/services/networking/index.rst @@ -0,0 +1,68 @@ +Networking v2 +============= + +.. include:: ../common/clients.sample.rst + +Networking service +~~~~~~~~~~~~~~~~~~ + +Now to instantiate the Networking service: + +.. code-block:: php + + $service = $client->networkingService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + networks + subnets + ports + security-groups + security-group-rules + +Glossary +-------- + +.. glossary:: + + network + A network is an isolated virtual layer-2 broadcast domain that is typically + reserved for the tenant who created it unless you configure the network to + be shared. The network is the main entity in the Networking service. Ports + and subnets are always associated with a network. + + subnet + A subnet represents an IP address block that can be used to assign IP + addresses to virtual instances (such as servers created using the Compute + service). Each subnet must have a CIDR and must be associated with a network. + + port + A port represents a virtual switch port on a logical network switch. + Virtual instances (such as servers created using the Compute service) + attach their interfaces into ports. The port also defines the MAC address + and the IP address(es) to be assigned to the interfaces plugged into them. + When IP addresses are associated to a port, this also implies the port is + associated with a subet, as the IP address is taken from the allocation + pool for a specific subnet. + + security group + A security group is a named container for security group rules. + + security group rule + A security group rule provides users the ability to specify the types of + traffic that are allowed to pass through to and from ports on a virtual + server instance. + + +Further links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/networking/networks.rst b/doc/services/networking/networks.rst new file mode 100644 index 000000000..b95d44eba --- /dev/null +++ b/doc/services/networking/networks.rst @@ -0,0 +1,128 @@ +Networks +======== + +Create a network +---------------- + +This operation takes one parameter, an associative array, with the +following keys: + ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+---------------------------------------+----------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++====================+===================================================================================================+=============+=============+=======================================+==================================+ +| ``name`` | A human-readable name for the network. This name might not be unique. | String | No | ``null`` | ``My private backend network`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+---------------------------------------+----------------------------------+ +| ``adminStateUp`` | The administrative state of network. If ``false`` (down), the network does not forward packets. | Boolean | No | ``true`` | ``true`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+---------------------------------------+----------------------------------+ +| ``shared`` | Specifies whether the network resource can be accessed by any tenant. | Boolean | No | ``false`` | ``false`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+---------------------------------------+----------------------------------+ +| ``tenantId`` | Owner of network. Only admin users can specify a tenant ID other than their own. | String | No | Same as tenant creating the network | ``123456`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+---------------------------------------+----------------------------------+ + +You can create a network as shown in the following example: + +.. code-block:: php + + /** @var $network OpenCloud\Networking\Resource\Network **/ + $network = $networkingService->createNetwork(array( + 'name' => 'My private backend network' + )); + +`Get the executable PHP script for this example `__ + + +Create multiple networks +------------------------ + +This operation takes one parameter, an indexed array. Each element of +this array must be an associative array with the keys shown in `the +preceding table <#create-a-network>`__. + +You can create multiple networks as shown in the following example: + +.. code-block:: php + + $networks = $networkingService->createNetworks(array( + array( + 'name' => 'My private backend network #1' + ), + array( + 'name' => 'My private backend network #2' + ) + )); + + foreach ($networks as $network) { + /** @var $network OpenCloud\Networking\Resource\Network **/ + } + +`Get the executable PHP script for this example `_ + +List networks +------------- + +You can list all the networks to which you have access as shown in the +following example: + +.. code-block:: php + + $networks = $networkingService->listNetworks(); + + foreach ($networks as $network) { + /** @var $network OpenCloud\Networking\Resource\Network **/ + } + + +`Get the executable PHP script for this example `_ + + +Get a network +------------- + +You can retrieve a specific network by using that network's ID, as shown +in the following example: + +.. code-block:: php + + /** @var $network OpenCloud\Networking\Resource\Network **/ + $network = $networkingService->getNetwork('{networkId}'); + +`Get the executable PHP script for this example `_ + + +Update a network +---------------- + +This operation takes one parameter, an associative array, with the +following keys: + ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+-----------------+------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++====================+===================================================================================================+=============+=============+=================+==========================================+ +| ``name`` | A human-readable name for the network. This name might not be unique. | String | No | ``null`` | ``My updated private backend network`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+-----------------+------------------------------------------+ +| ``adminStateUp`` | The administrative state of network. If ``false`` (down), the network does not forward packets. | Boolean | No | ``true`` | ``true`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+-----------------+------------------------------------------+ +| ``shared`` | Specifies whether the network resource can be accessed by any tenant. | Boolean | No | ``false`` | ``false`` | ++--------------------+---------------------------------------------------------------------------------------------------+-------------+-------------+-----------------+------------------------------------------+ + +You can update a network as shown in the following example: + +.. code-block:: php + + $network->update(array( + 'name' => 'My updated private backend network' + )); + +`Get the executable PHP script for this example `_ + + +Delete a network +~~~~~~~~~~~~~~~~ + +You can delete a network as shown in the following example: + +.. code-block:: php + + $network->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/networking/ports.rst b/doc/services/networking/ports.rst new file mode 100644 index 000000000..8eeb07bf0 --- /dev/null +++ b/doc/services/networking/ports.rst @@ -0,0 +1,150 @@ +Ports +===== + +Create a port +------------- + +This operation takes one parameter, an associative array, with the following keys: + ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++======================+=============================================================================================+============================================================+=============+=========================================+===========================================================================================================+ +| ``networkId`` | Network this port is associated with | String | Yes | - | ``eb60583c-57ea-41b9-8d5c-8fab2d22224c`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``name`` | A human-readable name for the port. This name might not be unique. | String | No | ``null`` | ``My port`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``adminStateUp`` | The administrative state of port. If ``false`` (down), the port does not forward packets. | Boolean | No | ``true`` | ``true`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``macAddress`` | MAC address to use on this port | String (MAC address in 6-octet form separated by colons) | No | Generated | ``0F:5A:6F:70:E9:5C`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``fixedIps`` | IP addresses for this port | Indexed array of associative arrays | No | Automatically allocated from the pool | ``array(array('subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', 'ipAddress' => '192.168.199.17'))`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``deviceId`` | Identifies the device (for example, virtual server) using this port | String | No | ``null`` | ``5e3898d7-11be-483e-9732-b2f5eccd2b2e`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``deviceOwner`` | Identifies the entity (for example, DHCP agent) using this port | String | No | ``null`` | ``network:router_interface`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``securityGroups`` | Specifies the IDs of any security groups associated with this port | Indexed array of strings | No | Empty array | ``array('f0ac4394-7e4a-4409-9701-ba8be283dbc3')`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``tenantId`` | Owner of the port. Only admin users can specify a tenant ID other than their own. | String | No | Same as the tenant creating the port | ``123456`` | ++----------------------+---------------------------------------------------------------------------------------------+------------------------------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ + +You can create a port as shown in the following example: + +.. code-block:: php + + /** @var $port OpenCloud\Networking\Resource\Port **/ + $port = $networkingService->createPort(array( + 'name' => 'My port', + 'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c' + )); + + +`Get the executable PHP script for this example `_ + + +Create multiple ports +--------------------- + +This operation takes one parameter, an indexed array. Each element of +this array must be an associative array with the keys shown in `the +preceding table <#create-a-port>`__. + +You can create multiple ports as shown in the following example: + +.. code-block:: php + + $ports = $networkingService->createPorts(array( + array( + 'name' => 'My port #1', + 'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c' + ), + array( + 'name' => 'My port #2', + 'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c' + ) + )); + + foreach ($ports as $port) { + /** @var $port OpenCloud\Networking\Resource\Port **/ + } + +`Get the executable PHP script for this example `_ + + +List ports +---------- + +You can list all the ports to which you have access as shown in the following example: + +.. code-block:: php + + $ports = $networkingService->listPorts(); + + foreach ($ports as $port) { + /** @var $port OpenCloud\Networking\Resource\Port **/ + } + +`Get the executable PHP script for this example `_ + + +Get a port +---------- + +You can retrieve a specific port by using that port's ID, as shown in +the following example: + +.. code-block:: php + + /** @var $port OpenCloud\Networking\Resource\Port **/ + $port = $networkingService->getPort('{portId}'); + +`Get the executable PHP script for this example `_ + + +Update a port +------------- + +This operation takes one parameter, an associative array, with the following keys: + ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++======================+=============================================================================================+=======================================+=============+=========================================+===========================================================================================================+ +| ``name`` | A human-readable name for the port. This name might not be unique. | String | No | ``null`` | ``My port`` | ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``adminStateUp`` | The administrative state of port. If ``false`` (down), the port does not forward packets. | Boolean | No | ``true`` | ``true`` | ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``fixedIps`` | IP addresses for this port | Indexed array of associative arrays | No | Automatically allocated from the pool | ``array(array('subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', 'ipAddress' => '192.168.199.59'))`` | ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``deviceId`` | Identifies the device (for example, virtual server) using this port | String | No | ``null`` | ``5e3898d7-11be-483e-9732-b2f5eccd2b2e`` | ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``deviceOwner`` | Identifies the entity (for example, DHCP agent) using this port | String | No | ``null`` | ``network:router_interface`` | ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ +| ``securityGroups`` | Specifies the IDs of any security groups associated with this port | Indexed array of strings | No | Empty array | ``array('f0ac4394-7e4a-4409-9701-ba8be283dbc3')`` | ++----------------------+---------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------------------------------+-----------------------------------------------------------------------------------------------------------+ + +You can update a port as shown in the following example: + +.. code-block:: php + + $port->update(array( + 'fixedIps' => array( + array( + 'subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', + 'ipAddress' => '192.168.199.59' + ) + ) + )); + +`Get the executable PHP script for this example `_ + + +Delete a port +------------- + +You can delete a port as shown in the following example: + +.. code-block:: php + + $port->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/networking/security-group-rules.rst b/doc/services/networking/security-group-rules.rst new file mode 100644 index 000000000..1ca6041d1 --- /dev/null +++ b/doc/services/networking/security-group-rules.rst @@ -0,0 +1,61 @@ +Security Group Rules +==================== + +Create a security group rule +---------------------------- + +This operation takes one parameter, an associative array, with the +following keys: + ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++=======================+===================================================================================================================================================================================================================================================================+=======================================+=============+=================+============================================+ +| ``securityGroupId`` | The security group ID to associate with this security group rule. | String | Yes | - | ``2076db17-a522-4506-91de-c6dd8e837028`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``direction`` | The direction in which the security group rule is applied. For a compute instance, an ingress security group rule is applied to incoming (ingress) traffic for that instance. An egress rule is applied to traffic leaving the instance. | String (``ingress`` or ``egress``) | Yes | - | ``ingress`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``ethertype`` | Must be IPv4 or IPv6, and addresses represented in CIDR must match the ingress or egress rules. | String (``IPv4`` or ``IPv6``) | No | ``IPv4`` | ``IPv6`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``portRangeMin`` | The minimum port number in the range that is matched by the security group rule. If the protocol is TCP or UDP, this value must be less than or equal to the value of the ``portRangeMax`` attribute. If the protocol is ICMP, this value must be an ICMP type. | Integer | No | ``null`` | ``80`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``portRangeMax`` | The maximum port number in the range that is matched by the security group rule. The port\_range\_min attribute constrains the attribute. If the protocol is ICMP, this value must be an ICMP type. | Integer | No | ``null`` | ``80`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``protocol`` | The protocol that is matched by the security group rule. | String (``tcp``, ``udp``, ``icmp``) | No | ``null`` | ``tcp`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``remoteGroupId`` | The remote group ID to be associated with this security group rule. You can specify either ``remoteGroupId`` or ``remoteGroupPrefix``. | String | Optional | ``null`` | ``85cc3048-abc3-43cc-89b3-377341426ac5`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ +| ``remoteIpPrefix`` | The remote IP prefix to be associated with this security group rule. You can specify either ``remoteGroupId`` or ``remoteGroupPrefix``. | String | Optional | ``null`` | ``192.168.5.0`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+-----------------+--------------------------------------------+ + +You can create a security group rule as shown in the following example: + +.. code:: php + + /** @var $securityGroupRule OpenCloud\Networking\Resource\SecurityGroupRule **/ + $securityGroupRule = $networkingService->createSecurityGroupRule(array( + 'securityGroupId' => '2076db17-a522-4506-91de-c6dd8e837028', + 'direction' => 'egress', + 'ethertype' => 'IPv4', + 'portRangeMin' => 80, + 'portRangeMax' => 80, + 'protocol' => 'tcp', + 'remoteGroupId' => '85cc3048-abc3-43cc-89b3-377341426ac5' + )); + +`Get the executable PHP script for this example `_ + + +List security group rules +------------------------- + +You can list all the security group rules to which you have access as +shown in the following example: + +.. code:: php + + $securityGroupRules = $networkingService->listSecurityGroupRules(); + foreach ($securityGroupRules as $securityGroupRule) { + /** @var $securityGroupRule OpenCloud\Networking\Resource\SecurityGroupRule **/ + } + +`Get the executable PHP script for this example `_ diff --git a/doc/services/networking/security-groups.rst b/doc/services/networking/security-groups.rst new file mode 100644 index 000000000..cde5c9a2d --- /dev/null +++ b/doc/services/networking/security-groups.rst @@ -0,0 +1,67 @@ +Security Groups +=============== + +Create a security group +~~~~~~~~~~~~~~~~~~~~~~~ + +This operation takes one parameter, an associative array, with the +following keys: + ++-------------------+--------------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+================================================================================+=============+=============+=================+=====================================+ +| ``name`` | A human-readable name for the security group. This name might not be unique. | String | Yes | - | ``new-webservers`` | ++-------------------+--------------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------------------+ +| ``description`` | Description of the security group. | String | No | ``null`` | ``security group for webservers`` | ++-------------------+--------------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------------------+ + +You can create a security group as shown in the following example: + +.. code-block:: php + + /** @var $securityGroup OpenCloud\Networking\Resource\SecurityGroup **/ + $securityGroup = $networkingService->createSecurityGroup(array( + 'name' => 'new-webservers', + 'description' => 'security group for webservers' + )); + +`Get the executable PHP script for this example `_ + +List security groups +~~~~~~~~~~~~~~~~~~~~ + +You can list all the security groups to which you have access as shown +in the following example: + +.. code-block:: php + + $securityGroups = $networkingService->listSecurityGroups(); + foreach ($securityGroups as $securityGroup) { + /** @var $securityGroup OpenCloud\Networking\Resource\SecurityGroup **/ + } + +`Get the executable PHP script for this example `_ + +Get a security group +~~~~~~~~~~~~~~~~~~~~ + +You can retrieve a specific security group by using that security +group’s ID, as shown in the following example: + +.. code-block:: php + + /** @var $securityGroup OpenCloud\Networking\Resource\SecurityGroup **/ + $securityGroup = $networkingService->getSecurityGroup('{secGroupId}'); + +`Get the executable PHP script for this example `_ + +Delete a security group +~~~~~~~~~~~~~~~~~~~~~~~ + +You can delete a security group as shown in the following example: + +.. code-block:: php + + $securityGroup->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/networking/subnets.rst b/doc/services/networking/subnets.rst new file mode 100644 index 000000000..9a6c2a7b4 --- /dev/null +++ b/doc/services/networking/subnets.rst @@ -0,0 +1,152 @@ +Subnets +======= + +Create a subnet +--------------- + +This operation takes one parameter, an associative array, with the following keys: + ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++=======================+===================================================================================================================+=======================================+=============+========================================================================+=================================================================================+ +| ``networkId`` | Network this subnet is associated with | String | Yes | - | ``eb60583c-57ea-41b9-8d5c-8fab2d22224c`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``ipVersion`` | IP version | Integer (``4`` or ``6``) | Yes | - | ``4`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``cidr`` | CIDR representing the IP address range for this subnet | String (CIDR) | Yes | - | ``192.168.199.0/25`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``name`` | A human-readable name for the subnet. This name might not be unique. | String | No | ``null`` | ``My subnet`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``gatewayIp`` | IP address of the default gateway used by devices on this subnet | String (IP address) | No | First IP address in CIDR | ``192.168.199.128`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``dnsNameservers`` | DNS nameservers used by hosts in this subnet | Indexed array of strings | No | Empty array | ``array('4.4.4.4', '8.8.8.8')`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``allocationPools`` | Subranges of the CIDR available for dynamic allocation to ports | Indexed array of associative arrays | No | Every IP address in CIDR, excluding gateway IP address if configured | ``array(array('start' => '192.168.199.2', 'end' => '192.168.199.127'))`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``hostRoutes`` | Routes that should be used by devices with IP addresses from this subnet (not including the local subnet route) | Indexed array of associative arrays | No | Empty array | ``array(array('destination' => '1.1.1.0/24', 'nexthop' => '192.168.19.20'))`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``enableDhcp`` | Specifies whether DHCP is enabled for this subnet | Boolean | No | ``true`` | ``false`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ +| ``tenantId`` | Owner of the subnet. Only admin users can specify a tenant ID other than their own. | String | No | Same as tenant creating the subnet | ``123456`` | ++-----------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+------------------------------------------------------------------------+---------------------------------------------------------------------------------+ + +You can create a subnet as shown in the following example: + +.. code-block:: php + + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ + $subnet = $networkingService->createSubnet(array( + 'name' => 'My subnet', + 'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c', + 'ipVersion' => 4, + 'cidr' => '192.168.199.0/25' + )); + +`Get the executable PHP script for this example `_ + + +Create multiple subnets +----------------------- + +This operation takes one parameter, an indexed array. Each element of +this array must be an associative array with the keys shown in `the +preceding table <#create-a-subnet>`__. + +You can create multiple subnets as shown in the following example: + +.. code-block:: php + + $subnets = $networkingService->createSubnets(array( + array( + 'name' => 'My subnet #1' + ), + array( + 'name' => 'My subnet #2' + ) + )); + + foreach ($subnets as $subnet) { + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ + } + +`Get the executable PHP script for this example `_ + + +List subnets +------------ + +You can list all the subnets to which you have access as shown in the +following example: + +.. code-block:: php + + $subnets = $networkingService->listSubnets(); + foreach ($subnets as $subnet) { + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ + } + +`Get the executable PHP script for this example `_ + + +Get a subnet +------------ + +You can retrieve a specific subnet by using that subnet's ID, as shown +in the following example: + +.. code-block:: php + + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ + $subnet = $networkingService->getSubnet('{subnetId}'); + +`Get the executable PHP script for this example `_ + + +Update a subnet +--------------- + +This operation takes one parameter, an associative array, with the +following keys: + ++----------------------+------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+----------------------------+---------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++======================+==================================================================================================================+=======================================+=============+============================+=================================================================================+ +| ``name`` | A human-readable name for the subnet. This name might not be unique. | String | No | ``null`` | ``My updated subnet`` | ++----------------------+------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+----------------------------+---------------------------------------------------------------------------------+ +| ``gatewayIp`` | IP address of the default gateway used by devices on this subnet | String (IP address) | No | First IP address in CIDR | ``192.168.62.155`` | ++----------------------+------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+----------------------------+---------------------------------------------------------------------------------+ +| ``dnsNameservers`` | DNS nameservers used by hosts in this subnet | Indexed array of strings | No | Empty array | ``array('4.4.4.4', '8.8.8.8')`` | ++----------------------+------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+----------------------------+---------------------------------------------------------------------------------+ +| ``hostRoutes`` | Routes that should be used by devices with IP adresses from this subnet (not including the local subnet route) | Indexed array of associative arrays | No | Empty array | ``array(array('destination' => '1.1.1.0/24', 'nexthop' => '192.168.17.19'))`` | ++----------------------+------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+----------------------------+---------------------------------------------------------------------------------+ +| ``enableDhcp`` | Specifies whether DHCP is enabled for this subnet | Boolean | No | ``true`` | ``false`` | ++----------------------+------------------------------------------------------------------------------------------------------------------+---------------------------------------+-------------+----------------------------+---------------------------------------------------------------------------------+ + +You can update a subnet as shown in the following example: + +.. code-block:: php + + $subnet->update(array( + 'name' => 'My updated subnet', + 'hostRoutes' => array( + array( + 'destination' => '1.1.1.0/24', + 'nexthop' => '192.168.17.19' + ) + ), + 'gatewayIp' => '192.168.62.155' + )); + +`Get the executable PHP script for this example `_ + + +Delete a subnet +--------------- + +You can delete a subnet as shown in the following example: + +.. code-block:: php + + $subnet->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/object-store/access.rst b/doc/services/object-store/access.rst new file mode 100644 index 000000000..62cb541ca --- /dev/null +++ b/doc/services/object-store/access.rst @@ -0,0 +1,86 @@ +Temporary URLs +============== + +Temporary URLs allow you to create time-limited Internet addresses that +allow you to grant access to your Cloud Files account. Using Temporary +URL, you may allow others to retrieve or place objects in your +containers - regardless of whether they're CDN-enabled. + + +Set "temporary URL" metadata key +-------------------------------- + +You must set this "secret" value on your account, where it can be used +in a global state: + +.. code-block:: php + + $account = $service->getAccount(); + $account->setTempUrlSecret('my_secret'); + + echo $account->getTempUrlSecret(); + +The string argument of ``setTempUrlSecret()`` is optional - if left out, +the SDK will generate a random hashed secret for you. + + +Create a temporary URL +---------------------- + +Once you've set an account secret, you can create a temporary URL for +your object. To allow GET access to your object for 1 minute: + +.. code-block:: php + + $object->getTemporaryUrl(60, 'GET'); + + +To allow PUT access for 1 hour: + +.. code-block:: php + + $object->getTemporaryUrl(360, 'PUT'); + + +Hosting HTML sites on CDN +========================= + +.. include:: rs-only.rst + +To host a static (i.e. HTML) website on Cloud Files, you must follow +these steps: + +1. CDN-enable a container: + +.. code-block:: php + + $container = $service->getContainer('html_site'); + $container->enableCdn(); + +2. Upload all HTML content. You can use nested directory structures. + +.. code-block:: php + + $container->uploadObjects(array( + array('name' => 'index.html', 'path' => 'index.html'), + array('name' => 'contact.html', 'path' => 'contact.html'), + array('name' => 'error.html', 'path' => 'error.html'), + array('name' => 'styles.css', 'path' => 'styles.css'), + array('name' => 'main.js', 'path' => 'main.js'), + )); + +3. Tell Cloud Files what to use for your default index page like this: + +.. code-block:: php + + $container->setStaticIndexPage('index.html'); + +4. (Optional) Tell Cloud Files which error page to use by default: + +.. code-block:: php + + $container->setStaticErrorPage('error.html'); + + +Bear in mind that steps 3 & 4 do not upload content, but rather specify +a reference to an existing page/CloudFiles object. diff --git a/doc/services/object-store/account.rst b/doc/services/object-store/account.rst new file mode 100644 index 000000000..fb51c8855 --- /dev/null +++ b/doc/services/object-store/account.rst @@ -0,0 +1,46 @@ +Account Details +=============== + +To see how many containers you have in your account +(X-Account-Container-Count), how many objects are in your account +(X-Account-Object-Count), and how many total bytes your account uses +(X-Account-Bytes-Used): + +Setup +----- + +.. code-block:: php + + $account = $service->getAccount(); + + +View all details +---------------- + +.. code-block:: php + + $details = $account->getDetails(); + + +Retrieve total container count +------------------------ + +.. code-block:: php + + $account->getContainerCount(); + + +Retrieve total object count +--------------------- + +.. code-block:: php + + $account->getObjectCount(); + + +Retrieve total bytes used +------------------------- + +.. code-block:: php + + $account->getBytesUsed(); diff --git a/doc/services/object-store/cdn.rst b/doc/services/object-store/cdn.rst new file mode 100644 index 000000000..5ad72b6cd --- /dev/null +++ b/doc/services/object-store/cdn.rst @@ -0,0 +1,124 @@ +CDN Containers +============== + +.. include:: rs-only.rst + +Setup +----- + +In order to interact with CDN containers, you first need to instantiate a +CDN service object: + +.. code-block:: php + + $cdnService = $service->getCdnService(); + + +List CDN-enabled containers +--------------------------- + +To list CDN-only containers, follow the same operation for Storage which +lists all containers. The only difference is which service object you +execute the method on: + +.. code-block:: php + + $cdnContainers = $cdnService->listContainers(); + + foreach ($cdnContainers as $cdnContainer) { + /** @var $cdnContainer OpenCloud\ObjectStore\Resource\CDNContainer */ + } + + +CDN-enable a container +---------------------- + +Before a container can be CDN-enabled, it must exist in the storage +system. When a container is CDN-enabled, any objects stored in it are +publicly accessible over the Content Delivery Network by combining the +container's CDN URL with the object name. + +Any CDN-accessed objects are cached in the CDN for the specified amount +of time called the TTL. The default TTL value is 259200 seconds, or 72 +hours. Each time the object is accessed after the TTL expires, the CDN +refetches and caches the object for the TTL period. + +.. code-block:: php + + $container->enableCdn(); + + +CDN-disable a container +----------------------- + +.. code-block:: php + + $container->disableCdn(); + + +Operations on CDN-enabled containers +------------------------------------ + +Once a container has been CDN-enabled, you can retrieve it like so: + +.. code-block:: php + + $cdnContainer = $cdnService->cdnContainer('{containerName}'); + + +Retrieve the SSL URL of a CDN container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $cdnContainer->getCdnSslUri(); + + +Retrieve the streaming URL of a CDN container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $cdnContainer->getCdnStreamingUri(); + + +Retrieve the iOS streaming URL of a CDN container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Cloud Files CDN allows you to stream video to iOS devices without +needing to convert your video. Once you CDN-enable your container, you +have the tools necessary for streaming media to multiple devices. + +.. code-block:: php + + $cdnContainer->getIosStreamingUri(); + + +CDN logging +~~~~~~~~~~~ + +To enable and disable logging for your CDN-enabled container: + +.. code-block:: php + + $cdnContainer->enableCdnLogging(); + $cdnContainer->disableCdnLogging(); + + +Purge CDN-enabled objects +------------------------- + +To remove a CDN object from public access: + +.. code-block:: php + + $object->purge(); + +You can also provide an optional e-mail address (or comma-delimeted list +of e-mails), which the API will send a confirmation message to once the +object has been completely purged: + +.. code-block:: php + + $object->purge('jamie.hannaford@rackspace.com'); + $object->purge('hello@example.com,hallo@example.com'); diff --git a/doc/services/object-store/containers.rst b/doc/services/object-store/containers.rst new file mode 100644 index 000000000..4b9c66ac3 --- /dev/null +++ b/doc/services/object-store/containers.rst @@ -0,0 +1,225 @@ +Containers +========== + +Create container +---------------- + +To create a new container, you just need to define its name: + +.. code-block:: php + + $container = $service->createContainer('my_amazing_container'); + +If the response returned is ``FALSE``, there was an API error - most +likely due to the fact you have a naming collision. + +Container names must be valid strings between 0 and 256 characters. +Forward slashes are not currently permitted. + +.. note:: + + When working with names that contain non-standard alphanumerical characters + (such as spaces or non-English characters), you must ensure they are encoded + with `urlencode `_ before passing them in + +List containers +--------------- + +.. code-block:: php + + $containers = $service->listContainers(); + + foreach ($containers as $container) { + /** @param $container OpenCloud\ObjectStore\Resource\Container */ + printf("Container name: %s\n", $container->name); + printf("Number of objects within container: %d\n", $container->getObjectCount()); + } + +Container names are sorted based on a binary comparison, a single +built-in collating sequence that compares string data using SQLite's +memcmp() function, regardless of text encoding. + +The list is limited to 10,000 containers at a time. To work with larger +collections, please read the next section. + + +Filtering large collections +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When you need more control over collections of containers, you can filter the +results and return back a subset of the total collection by using the ``marker`` +and ``end_marker`` parameters. The former parameter (``marker``) tells +the API where to begin the list, and the latter (``end_marker``) tells +it where to end the list. You may use either of them independently or +together. + +You may also use the ``limit`` parameter to fix the number of +containers returned. + +To list a set of containers between two fixed points: + +.. code-block:: php + + $someContainers = $service->listContainers(array( + 'marker' => 'container_55', + 'end_marker' => 'container_2001' + )); + +Or to return a limited set: + +.. code-block:: php + + $someContainers = $service->listContainers(array('limit' => 560)); + + +Get container +------------- + +To retrieve a certain container: + +.. code-block:: php + + /** @param $container OpenCloud\ObjectStore\Resource\Container */ + $container = $service->getContainer('{containerName}'); + + +Retrieve a container's name +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $name = $container->name; + + +Retrieve a container's object count +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $count = $container->getObjectCount(); + + +Retrieve a container's total bytes used +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $bytes = $container->getBytesUsed(); + + +Delete container +---------------- + +Deleting an empty container is easy: + +.. code-block:: php + + $container->delete(); + + +Please bear mind that you must delete all objects inside a container +before deleting it. This is done for you if you set the +``$deleteObjects`` parameter to ``TRUE`` like so: + +.. code-block:: php + + $container->delete(true); + + +You can also `delete all objects <#deleting-all-objects-inside-a-container>`_ +first, and then call ``delete``. + + +Deleting all objects inside a container +--------------------------------------- + +.. code-block:: php + + $container->deleteAllObjects(); + + +Create or update container metadata +----------------------------------- + +.. code-block:: php + + $container->saveMetadata(array( + 'Author' => 'Virginia Woolf', + 'Published' => '1931' + )); + +Please bear in mind that this action will set metadata to this array - +overriding existing values and wiping those left out. To *append* values +to the current metadata: + +.. code-block:: php + + $metadata = $container->appendToMetadata(array( + 'Publisher' => 'Hogarth' + )); + + +Container quotas +---------------- + +The ``container_quotas`` middleware implements simple quotas that can be +imposed on Cloud Files containers by a user. Setting container quotas +can be useful for limiting the scope of containers that are delegated to +non-admin users, exposed to formpost uploads, or just as a self-imposed +sanity check. + +To set quotas for a container: + +.. code-block:: php + + use OpenCloud\Common\Constants\Size; + + $container->setCountQuota(1000); + $container->setBytesQuota(2.5 * Size::GB); + +And to retrieve them: + +.. code-block:: php + + echo $container->getCountQuota(); + echo $container->getBytesQuota(); + + +Access log delivery +------------------- + +To view your object access, turn on Access Log Delivery. You can use +access logs to analyze the number of people who access your objects, +where they come from, how many requests for each object you receive, and +time-based usage patterns (such as monthly or seasonal usage). + +.. code-block:: php + + $container->enableLogging(); + $container->disableLogging(); + + +Syncing containers +------------------ + +You can synchronize local directories with your CloudFiles/Swift +containers very easily. When you do this, the container will mirror +exactly the nested file structure within your local directory: + +.. code-block:: php + + $container->uploadDirectory('/home/user/my-blog'); + +There are four scenarios you should be aware of: + ++------------------------+-----------------------+----------------------+--------------------------------+ +| Local | Remote | Comparison | Action | ++========================+=======================+======================+================================+ +| File exists | File exists | Identical checksum | No action | ++------------------------+-----------------------+----------------------+--------------------------------+ +| File exists | File exists | Different checksum | Local file overwrites remote | ++------------------------+-----------------------+----------------------+--------------------------------+ +| File exists | File does not exist | - | Local file created in Swift | ++------------------------+-----------------------+----------------------+--------------------------------+ +| Files does not exist | File exists | - | Remote file deleted | ++------------------------+-----------------------+----------------------+--------------------------------+ diff --git a/doc/services/object-store/index.rst b/doc/services/object-store/index.rst new file mode 100644 index 000000000..fcdc5aff2 --- /dev/null +++ b/doc/services/object-store/index.rst @@ -0,0 +1,65 @@ +Object Store v1 +=============== + +.. include:: ../common/clients.sample.rst + +Object Store service +~~~~~~~~~~~~~~~~~~~~ + +Now to instantiate the Object Store service: + +.. code-block:: php + + $service = $client->objectStoreService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + account + containers + objects + cdn + migrating-containers + access + +Glossary +-------- + +.. glossary:: + + account + The portion of the system designated for your use. An Object Store system is + typically designed to be used by many different customers, and your user + account is your portion of it. + + container + A storage compartment that provides a way for you to organize data. A + container is similar to a folder in Windows or a directory in UNIX. The + primary difference between a container and these other file system concepts + is that containers cannot be nested. + + cdn + A system of distributed servers (network) that delivers web pages and other + web content to a user based on the geographic locations of the user, the + origin of the web page, and a content delivery server. + + metadata + Optional information that you can assign to Cloud Files accounts, + containers, and objects through the use of a metadata header. + + object + An object (sometimes referred to as a file) is the unit of storage in an + Object Store. An object is a combination of content (data) and metadata. + + +Further links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/object-store/migrating-containers.rst b/doc/services/object-store/migrating-containers.rst new file mode 100644 index 000000000..22adb839b --- /dev/null +++ b/doc/services/object-store/migrating-containers.rst @@ -0,0 +1,111 @@ +Migrating containers across regions +=================================== + +Currently, there exists no single API operation to copy containers +across geographic endpoints. Although the API offers a ``COPY`` +operation for individual files, this does not work for cross-region +copying. The SDK, however, does offer this functionality. + +You **will** be charged for bandwidth between regions, so it's advisable +to use ServiceNet where possible (which is free). + + +Requirements +------------ + +- You must install the full Guzzle package, so that the process can + take advantage of Guzzle's batching functionality (it allows parallel + requests to be batched for greater efficiency). You can do this by + running: + +.. code-block:: bash + + composer require guzzle/guzzle + +- Depending on the size and number of transfer items, you will need to + raise PHP's memory limit: + +.. code-block:: php + + ini_set('memory_limit', '512M'); + +- You will need to enact some kind of backoff/retry strategy for rate + limits. Guzzle comes with a convenient feature that just needs to be + added as a normal subscriber: + +.. code-block:: php + + use Guzzle\Plugin\Backoff\BackoffPlugin; + + // set timeout in secs + $timeout = 10; + + // set HTTP error codes + $httpErrors = array(500, 503, 408); + + $backoffPlugin = BackoffPlugin::getExponentialBackoff($timeout, $httpErrors); + $client->addSubscriber($backoffPlugin); + + +This tells the client to retry up to ``10`` times for failed requests +have resulted in these HTTP status codes: ``500``, ``503`` or ``408``. + + +Setup +----- + +You can access all this functionality by executing: + +.. code-block:: php + + $ordService = $client->objectStoreService('cloudFiles', 'ORD'); + $iadService = $client->objectStoreService('cloudFiles', 'IAD'); + + $oldContainer = $ordService->getContainer('old_container'); + $newContainer = $iadService->getContainer('new_container'); + + $iadService->migrateContainer($oldContainer, $newContainer); + + +It's advisable to do this process in a Cloud Server in one of the two +regions you're migrating to/from. This allows you to use ``privateURL`` +as the third argument in the ``objectStoreService`` methods like this: + +.. code-block:: php + + $client->objectStoreService('cloudFiles', 'IAD', 'privateURL'); + + +This will ensure that traffic between your server and your new IAD +container will be held over the internal Rackspace network which is +free. + + +Options +------- + +You can pass in an array of arguments to the method: + +.. code-block:: php + + $options = array( + 'read.batchLimit' => 100, + 'read.pageLimit' => 100, + 'write.batchLimit' => 50 + ); + + $iadService->migrateContainer($oldContainer, $newContainer, $options); + + +Options explained +~~~~~~~~~~~~~~~~~ + ++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+ +| Name | Description | Default | ++========================+===============================================================================================================================================================================================================================================================================================================================================+===========+ +| ``read.pageLimit`` | When the process begins, it has to collect all the files that exist in the old container. It does this through a conventional ``objectList`` method, which calls the ``PaginatedIterator``. This iterator has the option to specify the page size for the collection (i.e. how many items are contained per page in responses from the API) | 10,000 | ++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+ +| ``read.batchLimit`` | After the data objects are collected, the process needs to send an individual GET request to ascertain more information. In order to make this process faster, these individual GET requests are batched together and sent in parallel. This limit refers to how many of these GET requests are batched together. | 1,000 | ++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+ +| ``write.batchLimit`` | Once each file has been retrieved from the API, a PUT request is executed against the new container. Similar to above, these PUT requests are batched - and this number refers to the amount of PUT requests batched together. | 100 | ++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+ diff --git a/doc/services/object-store/objects.rst b/doc/services/object-store/objects.rst new file mode 100644 index 000000000..e38e0eb8b --- /dev/null +++ b/doc/services/object-store/objects.rst @@ -0,0 +1,427 @@ +Objects +======= + +Setup +----- + +In order to interact with this feature, you must first retrieve a particular +container using its unique name: + +.. code-block:: php + + $container = $service->getContainer('{containerName}'); + + +Create an object +---------------- + +There are three ways to upload a new file, each of which has different +business needs. + +.. note:: + + Unlike previous versions, you do not need to manually specify your object's + content type. The API will do this for you. + +.. note:: + + When working with names that contain non-standard alphanumerical characters + (such as spaces or non-English characters), you must ensure they are encoded + with `urlencode `_ before passing them in. + +Upload a single file (under 5GB) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The simplest way to upload a local object, without additional metadata, is by +its path: + +.. code-block:: php + + $container->uploadObject('example.txt', fopen('/path/to/file.txt', 'r+')); + + +The resource handle will be automatically closed by Guzzle in its destructor, +so there is no need to execute ``fclose``. + + +Upload a single file (under 5GB) with metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Although the previous section handles most use cases, there are times when you +want greater control over what is being uploaded. For example, you might want +to control the object's metadata, or supply additional HTTP headers to coerce +browsers to handle the download a certain way. To add metadata to a new object: + +.. code-block:: php + + use OpenCloud\ObjectStore\Resource\DataObject; + + // specify optional metadata + $metadata = array( + 'Author' => 'Camera Obscura', + 'Origin' => 'Glasgow', + ); + + // specify optional HTTP headers + $httpHeaders = array( + 'Content-Type' => 'application/json', + ); + + // merge the two + $allHeaders = array_merge(DataObject::stockHeaders($metadata), $httpHeaders); + + // upload as usual + $container->uploadObject('example.txt', fopen('/path/to/file.txt', 'r+'), $allHeaders); + + +As you will notice, the first argument to ``uploadObject`` is the remote object +name, i.e. the name it will be uploaded as. The second argument is either a +file handle resource, or a string representation of object content (a temporary +resource will be created in memory), and the third is an array of additional +headers. + + +Batch upload multiple files (each under 5GB) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $files = array( + array( + 'name' => 'apache.log', + 'path' => '/etc/httpd/logs/error_log' + ), + array( + 'name' => 'mysql.log', + 'body' => fopen('/tmp/mysql.log', 'r+') + ), + array( + 'name' => 'to_do_list.txt', + 'body' => 'PHONE HOME' + ) + ); + + $container->uploadObjects($files); + +As you can see, the ``name`` key is required for every file. You must +also specify *either* a path key (to an existing file), or a ``body``. +The ``body`` can either be a PHP resource or a string representation of +the content you want to upload. + + +Upload large files (over 5GB) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For files over 5GB, you will need to use the +``OpenCloud\ObjectStore\Upload\TransferBuilder`` factory to build and execute your +transfer. For your convenience, the Container resource object contains a simple +method to do this heavy lifting for you: + +.. code-block:: php + + $transfer = $container->setupObjectTransfer(array( + 'name' => 'video.mov', + 'path' => '/home/user/video.mov', + 'metadata' => array('Author' => 'Jamie'), + 'concurrency' => 4, + 'partSize' => 1.5 * Size::GB + )); + + $transfer->upload(); + + +You can specify how many concurrent cURL connections are used to upload +parts of your file. The file is fragmented into chunks, each of which is +uploaded individually as a separate file (the filename of each part will +indicate that it's a segment rather than the full file). After all parts +are uploaded, a manifestfile is uploaded. When the end-user accesses the 5GB +by its true filename, it actually references the manifest file which +concatenates each segment into a streaming download. + +In Swift terminology, the name for this process is *Dynamic Large Object (DLO)*. +To find out more details, please consult the `official documentation +`_. + + +List objects in a container +--------------------------- + +To return a list of objects: + +.. code-block:: php + + $files = $container->objectList(); + + foreach ($files as $file) { + /** @var $file OpenCloud\ObjectStore\Resource\DataObject */ + } + +By default, 10,000 objects are returned as a maximum. To get around +this, you can construct a query which refines your result set. For a +full specification of query parameters relating to collection filtering, +see the `official +docs `__. + +.. code-block:: php + + $container->objectList(array('prefix' => 'logFile_')); + + +Get object +---------- + +To retrieve a specific file from Cloud Files: + +.. code-block:: php + + /** @var $file OpenCloud\ObjectStore\Resource\DataObject */ + $file = $container->getObject('summer_vacation.mp4'); + +Once you have access to this ``OpenCloud\ObjectStore\Resource\DataObject`` +object, you can access these attributes: + +Get object's parent container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $container OpenCloud\ObjectStore\Resource\Container */ + $container = $object->getContainer(); + + +Get file name +~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $container OpenCloud\ObjectStore\Resource\Container */ + $container = $object->getContainer(); + + +Get file size +~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $size int */ + $size = $object->getContentLength(); + + +Get content of file +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $content Guzzle\Http\EntityBody */ + $content = $object->getContainer(); + + +Get type of file +~~~~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $type string */ + $type = $object->getContentType(); + + +Get file checksum +~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $etag string */ + $etag = $object->getEtag(); + + +Get last modified date of file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + /** @param $lastModified string */ + $lastModified = $object->getLastModified(); + + +Conditional requests +~~~~~~~~~~~~~~~~~~~~ + +You can also perform conditional requests according to `RFC 2616 +specification `__ (§§ 14.24-26). +Supported headers are ``If-Match``, ``If-None-Match``, +``If-Modified-Since`` and ``If-Unmodified-Since``. + +So, to retrieve a file's contents only if it's been recently changed + +.. code-block:: php + + $file = $container->getObject('error_log.txt', array( + 'If-Modified-Since' => 'Tue, 15 Nov 1994 08:12:31 GMT' + )); + + if ($file->getContentLength()) { + echo 'Has been changed since the above date'; + } else { + echo 'Has not been changed'; + } + +Retrieve a file only if it has NOT been modified (and expect a 412 on +failure): + +.. code-block:: php + + use Guzzle\Http\Exception\ClientErrorResponseException; + + try { + $oldImmutableFile = $container->getObject('payroll_2001.xlsx', array( + 'If-Unmodified-Since' => 'Mon, 31 Dec 2001 23:00:00 GMT' + )); + } catch (ClientErrorResponseException $e) { + echo 'This file has been modified...'; + } + +Finally, you can specify a range - which will return a subset of bytes +from the file specified. To return the last 20B of a file: + +.. code-block:: php + + $snippet = $container->getObject('output.log', array('range' => 'bytes=-20')); + + +Update an existing object +------------------------- + +.. code-block:: php + + $file->setContent(fopen('/path/to/new/content', 'r+')); + $file->update(); + +Bear in mind that updating a file name will result in a new file being +generated (under the new name). You will need to delete the old file. + + +Copy object to new location +--------------------------- + +To copy a file to another location, you need to specify a string-based +destination path: + +.. code-block:: php + + $object->copy('/container_2/new_object_name'); + +Where ``container_2`` is the name of the container, and ``new_object_name`` is +the name of the object inside the container that does not exist yet. + + +Get object metadata +------------------- + +You can fetch just the object metadata without fetching the full +content: + +.. code-block:: php + + $container->getPartialObject('summer_vacation.mp4'); + + +In order to access the metadata on a partial or complete object, use: + +.. code-block:: php + + $object->getMetadata(); + + +You can turn a partial object into a full object to get the content +after looking at the metadata: + +.. code-block:: php + + $object->refresh(); + + +You can also update to get the latest metadata: + +.. code-block:: php + + $object->retrieveMetadata(); + + +Update object metadata +---------------------- + +Similarly, with setting metadata there are two options: you can update +the metadata values of the local object (i.e. no HTTP request) if you +anticipate you'll be executing one soon (an update operation for +example): + +.. code-block:: php + + // There's no need to execute a HTTP request, because we'll soon do one anyway for the update operation + $object->setMetadata(array( + 'Author' => 'Hemingway' + )); + + // ... code here + + $object->update(); + +Alternatively, you can update the API straight away - so that everything +is retained: + +.. code-block:: php + + $object->saveMetadata(array( + 'Author' => 'Hemingway' + )); + +Please be aware that these methods override and wipe existing values. If +you want to append values to your metadata, use the correct method: + +.. code-block:: php + + $metadata = $object->appendToMetadata(array( + 'Author' => 'Hemingway' + )); + + $object->saveMetadata($metadata); + + +Extract archive +--------------- + +CloudFiles provides you the ability to extract uploaded archives to +particular destinations. The archive will be extracted and its contents +will populate the particular area specified. To upload file (which might +represent a directory structure) into a particular container: + +.. code-block:: php + + use OpenCloud\ObjectStore\Constants\UrlType; + + $service->bulkExtract('container_1', fopen('/home/jamie/files.tar.gz','r'), UrlType::TAR_GZ); + +You can also omit the container name (i.e. provide an empty string as +the first argument). If you do this, the API will create the containers +necessary to house the extracted files - this is done based on the +filenames inside the archive. + + +Delete object +------------- + +.. code-block:: php + + $object->delete(); + + +Delete multiple objects +----------------------- + +Bulk delete a set of paths: + +.. code-block:: php + + $pathsToBeDeleted = array('/container_1/old_file', '/container_2/notes.txt', '/container_1/older_file.log'); + + $service->bulkDelete($pathsToBeDeleted); diff --git a/doc/services/object-store/rs-only.rst b/doc/services/object-store/rs-only.rst new file mode 100644 index 000000000..fab4e423f --- /dev/null +++ b/doc/services/object-store/rs-only.rst @@ -0,0 +1,3 @@ +.. note:: + + This feature is only available to Rackspace users. diff --git a/doc/services/orchestration/build-info.rst b/doc/services/orchestration/build-info.rst new file mode 100644 index 000000000..b4016bab2 --- /dev/null +++ b/doc/services/orchestration/build-info.rst @@ -0,0 +1,15 @@ +Build info +========== + +Get build info +-------------- + +You can retrieve information about the current Orchestration service +build as shown in the following example: + +.. code-block:: php + + /** @var $resourceType OpenCloud\Orchestration\Resource\BuildInfo **/ + $buildInfo = $orchestrationService->getBuildInfo(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/orchestration/events.rst b/doc/services/orchestration/events.rst new file mode 100644 index 000000000..bceec0f5a --- /dev/null +++ b/doc/services/orchestration/events.rst @@ -0,0 +1,53 @@ +Stack resource events +===================== + +Operations on resources within a stack (such as the creation of a +resource) produce events. + + +List stack events +----------------- + +You can list all of the events for all of the resources in a stack as +shown in the following example: + +.. code-block:: php + + $stackEvents = $stack->listEvents(); + + foreach ($stackEvents as $stackEvent) { + /** @var $stackEvent OpenCloud\Orchestration\Resource\Event **/ + } + +`Get the executable PHP script for this example `_ + + +List stack resource events +-------------------------- + +You can list all of the events for a specific resource in a stack as +shown in the following example: + +.. code-block:: php + + $resourceEvents = $resource->listEvents(); + + foreach ($resourceEvents as $resourceEvent) { + /** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/ + } + +`Get the executable PHP script for this example `_ + + +Get stack resource event +------------------------ + +You can retrieve a specific event for a specific resource in a stack, by +using the resource event's ID, as shown in the following example: + +.. code-block:: php + + /** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/ + $resourceEvent = $resource->getEvent('c1342a0a-59e6-4413-9af5-07c9cae7d729'); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/orchestration/index.rst b/doc/services/orchestration/index.rst new file mode 100644 index 000000000..bae5ec6aa --- /dev/null +++ b/doc/services/orchestration/index.rst @@ -0,0 +1,59 @@ +Orchestration v1 +================ + +.. include:: ../common/clients.sample.rst + +Orchestration service +~~~~~~~~~~~~~~~~~~~~~ + +Now to instantiate the Orchestration service: + +.. code-block:: php + + $service = $client->orchestrationService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + templates + stacks + resources + resource-types + build-info + events + + +Glossary +-------- + +.. glossary:: + + template + An Orchestration template is a JSON or YAML document + that describes how a set of resources should be assembled to produce + a working deployment. The template specifies what resources should be + used, what attributes of these resources are parameterized and what + information is output to the user when a template is instantiated. + + resource + A resource is a template artifact that represents some + component of your desired architecture (a Cloud Server, a group of + scaled Cloud Servers, a load balancer, some configuration management + system, and so forth). + + stack + A stack is a running instance of a template. When a stack + is created, the resources specified in the template are created. + + +Further links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/orchestration/resource-types.rst b/doc/services/orchestration/resource-types.rst new file mode 100644 index 000000000..caa58b013 --- /dev/null +++ b/doc/services/orchestration/resource-types.rst @@ -0,0 +1,48 @@ +Resource types +============== + +When you define a template, you must use resource types supported by +your cloud. + +List resource types +------------------- + +You can list all supported resource types as shown in the following +example: + +.. code-block:: php + + $resourceTypes = $orchestrationService->listResourceTypes(); + foreach ($resourceTypes as $resourceType) { + /** @var $resourceType OpenCloud\Orchestration\Resource\ResourceType **/ + } + +`Get the executable PHP script for this example `_ + + +Get resource type +----------------- + +You can retrieve a specific resource type's schema as shown in the +following example: + +.. code-block:: php + + /** @var $resourceType OpenCloud\Orchestration\Resource\ResourceType **/ + $resourceType = $orchestrationService->getResourceType('OS::Nova::Server'); + +`Get the executable PHP script for this example `_ + + +Get resource type template +-------------------------- + +You can retrieve a specific resource type's representation as it would +appear in a template, as shown in the following example: + +.. code-block:: php + + /** @var $resourceTypeTemplate string **/ + $resourceTypeTemplate = $resourceType->getTemplate(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/orchestration/resources.rst b/doc/services/orchestration/resources.rst new file mode 100644 index 000000000..b04115122 --- /dev/null +++ b/doc/services/orchestration/resources.rst @@ -0,0 +1,50 @@ +Stack resources +=============== + +A stack is made up of zero or more resources such as databases, load +balancers, and servers, and the software installed on servers. + + +List stack resources +-------------------- + +You can list all the resources for a stack as shown in the following +example: + +.. code-block:: php + + $resources = $stack->listResources(); + + foreach ($resources as $resource) { + /** @var $resource OpenCloud\Orchestration\Resource\Resource **/ + } + +`Get the executable PHP script for this example `_ + + +Get stack resource +------------------ + +You can retrieve a specific resource in a stack bt using that resource's +name, as shown in the following example: + +.. code-block:: php + + /** @var $resource OpenCloud\Orchestration\Resource\Resource **/ + $resource = $stack->getResource('load-balancer'); + +`Get the executable PHP script for this example `_ + + +Get stack resource metadata +--------------------------- + +You can retrieve the metadata for a specific resource in a stack as +shown in the following example: + +.. code-block:: php + + /** @var $resourceMetadata \stdClass **/ + $resourceMetadata = $resource->getMetadata(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/orchestration/stacks.rst b/doc/services/orchestration/stacks.rst new file mode 100644 index 000000000..29b6c4f7f --- /dev/null +++ b/doc/services/orchestration/stacks.rst @@ -0,0 +1,299 @@ +Stacks +====== + +A stack is a running instance of a template. When a stack is created, +the `resources <#stack-resources>`__ specified in the template are +created. + + +Preview stack +------------- + +Before you create a stack from a template, you might want to see what +that stack will look like. This is called *previewing the stack*. + +This operation takes one parameter, an associative array, with the +following keys: + ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+=====================================================================================================================================================================================================================+=========================================================================================================================+=======================================+=================+=================================================================================================+ +| ``name`` | Name of the stack | String. Must start with an alphabetic character, and must contain only alphanumeric, ``_``, ``-`` or ``.`` characters | Yes | - | ``simple-lamp-setup`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``template`` | Template contents | String. JSON or YAML | No, if ``templateUrl`` is specified | ``null`` | ``heat_template_version: 2013-05-23\ndescription: LAMP server\n`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``templateUrl`` | URL of the template file | String. HTTP or HTTPS URL | No, if ``template`` is specified | ``null`` | ``https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``parameters`` | Arguments to the template, based on the template's parameters. For example, see the parameters in `this template section `__ | Associative array | No | ``null`` | ``array('flavor_id' => 'general1-1')`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ + +Preview a stack from a template file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can use it to preview a stack as shown in the following +example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->previewStack(array( + 'name' => 'simple-lamp-setup', + 'template' => file_get_contents(__DIR__ . '/lamp.yml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ) + )); + +`Get the executable PHP script for this example `_ + + +Preview a stack from a template URL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can use it to preview a stack as shown +in the following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->previewStack(array( + 'name' => 'simple-lamp-setup', + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ) + )); + +`Get the executable PHP script for this example `_ + + +Create stack +------------ + +You can create a stack from a template. This operation takes one parameter, an +associative array, with the following keys: + ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+====================================================================+==========================================================================================================================+=======================================+=================+=================================================================================================+ +| ``name`` | Name of the stack | String. Must start with an alphabetic character, and must contain only alphanumeric, ``_``, ``-`` or ``.`` characters. | Yes | - | ``simple-lamp-setup`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``template`` | Template contents | String. JSON or YAML | No, if ``templateUrl`` is specified | ``null`` | ``heat_template_version: 2013-05-23\ndescription: LAMP server\n`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``templateUrl`` | URL of template file | String. HTTP or HTTPS URL | No, if ``template`` is specified | ``null`` | ``https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``parameters`` | Arguments to the template, based on the template's parameters | Associative array | No | ``null`` | ``array('server_hostname' => 'web01')`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``timeoutMins`` | Duration, in minutes, after which stack creation should time out | Integer | Yes | - | 5 | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ + +Create a stack from a template file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can use it to create a stack as shown in the following +example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->createStack(array( + 'name' => 'simple-lamp-setup', + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + + +Create a stack from a template URL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can use it to create a stack as shown +in the following example: + +.. code-block:: php + + $stack = $orchestrationService->stack(); + $stack->create(array( + 'name' => 'simple-lamp-setup', + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + +List stacks +----------- + +You can list all the stacks that you have created as shown in the +following example: + +.. code-block:: php + + $stacks = $orchestrationService->listStacks(); + foreach ($stacks as $stack) { + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + } + +`Get the executable PHP script for this example `_ + + +Get stack +--------- + +You can retrieve a specific stack using its name, as shown in the +following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->getStack('simple-lamp-setup'); + +`Get the executable PHP script for this example `_ + + +Get stack template +------------------ + +You can retrieve the template used to create a stack. Note that a JSON +string is returned, regardless of whether a JSON or YAML template was +used to create the stack. + +.. code-block:: php + + /** @var $stackTemplate string **/ + $stackTemplate = $stack->getTemplate(); + +`Get the executable PHP script for this example `_ + + +Update stack +------------ + +You can update a running stack. + +This operation takes one parameter, an associative array, with the +following keys: + ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+==================================================================+=============================+=======================================+=================+=========================================================================================================+ +| ``template`` | Template contents | String. JSON or YAML | No, if ``templateUrl`` is specified | ``null`` | ``heat_template_version: 2013-05-23\ndescription: LAMP server\n`` | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| ``templateUrl`` | URL of template file | String. HTTP or HTTPS URL | No, if ``template`` is specified | ``null`` | ``https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp-updated.yaml`` | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| ``parameters`` | Arguments to the template, based on the template's parameters | Associative array | No | ``null`` | ``array('flavor_id' => 'general1-1')`` | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| ``timeoutMins`` | Duration, in minutes, after which stack update should time out | Integer | Yes | - | 5 | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ + + +Update a stack from a template file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can use it to update a stack as shown in the following +example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack->update(array( + 'template' => file_get_contents(__DIR__ . '/lamp-updated.yml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + + +Update Stack from Template URL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can use it to update a stack as shown +in the following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack->update(array( + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp-updated.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + + +Delete stack +------------ + +If you no longer need a stack and all its resources, you can delete the +stack *and* the resources as shown in the following example: + +.. code-block:: php + + $stack->delete(); + +`Get the executable PHP script for this example `_ + + +Abandon Stack +------------- + +.. note:: + + This operation returns data about the abandoned stack as a string. You can + use this data to recreate the stack by using the `adopt stack <#adopt-stack>`_ + operation. + +If you want to delete a stack but preserve all its resources, you can +abandon the stack as shown in the following example: + +.. code-block:: php + + /** @var $abandonStackData string **/ + $abandonStackData = $stack->abandon(); + file_put_contents(__DIR__ . '/sample_adopt_stack_data.json', $abandonStackData); + +`Get the executable PHP script for this example `_ + + +Adopt stack +----------- + +If you have data from an abandoned stack, you can re-create the stack as +shown in the following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->adoptStack(array( + 'name' => 'simple-lamp-setup', + 'template' => file_get_contents(__DIR__ . '/lamp.yml'), + 'adoptStackData' => $abandonStackData, + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/orchestration/stacks.rst-e b/doc/services/orchestration/stacks.rst-e new file mode 100644 index 000000000..29b6c4f7f --- /dev/null +++ b/doc/services/orchestration/stacks.rst-e @@ -0,0 +1,299 @@ +Stacks +====== + +A stack is a running instance of a template. When a stack is created, +the `resources <#stack-resources>`__ specified in the template are +created. + + +Preview stack +------------- + +Before you create a stack from a template, you might want to see what +that stack will look like. This is called *previewing the stack*. + +This operation takes one parameter, an associative array, with the +following keys: + ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+=====================================================================================================================================================================================================================+=========================================================================================================================+=======================================+=================+=================================================================================================+ +| ``name`` | Name of the stack | String. Must start with an alphabetic character, and must contain only alphanumeric, ``_``, ``-`` or ``.`` characters | Yes | - | ``simple-lamp-setup`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``template`` | Template contents | String. JSON or YAML | No, if ``templateUrl`` is specified | ``null`` | ``heat_template_version: 2013-05-23\ndescription: LAMP server\n`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``templateUrl`` | URL of the template file | String. HTTP or HTTPS URL | No, if ``template`` is specified | ``null`` | ``https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``parameters`` | Arguments to the template, based on the template's parameters. For example, see the parameters in `this template section `__ | Associative array | No | ``null`` | ``array('flavor_id' => 'general1-1')`` | ++-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ + +Preview a stack from a template file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can use it to preview a stack as shown in the following +example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->previewStack(array( + 'name' => 'simple-lamp-setup', + 'template' => file_get_contents(__DIR__ . '/lamp.yml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ) + )); + +`Get the executable PHP script for this example `_ + + +Preview a stack from a template URL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can use it to preview a stack as shown +in the following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->previewStack(array( + 'name' => 'simple-lamp-setup', + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ) + )); + +`Get the executable PHP script for this example `_ + + +Create stack +------------ + +You can create a stack from a template. This operation takes one parameter, an +associative array, with the following keys: + ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+====================================================================+==========================================================================================================================+=======================================+=================+=================================================================================================+ +| ``name`` | Name of the stack | String. Must start with an alphabetic character, and must contain only alphanumeric, ``_``, ``-`` or ``.`` characters. | Yes | - | ``simple-lamp-setup`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``template`` | Template contents | String. JSON or YAML | No, if ``templateUrl`` is specified | ``null`` | ``heat_template_version: 2013-05-23\ndescription: LAMP server\n`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``templateUrl`` | URL of template file | String. HTTP or HTTPS URL | No, if ``template`` is specified | ``null`` | ``https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``parameters`` | Arguments to the template, based on the template's parameters | Associative array | No | ``null`` | ``array('server_hostname' => 'web01')`` | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ +| ``timeoutMins`` | Duration, in minutes, after which stack creation should time out | Integer | Yes | - | 5 | ++-------------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------------------------+-----------------+-------------------------------------------------------------------------------------------------+ + +Create a stack from a template file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can use it to create a stack as shown in the following +example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->createStack(array( + 'name' => 'simple-lamp-setup', + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + + +Create a stack from a template URL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can use it to create a stack as shown +in the following example: + +.. code-block:: php + + $stack = $orchestrationService->stack(); + $stack->create(array( + 'name' => 'simple-lamp-setup', + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + +List stacks +----------- + +You can list all the stacks that you have created as shown in the +following example: + +.. code-block:: php + + $stacks = $orchestrationService->listStacks(); + foreach ($stacks as $stack) { + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + } + +`Get the executable PHP script for this example `_ + + +Get stack +--------- + +You can retrieve a specific stack using its name, as shown in the +following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->getStack('simple-lamp-setup'); + +`Get the executable PHP script for this example `_ + + +Get stack template +------------------ + +You can retrieve the template used to create a stack. Note that a JSON +string is returned, regardless of whether a JSON or YAML template was +used to create the stack. + +.. code-block:: php + + /** @var $stackTemplate string **/ + $stackTemplate = $stack->getTemplate(); + +`Get the executable PHP script for this example `_ + + +Update stack +------------ + +You can update a running stack. + +This operation takes one parameter, an associative array, with the +following keys: + ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| Name | Description | Data type | Required? | Default value | Example value | ++===================+==================================================================+=============================+=======================================+=================+=========================================================================================================+ +| ``template`` | Template contents | String. JSON or YAML | No, if ``templateUrl`` is specified | ``null`` | ``heat_template_version: 2013-05-23\ndescription: LAMP server\n`` | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| ``templateUrl`` | URL of template file | String. HTTP or HTTPS URL | No, if ``template`` is specified | ``null`` | ``https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp-updated.yaml`` | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| ``parameters`` | Arguments to the template, based on the template's parameters | Associative array | No | ``null`` | ``array('flavor_id' => 'general1-1')`` | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ +| ``timeoutMins`` | Duration, in minutes, after which stack update should time out | Integer | Yes | - | 5 | ++-------------------+------------------------------------------------------------------+-----------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------+ + + +Update a stack from a template file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can use it to update a stack as shown in the following +example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack->update(array( + 'template' => file_get_contents(__DIR__ . '/lamp-updated.yml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + + +Update Stack from Template URL +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can use it to update a stack as shown +in the following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack->update(array( + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp-updated.yaml', + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ + + +Delete stack +------------ + +If you no longer need a stack and all its resources, you can delete the +stack *and* the resources as shown in the following example: + +.. code-block:: php + + $stack->delete(); + +`Get the executable PHP script for this example `_ + + +Abandon Stack +------------- + +.. note:: + + This operation returns data about the abandoned stack as a string. You can + use this data to recreate the stack by using the `adopt stack <#adopt-stack>`_ + operation. + +If you want to delete a stack but preserve all its resources, you can +abandon the stack as shown in the following example: + +.. code-block:: php + + /** @var $abandonStackData string **/ + $abandonStackData = $stack->abandon(); + file_put_contents(__DIR__ . '/sample_adopt_stack_data.json', $abandonStackData); + +`Get the executable PHP script for this example `_ + + +Adopt stack +----------- + +If you have data from an abandoned stack, you can re-create the stack as +shown in the following example: + +.. code-block:: php + + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + $stack = $orchestrationService->adoptStack(array( + 'name' => 'simple-lamp-setup', + 'template' => file_get_contents(__DIR__ . '/lamp.yml'), + 'adoptStackData' => $abandonStackData, + 'timeoutMins' => 5 + )); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/orchestration/templates.rst b/doc/services/orchestration/templates.rst new file mode 100644 index 000000000..24bc896bc --- /dev/null +++ b/doc/services/orchestration/templates.rst @@ -0,0 +1,55 @@ +Templates +========= + +An Orchestration template is a JSON or YAML document that describes how +a set of resources should be assembled to produce a working deployment +(known as a `stack <#stacks>`__). The template specifies the resources +to use, the attributes of these resources that are parameterized and the +information that is sent to the user when a template is instantiated. + +Validating templates +-------------------- + +Before you use a template to create a stack, you might want to validate it. + + +Validate a template from a file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored on your local computer as a JSON or YAML +file, you can validate it as shown in the following example: + +.. code-block:: php + + use OpenCloud\Common\Exceptions\InvalidTemplateError; + + try { + $orchestrationService->validateTemplate(array( + 'template' => file_get_contents(__DIR__ . '/lamp.yaml') + )); + } catch (InvalidTemplateError $e) { + // Use $e->getMessage() for explanation of why template is invalid + } + +`Get the executable PHP script for this example `_ + +Validate Template from URL +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your template is stored as a JSON or YAML file in a remote location +accessible via HTTP or HTTPS, you can validate it as shown in the +following example: + +.. code-block:: php + + use OpenCloud\Common\Exceptions\InvalidTemplateError; + + try { + $orchestrationService->validateTemplate(array( + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml' + )); + } catch (InvalidTemplateError $e) { + // Use $e->getMessage() for explanation of why template is invalid + } + +`Get the executable PHP script for this example `_ diff --git a/doc/services/queues/claims.rst b/doc/services/queues/claims.rst new file mode 100644 index 000000000..7e375c8d3 --- /dev/null +++ b/doc/services/queues/claims.rst @@ -0,0 +1,119 @@ +Claims +====== + +Setup +----- + +In order to work with messages, you must first retrieve a queue by its name: + +.. code-block:: php + + $queue = $service->getQueue('{queueName}'); + + +Claim messages +-------------- + +This operation claims a set of messages (up to the value of the limit +parameter) from oldest to newest and skips any messages that are already +claimed. If no unclaimed messages are available, the API returns a +``204 No Content`` message. + +When a client (worker) finishes processing a message, it should delete +the message before the claim expires to ensure that the message is +processed only once. As part of the delete operation, workers should +specify the claim ID (which is best done by simply using the provided +href). If workers perform these actions, then if a claim simply expires, +the server can return an error and notify the worker of the race +condition. This action gives the worker a chance to roll back its own +processing of the given message because another worker can claim the +message and process it. + +The age given for a claim is relative to the server's clock. The claim's +age is useful for determining how quickly messages are getting processed +and whether a given message's claim is about to expire. + +When a claim expires, it is released. If the original worker failed to +process the message, another client worker can then claim the message. + +Parameters +~~~~~~~~~~ + +The ``ttl`` attribute specifies how long the server waits before +releasing the claim. The ttl value must be between 60 and 43200 seconds +(12 hours). You must include a value for this attribute in your request. + +The ``grace`` attribute specifies the message grace period in seconds. +The value of grace value must be between 60 and 43200 seconds (12 +hours). You must include a value for this attribute in your request. To +deal with workers that have stopped responding (for up to 1209600 +seconds or 14 days, including claim lifetime), the server extends the +lifetime of claimed messages to be at least as long as the lifetime of +the claim itself, plus the specified grace period. If a claimed message +would normally live longer than the grace period, its expiration is not +adjusted. + +The ``limit`` attribute specifies the number of messages to return, up +to 20 messages. If limit is not specified, limit defaults to 10. The +limit parameter is optional. + +.. code-block:: php + + use OpenCloud\Common\Constants\Datetime; + + $queue->claimMessages(array( + 'limit' => 15, + 'grace' => 5 * Datetime::MINUTE, + 'ttl' => 5 * Datetime::MINUTE + )); + + +Query claim +----------- + +This operation queries the specified claim for the specified queue. Claims with +malformed IDs or claims that are not found by ID are ignored. + +.. code-block:: php + + $claim = $queue->getClaim('{claimId}'); + + +Update claim +------------ + +This operation updates the specified claim for the specified queue. +Claims with malformed IDs or claims that are not found by ID are +ignored. + +Clients should periodically renew claims during long-running batches of +work to avoid losing a claim while processing a message. The client can +renew a claim by executing this method on a specific **Claim** and +including a new TTL. The API will then reset the age of the claim and +apply the new TTL. + +.. code-block:: php + + use OpenCloud\Common\Constants\Datetime; + + $claim->update(array( + 'ttl' => 10 * Datetime::MINUTE + )); + + +Release claim +------------- + +This operation immediately releases a claim, making any remaining +undeleted messages that are associated with the claim available to other +workers. Claims with malformed IDs or claims that are not found by ID +are ignored. + +This operation is useful when a worker is performing a graceful +shutdown, fails to process one or more messages, or is taking longer +than expected to process messages, and wants to make the remainder of +the messages available to other workers. + +.. code-block:: php + + $message->delete(); diff --git a/doc/services/queues/index.rst b/doc/services/queues/index.rst new file mode 100644 index 000000000..4175df760 --- /dev/null +++ b/doc/services/queues/index.rst @@ -0,0 +1,56 @@ +Queues v1 +========= + +.. include:: ../common/clients.sample.rst + +Queues service +~~~~~~~~~~~~~~ + +Now to instantiate the Queues service: + +.. code-block:: php + + $service = $client->queuesService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + queues + messages + claims + + +Glossary +-------- + +.. glossary:: + + claim + A Claim is the process of a worker checking out a message to perform + a task. Claiming a message prevents other workers from attempting to + process the same messages. + + queue + A Queue is an entity that holds messages. Ideally, a queue is created + per work type. For example, if you want to compress files, you would + create a queue dedicated to this job. Any application that reads from + this queue would only compress files. + + message + A Message is a task, a notification, or any meaningful data that a + producer or publisher sends to the queue. A message exists until it is + deleted by a recipient or automatically by the system based on a TTL + (time-to-live) value. + + +Further links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/queues/messages.rst b/doc/services/queues/messages.rst new file mode 100644 index 000000000..ea23caea3 --- /dev/null +++ b/doc/services/queues/messages.rst @@ -0,0 +1,201 @@ +Messages +======== + +Setup +----- + +In order to work with messages, you must first retrieve a queue by its name: + +.. code-block:: php + + $queue = $service->getQueue('{queueName}'); + + +Post new message +---------------- + +This operation posts the specified message or messages. You can submit +up to 10 messages in a single request. + +When posting new messages, you specify only the ``body`` and ``ttl`` for +the message. The API will insert metadata, such as ID and age. + +How you pass through the array structure depends on whether you are +executing multiple or single posts, but the keys are the +same: + +* The ``body`` attribute specifies an arbitrary document that constitutes + the body of the message being sent. The size of this body is limited to + 256 KB, excluding whitespace. + +* The ``ttl`` attribute specifies how long the server waits before marking + the message as expired and removing it from the queue. The value of ttl + must be between 60 and 1209600 seconds (14 days). Note that the server + might not actually delete the message until its age has reached up to + (ttl + 60) seconds, to allow for flexibility in storage implementations. + + +Posting a single message +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + use OpenCloud\Common\Constants\Datetime; + + $queue->createMessage(array( + 'body' => (object) array( + 'event' => 'BackupStarted', + 'deadline' => '26.12.2013', + ), + 'ttl' => 2 * Datetime::DAY + )); + + +Post a batch of messages +~~~~~~~~~~~~~~~~~~~~~~~~ + +Please note that the list of messages will be truncated at 10. For more, +please execute another method call. + +.. code-block:: php + + use OpenCloud\Common\Constants\Datetime; + + $messages = array( + array( + 'body' => (object) array( + 'play' => 'football' + ), + 'ttl' => 2 * Datetime::DAY + ), + array( + 'body' => (object) array( + 'play' => 'tennis' + ), + 'ttl' => 50 * Datetime::HOUR + ) + ); + + $queue->createMessages($messages); + + +Get messages +------------ + +This operation gets the message or messages in the specified queue. + +Message IDs and markers are opaque strings. Clients should make no +assumptions about their format or length. Furthermore, clients should +assume that there is no relationship between markers and message IDs +(that is, one cannot be derived from the other). This allows for a wide +variety of storage driver implementations. + +Results are ordered by age, oldest message first. + + +Parameters +~~~~~~~~~~ + +When retrieving messages, you can filter using these options: + ++--------------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Name | Style | Type | Description | ++====================+=========+============+============================================================================================================================================================================================================================================================================================================================================================================================================================================================================+ +| marker | Query | String | Specifies an opaque string that the client can use to request the next batch of messages. The marker parameter communicates to the server which messages the client has already received. If you do not specify a value, the API returns all messages at the head of the queue (up to the limit). Optional. | ++--------------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| limit | Query | Integer | When more messages are available than can be returned in a single request, the client can pick up the next batch of messages by simply using the URI template parameters returned from the previous call in the "next" field. Specifies up to 10 messages (the default value) to return. If you do not specify a value for the limit parameter, the default value of 10 is used. Optional. | ++--------------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| echo | Query | Boolean | Determines whether the API returns a client's own messages. The echo parameter is a Boolean value (true or false) that determines whether the API returns a client's own messages, as determined by the uuid portion of the User-Agent header. If you do not specify a value, echo uses the default value of false. If you are experimenting with the API, you might want to set echo=true in order to see the messages that you posted. The echo parameter is optional. | ++--------------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| include_claimed | Query | ​Boolean | Determines whether the API returns claimed messages and unclaimed messages. The include\_claimed parameter is a Boolean value (true or false) that determines whether the API returns claimed messages and unclaimed messages. If you do not specify a value, include\_claimed uses the default value of false (only unclaimed messages are returned). Optional. | ++--------------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. code-block:: php + + $messages = $queue->listMessages(array( + 'marker' => '51db6f78c508f17ddc924357', + 'limit' => 20, + 'echo' => true + )); + + foreach ($messages as $message) { + echo $message->getId() . PHP_EOL; + } + + +Get a set of messages by ID +--------------------------- + +This operation provides a more efficient way to query multiple messages +compared to using a series of individual GET. Note that the list of IDs +cannot exceed 20. If a malformed ID or a nonexistent message ID is +provided, it is ignored, and the remaining messages are returned. + +Parameters +~~~~~~~~~~ + ++------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| Name | Style | Type | Description | ++============+=========+============+========================================================================================================================================+ +| ids | Query | String | Specifies the IDs of the messages to get. Format multiple message ID values by separating them with commas (comma-separated). Optional | ++------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| claim_id | Query | ​Boolean | Specifies the claim ID with which the message is associated. Optional. | ++------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------+ + + +.. code-block:: php + + $ids = array('id_1', 'id_2'); + + $messages = $queue->listMessages(array('ids' => $ids)); + + foreach ($messages as $message) { + echo $message->getId() . PHP_EOL; + } + + +Delete a set of messages by ID +------------------------------ + +This operation immediately deletes the specified messages. If any of the +message IDs are malformed or non-existent, they are ignored. The +remaining valid messages IDs are deleted. + +.. code-block:: php + + $ids = array('id_1', 'id_2'); + $response = $queue->deleteMessages($ids); + + +Get a specific message +---------------------- + +This operation gets the specified message from the specified queue. + +.. code-block:: php + + /** @var $message OpenCloud\Queues\Message */ + $message = $queue->getMessage('{messageId}'); + + +Once you have access to the ``Message`` object, you access its attributes: + ++-----------+-------------+--------------------------------------------------------------------------------------------------------------+ +| attribute | method | description | ++===========+=============+==============================================================================================================+ +| href | ``getHref`` | An opaque relative URI that the client can use to uniquely identify a message resource and interact with it. | ++-----------+-------------+--------------------------------------------------------------------------------------------------------------+ +| ttl | ``getTtl`` | The TTL that was set on the message when it was posted. The message expires after (ttl - age) seconds. | ++-----------+-------------+--------------------------------------------------------------------------------------------------------------+ +| age | ``getAge`` | The number of seconds relative to the server's clock. | ++-----------+-------------+--------------------------------------------------------------------------------------------------------------+ +| body | ``getBody`` | The arbitrary document that was submitted with the original request to post the message. | ++-----------+-------------+--------------------------------------------------------------------------------------------------------------+ + + +Delete message +-------------- + +.. code-block:: php + + $message->delete(); diff --git a/doc/services/queues/queues.rst b/doc/services/queues/queues.rst new file mode 100644 index 000000000..7958adfae --- /dev/null +++ b/doc/services/queues/queues.rst @@ -0,0 +1,124 @@ +Queues +====== + +A note on Client IDs +-------------------- + +For most of the operations in Cloud Queues, you must specify a **Client ID** +which will be used as a unique identifier for the process accessing this +Queue. This is basically a UUID that must be unique to each client +accessing the API - it can be an arbitrary string. + +.. code-block:: php + + $service->setClientId(); + + echo $service->getClientId(); + +If you call ``setClientId`` without any parameters, a UUID is +automatically generated for you. + + +List queues +----------- + +This operation lists queues for the project. The queues are sorted alphabetically by name. + +.. code-block:: php + + $queues = $service->listQueues(); + + foreach ($queues as $queue) { + echo $queue->getName() , PHP_EOL; + } + + +Filtering lists +~~~~~~~~~~~~~~~ + +You can also filter collections using the following query parameters: + ++----------+-------+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Name | Style | Type | Description | ++==========+=======+=========+================================================================================================================================================================================================+ +| marker | Query | ​String | Specifies the name of the last queue received in a previous request, or none to get the first page of results. Optional. | ++----------+-------+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| limit | Query | Integer | Specifies the number of queues to return. The default value for the number of queues returned is 10. If you do not specify this parameter, the default number of queues is returned. Optional. | ++----------+-------+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| detailed | Query | ​Boolean | Determines whether queue metadata is included in the response. The default value for this parameter is false, which excludes the metadata. Optional. | ++----------+-------+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. code-block:: php + + $queues = $service->listQueues(array('detailed' => false)); + + +Create queue +------------ + +The only parameter required is the name of the queue you're creating. The name +must not exceed 64 bytes in length, and it is limited to US-ASCII letters, +digits, underscores, and hyphens. + +.. code-block:: php + + $queue = $service->createQueue('new_queue'); + + +Find queue details +------------------ + +.. code-block:: php + + /** @var $queue OpenCloud\Queues\Resource\Queues */ + $queue = $service->getQueue('{name}'); + + +Check queue existence +--------------------- + +This operation verifies whether the specified queue exists by returning +``TRUE`` or ``FALSE``. + +.. code-block:: php + + if ($service->hasQueue('new_queue')) { + // do something + } + + +Update queue metadata +--------------------- + +This operation replaces any existing metadata document in its entirety. +Ensure that you do not accidentally overwrite existing metadata that you +want to retain. If you want to *append* metadata, ensure you merge a new +array to the existing values. + +.. code-block:: php + + $queue->saveMetadata(array( + 'foo' => 'bar' + )); + + +Retrieve the queue metadata +--------------------------- + +This operation returns metadata, such as message TTL, for the queue. + +.. code-block:: php + + $metadata = $queue->retrieveMetadata(); + print_r($metadata->toArray()); + + +Get queue stats +--------------- + +This operation returns queue statistics, including how many messages are +in the queue, categorized by status. + +.. code-block:: php + + $queue->getStats(); diff --git a/doc/services/volume/index.rst b/doc/services/volume/index.rst new file mode 100644 index 000000000..bee589086 --- /dev/null +++ b/doc/services/volume/index.rst @@ -0,0 +1,51 @@ +Volumes v1 +========== + +.. include:: ../common/clients.sample.rst + +Volume service +~~~~~~~~~~~~~~ + +Now to instantiate the Volume service: + +.. code-block:: php + + $service = $client->volumeService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst + + +Operations +---------- + +.. toctree:: + + volumes + volume-types + snapshots + + +Glossary +-------- + +.. glossary:: + + volume + A volume is a detachable block storage device. You can think of it as a USB + hard drive. It can only be attached to one instance at a time. + + volume type + Providers may support multiple types of volumes; at Rackspace, a volume + can either be ``SSD`` (solid state disk: expensive, high-performance) or + ``SATA`` (serial attached storage: regular disks, less expensive). + + snapshot + A snapshot is a point-in-time copy of the data contained in a volume. + + +Further links +------------- + +- `Getting Started Guide for the API `_ +- `API Developer Guide `_ +- `API release history `_ diff --git a/doc/services/volume/snapshots.rst b/doc/services/volume/snapshots.rst new file mode 100644 index 000000000..c2d8ef6cc --- /dev/null +++ b/doc/services/volume/snapshots.rst @@ -0,0 +1,48 @@ +Snapshots +========= + +Create a snapshot +----------------- + +A ``Snapshot`` object is created from the Cloud Block Storage service. +However, it is associated with a volume, and you must specify a volume +to create one: + +.. code-block:: php + + // New instance of OpenCloud\Volume\Resource\Snapshot + $snapshot = $service->snapshot(); + + // Send to API + $snapshot->create(array( + 'display_name' => 'Name that snapshot', + 'volume_id' => $volume->id + )); + + +List snapshots +-------------- + +.. code-block:: php + + $snapshots = $service->snapshotList(); + + foreach ($snapshots as $snapshot) { + /** @param $snapshot OpenCloud\Volume\Resource\Snapshot */ + } + + +To get details on a single snapshot +----------------------------------- + +.. code-block:: php + + $snapshot = $dallas->snapshot('{snapshotId}'); + + +To delete a snapshot +-------------------- + +.. code-block:: php + + $snapshot->delete(); diff --git a/doc/services/volume/volume-types.rst b/doc/services/volume/volume-types.rst new file mode 100644 index 000000000..ba3176df9 --- /dev/null +++ b/doc/services/volume/volume-types.rst @@ -0,0 +1,30 @@ +Volume Types +============ + +List volume types +----------------- + +.. code-block:: php + + $volumeTypes = $service->volumeTypeList(); + + foreach ($volumeTypes as $volumeType) { + /** @param $volumeType OpenCloud\Volume\Resource\VolumeType */ + } + + +Describe a volume type +---------------------- + +If you know the ID of a volume type, use the ``volumeType`` method to +retrieve information on it: + +.. code-block:: php + + $volumeType = $service->volumeType(1); + +A volume type has three attributes: + +- ``id`` the volume type identifier +- ``name`` its name +- ``extra_specs`` additional information for the provider diff --git a/doc/services/volume/volumes.rst b/doc/services/volume/volumes.rst new file mode 100644 index 000000000..6a35bb135 --- /dev/null +++ b/doc/services/volume/volumes.rst @@ -0,0 +1,79 @@ +Volumes +======= + +Create a volume +--------------- + +To create a volume, you must specify its size (in gigabytes). All other +parameters are optional: + +.. code-block:: php + + // Create instance of OpenCloud\Volume\Resource\Volume + $volume = $service->volume(); + + $volume->create(array( + 'size' => 200, + 'volume_type' => $service->volumeType(''), + 'display_name' => 'My Volume', + 'display_description' => 'Used for large object storage' + )); + +List volumes +------------ + +.. code-block:: php + + $volumes = $service->volumeList(); + + foreach ($volumes as $volume) { + /** @param $volumeType OpenCloud\Volume\Resource\Volume */ + } + + +Get details on a single volume +------------------------------ + +If you specify an ID on the ``volume()`` method, it retrieves +information on the specified volume: + +.. code-block:: php + + $volume = $dallas->volume(''); + echo $volume->size; + + +To delete a volume +------------------ + +.. code-block:: php + + $volume->delete(); + + +Attach a volume to a server +--------------------------- + +.. code-block:: php + + // retrieve server + $computeService = $client->computeService('{catalogName}', '{region}'); + $server = $computeService->server('{serverId}'); + + // attach volume + $server->attachVolume($volume, '{mountPoint}') + +The ``{mountPoint}`` is the location on the server on which to mount +the volume (usually ``/dev/xvhdd`` or similar). You can also supply +``'auto'`` as the mount point, in which case the mount point will be +automatically selected for you. ``auto`` is the default value for +``{mountPoint}``, so you do not actually need to supply anything for +that parameter. + + +Detach a volume from a server +----------------------------- + +.. code-block:: php + + $server->detachVolume($volume); diff --git a/doc/url-types.rst b/doc/url-types.rst new file mode 100644 index 000000000..26a0410bd --- /dev/null +++ b/doc/url-types.rst @@ -0,0 +1,15 @@ +URL types +========= + +internalURL +----------- + +An internal URL is a URL that is accessible only from within the Rackspace +Cloud network. Access to an internal URL is always free of charge. + + +publicURL +--------- + +A public URL is a URL that is accessible from anywhere. Access to a public URL +usually incurs traffic charges.