diff --git a/.travis.yml b/.travis.yml index fad14d88c..78dd0003f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,14 @@ php: - "5.6" - "5.5" - "5.4" - - "5.3" - hhvm +sudo: false + matrix: allow_failures: - php: hhvm + fast_finish: true branches: only: @@ -17,6 +19,8 @@ branches: before_script: - composer install --prefer-source + - vendor/bin/parallel-lint --exclude vendor . + - vendor/bin/php-cs-fixer fix --dry-run --diff --level psr2 . after_script: - php vendor/bin/coveralls -v @@ -26,3 +30,6 @@ notifications: - jamie.hannaford@rackspace.com - glen.campbell@rackspace.com - shaunak.kashyap@rackspace.com + +env: + - secure: "bdrUeYb3nSGgBB+QtDZxUHVPw6B/wjb3KXLm8TgonWrQm4GPeWKK29qhmDnFZmQjwQPfuebe7wAk1ZxGoZKbEiELVpJJ+8XYVOt6W/6V53H31JL6FqiIE5+7qBwDe+9ziveM6GcTXHT1GI5mUeACIbeBDPZaNubIJH3U6MPim64=" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..5ff44c32b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,50 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by opening an issue. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a500b696d..4764be882 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,13 +11,21 @@ efforts. Here are a few general guidelines to follow: will need to write new test cases; if you're updating existing code, you will need to make sure the methods you're updating are still completely covered. -3. Please abide by PSR code styling. +3. Please abide by [PSR-2 code styling](#ensuring-psr-2-coding-style-compliance). 4. Explaining your pull requests is appreciated. Unless you're fixing a minor typographical error, create a description which explains your changes and, where relevant, references the existing issue you're hoping to fix. -5. Document your code! +5. If your pull request introduces a large change or addition, please consider + creating a work-in-progress (WIP) pull request. This lets us review your changes + and provide feedback early and often rather than all at once when the entire pull + request is ready. To denote a pull request as WIP, simply add the "PR: Work In Progress" + label to it. When you are finished with your work in the pull request and + are ready for a final review and merge, please remove the "PR: Work In Progress" + label. + +6. Document your code! If you submit code, please add your name and email address to the CONTRIBUTORS file. @@ -27,7 +35,7 @@ Test Instructions ### To run unit tests: ```bash -phpunit +vendor/bin/phpunit ``` ### To run the full suite of acceptance tests: @@ -44,3 +52,22 @@ phpunit * Methods that create a new resource, say `Foo`, should be named `createFoo`. For example, [`createEntity`](/lib/OpenCloud/CloudMonitoring/Service.php#L105). * When validating arguments to a method, please throw `\InvalidArgumentException` when an invalid argument is found. For example, see [here](/lib/OpenCloud/LoadBalancer/Resource/LoadBalancer.php#L212-L215). + +## Ensuring PSR-2 coding style compliance + +The code in this library is compliant with the [PSR-2 Coding Style Guide](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md). To ensure that any code you contribute is also PSR-2 compliant, please run the following command from the base directory of this project _before_ submitting your contribution: + + $ vendor/bin/php-cs-fixer fix --level psr2 . + +Running this command will _change_ your code to become PSR-2 compliant. You will need to _commit_ these changes and make them part of your pull request. + +## Releasing a new version of php-opencloud +If you are a core contributor to php-opencloud, you have the power to release new versions of it. Here are the steps to follow to ensure a proper release: + +1. Update the value of the the [`VERSION` constant](/lib/OpenCloud/Version.php#L30). +2. Merge the `working` branch into the `master` branch. +3. [Run the smoke tests](#to-run-the-full-suite-of-acceptance-tests). If they fail, make necessary changes and go to step 2. +4. [Create new release notes](https://github.com/rackspace/php-opencloud/releases/new). +5. Publish release notes. +6. Announce release via appropriate channels. +7. Party :tada: :balloon: \ No newline at end of file diff --git a/README.md b/README.md index 9c8fd1aa1..15191ba3d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ -**php-opencloud** -============= -PHP SDK for OpenStack/Rackspace APIs +# php-opencloud + +> **OpenStack users are recommended to use https://github.com/php-opencloud/openstack, which +> is the latest supported version of the SDK for OpenStack.** [![Latest Stable Version](https://poser.pugx.org/rackspace/php-opencloud/v/stable.png)](https://packagist.org/packages/rackspace/php-opencloud) [![Travis CI](https://secure.travis-ci.org/rackspace/php-opencloud.png)](https://travis-ci.org/rackspace/php-opencloud) [![Total Downloads](https://poser.pugx.org/rackspace/php-opencloud/downloads.png)](https://packagist.org/packages/rackspace/php-opencloud) -For SDKs in different languages, see http://developer.rackspace.com. +PHP SDK for OpenStack/Rackspace APIs. Our official documentation is now available on http://docs.php-opencloud.com. For SDKs in different languages, see http://developer.rackspace.com. The PHP SDK should work with most OpenStack-based cloud deployments, though it specifically targets the Rackspace public cloud. In @@ -16,9 +17,11 @@ so that you can still use the SDK with a pure OpenStack instance Requirements ------------ -* PHP >=5.3.3 +* PHP >=5.4 * cURL extension for PHP +**Note**: Since PHP 5.3 has reached [end of life](http://php.net/eol.php) and is no longer officially supported, we are moving to 5.4 as a minimum requirement. If upgrading is not an option and you still need a stable version of the SDK for 5.3, please follow [this guide](http://docs.php-opencloud.com/en/latest/using-php-5.3.html). + Installation ------------ You must install this library through Composer: @@ -28,16 +31,19 @@ You must install this library through Composer: curl -sS https://getcomposer.org/installer | php # Require php-opencloud as a dependency -php composer.phar require rackspace/php-opencloud:dev-master +php composer.phar require rackspace/php-opencloud ``` Once you have installed the library, you will need to load Composer's autoloader (which registers all the required -namespaces): +namespaces). To do this, place the following line of PHP code at the top of your application's PHP files: ```php require 'vendor/autoload.php'; ``` +**Note**: 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. + And you're ready to go! You can also check out the [Getting Started guide](docs/getting-started.md) for a quick tutorial. @@ -60,7 +66,7 @@ Your feedback is appreciated! If you have specific problems or bugs with this SD also have a [mailing list](https://groups.google.com/forum/#!forum/php-opencloud), 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. +For general feedback and support requests, contact us at https://developer.rackspace.com/support/ You can also find assistance via IRC on #rackspace at freenode.net. diff --git a/apigen.neon b/apigen.neon new file mode 100644 index 000000000..1907d65f4 --- /dev/null +++ b/apigen.neon @@ -0,0 +1,3 @@ +templateTheme: bootstrap + +accessLevels: [public] diff --git a/composer.json b/composer.json index 5bf3d0d36..d07ca4280 100644 --- a/composer.json +++ b/composer.json @@ -9,24 +9,35 @@ "name": "Jamie Hannaford", "email": "jamie.hannaford@rackspace.com", "homepage" : "https://github.com/jamiehannaford" - }, - { - "name": "Glen Campbell", - "email": "glen.campbell@rackspace.com" } ], "autoload": { "psr-0": { - "OpenCloud": ["lib/", "tests/"] + "OpenCloud": ["lib/"] + } + }, + "autoload-dev": { + "psr-0": { + "OpenCloud": ["tests/"] } }, "require": { - "php" : ">=5.3.3", - "guzzle/http" : "~3.8", - "psr/log": "~1.0" + "php" : ">=5.4", + "guzzle/guzzle" : "~3.8", + "psr/log": "~1.0", + "mikemccabe/json-patch-php": "~0.1" }, "require-dev" : { - "guzzle/guzzle": "~3.8", - "satooshi/php-coveralls": "0.6.*@dev" + "phpunit/phpunit": "4.3.*", + "phpspec/prophecy": "~1.4", + "satooshi/php-coveralls": "0.6.1", + "jakub-onderka/php-parallel-lint": "0.*", + "fabpot/php-cs-fixer": "1.0.*@dev", + "apigen/apigen": "~4.0" + }, + "extra": { + "branch-alias": { + "dev-working": "1.16-dev" + } } } 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/_build/doctrees/auth.doctree b/doc/_build/doctrees/auth.doctree new file mode 100644 index 000000000..8ee18ed4c Binary files /dev/null and b/doc/_build/doctrees/auth.doctree differ diff --git a/doc/_build/doctrees/caching-creds.doctree b/doc/_build/doctrees/caching-creds.doctree new file mode 100644 index 000000000..93548c4c3 Binary files /dev/null and b/doc/_build/doctrees/caching-creds.doctree differ diff --git a/doc/_build/doctrees/customizing-clients.doctree b/doc/_build/doctrees/customizing-clients.doctree new file mode 100644 index 000000000..eb198e953 Binary files /dev/null and b/doc/_build/doctrees/customizing-clients.doctree differ diff --git a/doc/_build/doctrees/debugging.doctree b/doc/_build/doctrees/debugging.doctree new file mode 100644 index 000000000..9b80c8314 Binary files /dev/null and b/doc/_build/doctrees/debugging.doctree differ diff --git a/doc/_build/doctrees/environment.pickle b/doc/_build/doctrees/environment.pickle new file mode 100644 index 000000000..74fa31fe9 Binary files /dev/null and b/doc/_build/doctrees/environment.pickle differ diff --git a/doc/_build/doctrees/getting-started-with-openstack.doctree b/doc/_build/doctrees/getting-started-with-openstack.doctree new file mode 100644 index 000000000..e2c06eebc Binary files /dev/null and b/doc/_build/doctrees/getting-started-with-openstack.doctree differ diff --git a/doc/_build/doctrees/getting-started-with-rackspace.doctree b/doc/_build/doctrees/getting-started-with-rackspace.doctree new file mode 100644 index 000000000..4e0af8595 Binary files /dev/null and b/doc/_build/doctrees/getting-started-with-rackspace.doctree differ diff --git a/doc/_build/doctrees/http-clients.doctree b/doc/_build/doctrees/http-clients.doctree new file mode 100644 index 000000000..aa0efa026 Binary files /dev/null and b/doc/_build/doctrees/http-clients.doctree differ diff --git a/doc/_build/doctrees/index.doctree b/doc/_build/doctrees/index.doctree new file mode 100644 index 000000000..92f917534 Binary files /dev/null and b/doc/_build/doctrees/index.doctree differ diff --git a/doc/_build/doctrees/iterators.doctree b/doc/_build/doctrees/iterators.doctree new file mode 100644 index 000000000..e08b87013 Binary files /dev/null and b/doc/_build/doctrees/iterators.doctree differ diff --git a/doc/_build/doctrees/logging.doctree b/doc/_build/doctrees/logging.doctree new file mode 100644 index 000000000..1194f30aa Binary files /dev/null and b/doc/_build/doctrees/logging.doctree differ diff --git a/doc/_build/doctrees/regions.doctree b/doc/_build/doctrees/regions.doctree new file mode 100644 index 000000000..4de01f904 Binary files /dev/null and b/doc/_build/doctrees/regions.doctree differ diff --git a/doc/_build/doctrees/services/autoscale/group-config.doctree b/doc/_build/doctrees/services/autoscale/group-config.doctree new file mode 100644 index 000000000..e0023bfb3 Binary files /dev/null and b/doc/_build/doctrees/services/autoscale/group-config.doctree differ diff --git a/doc/_build/doctrees/services/autoscale/groups.doctree b/doc/_build/doctrees/services/autoscale/groups.doctree new file mode 100644 index 000000000..bdc6ef66d Binary files /dev/null and b/doc/_build/doctrees/services/autoscale/groups.doctree differ diff --git a/doc/_build/doctrees/services/autoscale/index.doctree b/doc/_build/doctrees/services/autoscale/index.doctree new file mode 100644 index 000000000..3e1295f8b Binary files /dev/null and b/doc/_build/doctrees/services/autoscale/index.doctree differ diff --git a/doc/_build/doctrees/services/autoscale/policies.doctree b/doc/_build/doctrees/services/autoscale/policies.doctree new file mode 100644 index 000000000..afb159213 Binary files /dev/null and b/doc/_build/doctrees/services/autoscale/policies.doctree differ diff --git a/doc/_build/doctrees/services/autoscale/service.sample.doctree b/doc/_build/doctrees/services/autoscale/service.sample.doctree new file mode 100644 index 000000000..0af1db423 Binary files /dev/null and b/doc/_build/doctrees/services/autoscale/service.sample.doctree differ diff --git a/doc/_build/doctrees/services/autoscale/webhooks.doctree b/doc/_build/doctrees/services/autoscale/webhooks.doctree new file mode 100644 index 000000000..463f737e9 Binary files /dev/null and b/doc/_build/doctrees/services/autoscale/webhooks.doctree differ diff --git a/doc/_build/doctrees/services/common/clients.sample.doctree b/doc/_build/doctrees/services/common/clients.sample.doctree new file mode 100644 index 000000000..035ed7cde Binary files /dev/null and b/doc/_build/doctrees/services/common/clients.sample.doctree differ diff --git a/doc/_build/doctrees/services/common/os-client.sample.doctree b/doc/_build/doctrees/services/common/os-client.sample.doctree new file mode 100644 index 000000000..145c43ce8 Binary files /dev/null and b/doc/_build/doctrees/services/common/os-client.sample.doctree differ diff --git a/doc/_build/doctrees/services/common/rs-client.doctree b/doc/_build/doctrees/services/common/rs-client.doctree new file mode 100644 index 000000000..236c72484 Binary files /dev/null and b/doc/_build/doctrees/services/common/rs-client.doctree differ diff --git a/doc/_build/doctrees/services/common/rs-client.sample.doctree b/doc/_build/doctrees/services/common/rs-client.sample.doctree new file mode 100644 index 000000000..de4a12bee Binary files /dev/null and b/doc/_build/doctrees/services/common/rs-client.sample.doctree differ diff --git a/doc/_build/doctrees/services/common/rs-only.sample.doctree b/doc/_build/doctrees/services/common/rs-only.sample.doctree new file mode 100644 index 000000000..c087b50e2 Binary files /dev/null and b/doc/_build/doctrees/services/common/rs-only.sample.doctree differ diff --git a/doc/_build/doctrees/services/common/service-args.doctree b/doc/_build/doctrees/services/common/service-args.doctree new file mode 100644 index 000000000..1027c1f60 Binary files /dev/null and b/doc/_build/doctrees/services/common/service-args.doctree differ diff --git a/doc/_build/doctrees/services/compute/Images.md.doctree b/doc/_build/doctrees/services/compute/Images.md.doctree new file mode 100644 index 000000000..6002d5bd9 Binary files /dev/null and b/doc/_build/doctrees/services/compute/Images.md.doctree differ diff --git a/doc/_build/doctrees/services/compute/Keypair.md.doctree b/doc/_build/doctrees/services/compute/Keypair.md.doctree new file mode 100644 index 000000000..87052e9b7 Binary files /dev/null and b/doc/_build/doctrees/services/compute/Keypair.md.doctree differ diff --git a/doc/_build/doctrees/services/compute/Server.md.doctree b/doc/_build/doctrees/services/compute/Server.md.doctree new file mode 100644 index 000000000..41b786999 Binary files /dev/null and b/doc/_build/doctrees/services/compute/Server.md.doctree differ diff --git a/doc/_build/doctrees/services/compute/Service.md.doctree b/doc/_build/doctrees/services/compute/Service.md.doctree new file mode 100644 index 000000000..ada2a1d5a Binary files /dev/null and b/doc/_build/doctrees/services/compute/Service.md.doctree differ diff --git a/doc/_build/doctrees/services/compute/flavors.doctree b/doc/_build/doctrees/services/compute/flavors.doctree new file mode 100644 index 000000000..fb8234568 Binary files /dev/null and b/doc/_build/doctrees/services/compute/flavors.doctree differ diff --git a/doc/_build/doctrees/services/compute/images.doctree b/doc/_build/doctrees/services/compute/images.doctree new file mode 100644 index 000000000..621fc08e6 Binary files /dev/null and b/doc/_build/doctrees/services/compute/images.doctree differ diff --git a/doc/_build/doctrees/services/compute/index.doctree b/doc/_build/doctrees/services/compute/index.doctree new file mode 100644 index 000000000..fb2586066 Binary files /dev/null and b/doc/_build/doctrees/services/compute/index.doctree differ diff --git a/doc/_build/doctrees/services/compute/keypair.doctree b/doc/_build/doctrees/services/compute/keypair.doctree new file mode 100644 index 000000000..6b5775211 Binary files /dev/null and b/doc/_build/doctrees/services/compute/keypair.doctree differ diff --git a/doc/_build/doctrees/services/compute/keypairs.doctree b/doc/_build/doctrees/services/compute/keypairs.doctree new file mode 100644 index 000000000..1555d7ab8 Binary files /dev/null and b/doc/_build/doctrees/services/compute/keypairs.doctree differ diff --git a/doc/_build/doctrees/services/compute/server.doctree b/doc/_build/doctrees/services/compute/server.doctree new file mode 100644 index 000000000..c7fcc0462 Binary files /dev/null and b/doc/_build/doctrees/services/compute/server.doctree differ diff --git a/doc/_build/doctrees/services/compute/servers.doctree b/doc/_build/doctrees/services/compute/servers.doctree new file mode 100644 index 000000000..ff14d965f Binary files /dev/null and b/doc/_build/doctrees/services/compute/servers.doctree differ diff --git a/doc/_build/doctrees/services/compute/service.sample.doctree b/doc/_build/doctrees/services/compute/service.sample.doctree new file mode 100644 index 000000000..d29b3c5ba Binary files /dev/null and b/doc/_build/doctrees/services/compute/service.sample.doctree differ diff --git a/doc/_build/doctrees/services/database/README.md.doctree b/doc/_build/doctrees/services/database/README.md.doctree new file mode 100644 index 000000000..f43ebad5d Binary files /dev/null and b/doc/_build/doctrees/services/database/README.md.doctree differ diff --git a/doc/_build/doctrees/services/database/configurations.doctree b/doc/_build/doctrees/services/database/configurations.doctree new file mode 100644 index 000000000..1b2ca99d4 Binary files /dev/null and b/doc/_build/doctrees/services/database/configurations.doctree differ diff --git a/doc/_build/doctrees/services/database/databases.doctree b/doc/_build/doctrees/services/database/databases.doctree new file mode 100644 index 000000000..7c1afa4a5 Binary files /dev/null and b/doc/_build/doctrees/services/database/databases.doctree differ diff --git a/doc/_build/doctrees/services/database/datastores.doctree b/doc/_build/doctrees/services/database/datastores.doctree new file mode 100644 index 000000000..ff6448286 Binary files /dev/null and b/doc/_build/doctrees/services/database/datastores.doctree differ diff --git a/doc/_build/doctrees/services/database/index.doctree b/doc/_build/doctrees/services/database/index.doctree new file mode 100644 index 000000000..00858d04f Binary files /dev/null and b/doc/_build/doctrees/services/database/index.doctree differ diff --git a/doc/_build/doctrees/services/database/instances.doctree b/doc/_build/doctrees/services/database/instances.doctree new file mode 100644 index 000000000..e5287f0d7 Binary files /dev/null and b/doc/_build/doctrees/services/database/instances.doctree differ diff --git a/doc/_build/doctrees/services/database/service.sample.doctree b/doc/_build/doctrees/services/database/service.sample.doctree new file mode 100644 index 000000000..da9ffe765 Binary files /dev/null and b/doc/_build/doctrees/services/database/service.sample.doctree differ diff --git a/doc/_build/doctrees/services/database/users.doctree b/doc/_build/doctrees/services/database/users.doctree new file mode 100644 index 000000000..2f3ff75db Binary files /dev/null and b/doc/_build/doctrees/services/database/users.doctree differ diff --git a/doc/_build/doctrees/services/dns/Domains.md.doctree b/doc/_build/doctrees/services/dns/Domains.md.doctree new file mode 100644 index 000000000..4dcf49cc0 Binary files /dev/null and b/doc/_build/doctrees/services/dns/Domains.md.doctree differ diff --git a/doc/_build/doctrees/services/dns/Limits.md.doctree b/doc/_build/doctrees/services/dns/Limits.md.doctree new file mode 100644 index 000000000..eb73f8985 Binary files /dev/null and b/doc/_build/doctrees/services/dns/Limits.md.doctree differ diff --git a/doc/_build/doctrees/services/dns/Records.md.doctree b/doc/_build/doctrees/services/dns/Records.md.doctree new file mode 100644 index 000000000..6318320cd Binary files /dev/null and b/doc/_build/doctrees/services/dns/Records.md.doctree differ diff --git a/doc/_build/doctrees/services/dns/Reverse-DNS.md.doctree b/doc/_build/doctrees/services/dns/Reverse-DNS.md.doctree new file mode 100644 index 000000000..5f45765f2 Binary files /dev/null and b/doc/_build/doctrees/services/dns/Reverse-DNS.md.doctree differ diff --git a/doc/_build/doctrees/services/dns/Service.md.doctree b/doc/_build/doctrees/services/dns/Service.md.doctree new file mode 100644 index 000000000..d1ec67dac Binary files /dev/null and b/doc/_build/doctrees/services/dns/Service.md.doctree differ diff --git a/doc/_build/doctrees/services/dns/domains.doctree b/doc/_build/doctrees/services/dns/domains.doctree new file mode 100644 index 000000000..87eb58032 Binary files /dev/null and b/doc/_build/doctrees/services/dns/domains.doctree differ diff --git a/doc/_build/doctrees/services/dns/index.doctree b/doc/_build/doctrees/services/dns/index.doctree new file mode 100644 index 000000000..6c0a00920 Binary files /dev/null and b/doc/_build/doctrees/services/dns/index.doctree differ diff --git a/doc/_build/doctrees/services/dns/limits.doctree b/doc/_build/doctrees/services/dns/limits.doctree new file mode 100644 index 000000000..23c8c2967 Binary files /dev/null and b/doc/_build/doctrees/services/dns/limits.doctree differ diff --git a/doc/_build/doctrees/services/dns/records.doctree b/doc/_build/doctrees/services/dns/records.doctree new file mode 100644 index 000000000..38ed0eea4 Binary files /dev/null and b/doc/_build/doctrees/services/dns/records.doctree differ diff --git a/doc/_build/doctrees/services/dns/reverse-dns.doctree b/doc/_build/doctrees/services/dns/reverse-dns.doctree new file mode 100644 index 000000000..71836ec2e Binary files /dev/null and b/doc/_build/doctrees/services/dns/reverse-dns.doctree differ diff --git a/doc/_build/doctrees/services/identity/Roles.md.doctree b/doc/_build/doctrees/services/identity/Roles.md.doctree new file mode 100644 index 000000000..ec1b2c3de Binary files /dev/null and b/doc/_build/doctrees/services/identity/Roles.md.doctree differ diff --git a/doc/_build/doctrees/services/identity/Service.md.doctree b/doc/_build/doctrees/services/identity/Service.md.doctree new file mode 100644 index 000000000..57afa3527 Binary files /dev/null and b/doc/_build/doctrees/services/identity/Service.md.doctree differ diff --git a/doc/_build/doctrees/services/identity/Tenants.md.doctree b/doc/_build/doctrees/services/identity/Tenants.md.doctree new file mode 100644 index 000000000..4bd673d1c Binary files /dev/null and b/doc/_build/doctrees/services/identity/Tenants.md.doctree differ diff --git a/doc/_build/doctrees/services/identity/Tokens.md.doctree b/doc/_build/doctrees/services/identity/Tokens.md.doctree new file mode 100644 index 000000000..dd41dcc49 Binary files /dev/null and b/doc/_build/doctrees/services/identity/Tokens.md.doctree differ diff --git a/doc/_build/doctrees/services/identity/Users.md.doctree b/doc/_build/doctrees/services/identity/Users.md.doctree new file mode 100644 index 000000000..7d113d585 Binary files /dev/null and b/doc/_build/doctrees/services/identity/Users.md.doctree differ diff --git a/doc/_build/doctrees/services/identity/index.doctree b/doc/_build/doctrees/services/identity/index.doctree new file mode 100644 index 000000000..0d4886c98 Binary files /dev/null and b/doc/_build/doctrees/services/identity/index.doctree differ diff --git a/doc/_build/doctrees/services/identity/roles.doctree b/doc/_build/doctrees/services/identity/roles.doctree new file mode 100644 index 000000000..5c6616b61 Binary files /dev/null and b/doc/_build/doctrees/services/identity/roles.doctree differ diff --git a/doc/_build/doctrees/services/identity/tenants.doctree b/doc/_build/doctrees/services/identity/tenants.doctree new file mode 100644 index 000000000..88f924493 Binary files /dev/null and b/doc/_build/doctrees/services/identity/tenants.doctree differ diff --git a/doc/_build/doctrees/services/identity/tokens.doctree b/doc/_build/doctrees/services/identity/tokens.doctree new file mode 100644 index 000000000..03574cbbb Binary files /dev/null and b/doc/_build/doctrees/services/identity/tokens.doctree differ diff --git a/doc/_build/doctrees/services/identity/users.doctree b/doc/_build/doctrees/services/identity/users.doctree new file mode 100644 index 000000000..5f42ff8cf Binary files /dev/null and b/doc/_build/doctrees/services/identity/users.doctree differ diff --git a/doc/_build/doctrees/services/image/Images.md.doctree b/doc/_build/doctrees/services/image/Images.md.doctree new file mode 100644 index 000000000..27aada00d Binary files /dev/null and b/doc/_build/doctrees/services/image/Images.md.doctree differ diff --git a/doc/_build/doctrees/services/image/Schemas.md.doctree b/doc/_build/doctrees/services/image/Schemas.md.doctree new file mode 100644 index 000000000..a0becfc3b Binary files /dev/null and b/doc/_build/doctrees/services/image/Schemas.md.doctree differ diff --git a/doc/_build/doctrees/services/image/Sharing.md.doctree b/doc/_build/doctrees/services/image/Sharing.md.doctree new file mode 100644 index 000000000..8b0dfa55f Binary files /dev/null and b/doc/_build/doctrees/services/image/Sharing.md.doctree differ diff --git a/doc/_build/doctrees/services/image/Tags.md.doctree b/doc/_build/doctrees/services/image/Tags.md.doctree new file mode 100644 index 000000000..6cd78bb2b Binary files /dev/null and b/doc/_build/doctrees/services/image/Tags.md.doctree differ diff --git a/doc/_build/doctrees/services/image/images.doctree b/doc/_build/doctrees/services/image/images.doctree new file mode 100644 index 000000000..49fc9f614 Binary files /dev/null and b/doc/_build/doctrees/services/image/images.doctree differ diff --git a/doc/_build/doctrees/services/image/index.doctree b/doc/_build/doctrees/services/image/index.doctree new file mode 100644 index 000000000..ea04800dc Binary files /dev/null and b/doc/_build/doctrees/services/image/index.doctree differ diff --git a/doc/_build/doctrees/services/image/schemas.doctree b/doc/_build/doctrees/services/image/schemas.doctree new file mode 100644 index 000000000..f8c49635b Binary files /dev/null and b/doc/_build/doctrees/services/image/schemas.doctree differ diff --git a/doc/_build/doctrees/services/image/sharing.doctree b/doc/_build/doctrees/services/image/sharing.doctree new file mode 100644 index 000000000..6a29cc3fa Binary files /dev/null and b/doc/_build/doctrees/services/image/sharing.doctree differ diff --git a/doc/_build/doctrees/services/image/tags.doctree b/doc/_build/doctrees/services/image/tags.doctree new file mode 100644 index 000000000..b74e3100d Binary files /dev/null and b/doc/_build/doctrees/services/image/tags.doctree differ diff --git a/doc/_build/doctrees/services/index.doctree b/doc/_build/doctrees/services/index.doctree new file mode 100644 index 000000000..66ac9ffea Binary files /dev/null and b/doc/_build/doctrees/services/index.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/README.md.doctree b/doc/_build/doctrees/services/load-balancer/README.md.doctree new file mode 100644 index 000000000..34e690cf0 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/README.md.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/USERGUIDE.md.doctree b/doc/_build/doctrees/services/load-balancer/USERGUIDE.md.doctree new file mode 100644 index 000000000..4496533f3 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/USERGUIDE.md.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/access.doctree b/doc/_build/doctrees/services/load-balancer/access.doctree new file mode 100644 index 000000000..1386f1132 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/access.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/caching.doctree b/doc/_build/doctrees/services/load-balancer/caching.doctree new file mode 100644 index 000000000..84d22fd2b Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/caching.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/errors.doctree b/doc/_build/doctrees/services/load-balancer/errors.doctree new file mode 100644 index 000000000..a9540bb0c Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/errors.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/index.doctree b/doc/_build/doctrees/services/load-balancer/index.doctree new file mode 100644 index 000000000..a65adf247 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/index.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/lb-setup.sample.doctree b/doc/_build/doctrees/services/load-balancer/lb-setup.sample.doctree new file mode 100644 index 000000000..365d5a3e2 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/lb-setup.sample.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/load-balancer.doctree b/doc/_build/doctrees/services/load-balancer/load-balancer.doctree new file mode 100644 index 000000000..581c6dbf8 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/load-balancer.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/logging.doctree b/doc/_build/doctrees/services/load-balancer/logging.doctree new file mode 100644 index 000000000..22fc175e6 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/logging.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/metadata.doctree b/doc/_build/doctrees/services/load-balancer/metadata.doctree new file mode 100644 index 000000000..35926c153 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/metadata.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/monitors.doctree b/doc/_build/doctrees/services/load-balancer/monitors.doctree new file mode 100644 index 000000000..d62a8dbb7 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/monitors.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/nodes.doctree b/doc/_build/doctrees/services/load-balancer/nodes.doctree new file mode 100644 index 000000000..e11c4dc36 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/nodes.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/sessions.doctree b/doc/_build/doctrees/services/load-balancer/sessions.doctree new file mode 100644 index 000000000..9171eef3e Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/sessions.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/ssl.doctree b/doc/_build/doctrees/services/load-balancer/ssl.doctree new file mode 100644 index 000000000..0c715a1ec Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/ssl.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/stats.doctree b/doc/_build/doctrees/services/load-balancer/stats.doctree new file mode 100644 index 000000000..7e39590f0 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/stats.doctree differ diff --git a/doc/_build/doctrees/services/load-balancer/virtual-ips.doctree b/doc/_build/doctrees/services/load-balancer/virtual-ips.doctree new file mode 100644 index 000000000..b36874513 Binary files /dev/null and b/doc/_build/doctrees/services/load-balancer/virtual-ips.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Agents.md.doctree b/doc/_build/doctrees/services/monitoring/Agents.md.doctree new file mode 100644 index 000000000..58d32847b Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Agents.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Alarms.md.doctree b/doc/_build/doctrees/services/monitoring/Alarms.md.doctree new file mode 100644 index 000000000..a68520008 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Alarms.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Changelogs.md.doctree b/doc/_build/doctrees/services/monitoring/Changelogs.md.doctree new file mode 100644 index 000000000..79439d5dd Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Changelogs.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Checks.md.doctree b/doc/_build/doctrees/services/monitoring/Checks.md.doctree new file mode 100644 index 000000000..3110af534 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Checks.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Entities.md.doctree b/doc/_build/doctrees/services/monitoring/Entities.md.doctree new file mode 100644 index 000000000..8197caf8b Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Entities.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Metrics.md.doctree b/doc/_build/doctrees/services/monitoring/Metrics.md.doctree new file mode 100644 index 000000000..13f77e70d Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Metrics.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Notifications.md.doctree b/doc/_build/doctrees/services/monitoring/Notifications.md.doctree new file mode 100644 index 000000000..5591d3aea Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Notifications.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Service.md.doctree b/doc/_build/doctrees/services/monitoring/Service.md.doctree new file mode 100644 index 000000000..a1a26ef5f Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Service.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Views.md.doctree b/doc/_build/doctrees/services/monitoring/Views.md.doctree new file mode 100644 index 000000000..f32696c1d Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Views.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/Zones.md.doctree b/doc/_build/doctrees/services/monitoring/Zones.md.doctree new file mode 100644 index 000000000..c0337c497 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/Zones.md.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/agents.doctree b/doc/_build/doctrees/services/monitoring/agents.doctree new file mode 100644 index 000000000..910060974 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/agents.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/alarms.doctree b/doc/_build/doctrees/services/monitoring/alarms.doctree new file mode 100644 index 000000000..5029ce7ed Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/alarms.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/changelogs.doctree b/doc/_build/doctrees/services/monitoring/changelogs.doctree new file mode 100644 index 000000000..0f5634d01 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/changelogs.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/checks.doctree b/doc/_build/doctrees/services/monitoring/checks.doctree new file mode 100644 index 000000000..4d43f2cb9 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/checks.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/entities.doctree b/doc/_build/doctrees/services/monitoring/entities.doctree new file mode 100644 index 000000000..b01735485 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/entities.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/index.doctree b/doc/_build/doctrees/services/monitoring/index.doctree new file mode 100644 index 000000000..1d07fc871 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/index.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/metrics.doctree b/doc/_build/doctrees/services/monitoring/metrics.doctree new file mode 100644 index 000000000..d9f71a306 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/metrics.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/notifications.doctree b/doc/_build/doctrees/services/monitoring/notifications.doctree new file mode 100644 index 000000000..7f150e459 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/notifications.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/views.doctree b/doc/_build/doctrees/services/monitoring/views.doctree new file mode 100644 index 000000000..3244afd63 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/views.doctree differ diff --git a/doc/_build/doctrees/services/monitoring/zones.doctree b/doc/_build/doctrees/services/monitoring/zones.doctree new file mode 100644 index 000000000..813107fd4 Binary files /dev/null and b/doc/_build/doctrees/services/monitoring/zones.doctree differ diff --git a/doc/_build/doctrees/services/networking/README.md.doctree b/doc/_build/doctrees/services/networking/README.md.doctree new file mode 100644 index 000000000..ab827e40c Binary files /dev/null and b/doc/_build/doctrees/services/networking/README.md.doctree differ diff --git a/doc/_build/doctrees/services/networking/USERGUIDE.md.doctree b/doc/_build/doctrees/services/networking/USERGUIDE.md.doctree new file mode 100644 index 000000000..595d7c259 Binary files /dev/null and b/doc/_build/doctrees/services/networking/USERGUIDE.md.doctree differ diff --git a/doc/_build/doctrees/services/networking/index.doctree b/doc/_build/doctrees/services/networking/index.doctree new file mode 100644 index 000000000..fd58e44cb Binary files /dev/null and b/doc/_build/doctrees/services/networking/index.doctree differ diff --git a/doc/_build/doctrees/services/networking/networks.doctree b/doc/_build/doctrees/services/networking/networks.doctree new file mode 100644 index 000000000..e2f9dc114 Binary files /dev/null and b/doc/_build/doctrees/services/networking/networks.doctree differ diff --git a/doc/_build/doctrees/services/networking/ports.doctree b/doc/_build/doctrees/services/networking/ports.doctree new file mode 100644 index 000000000..68e747bd4 Binary files /dev/null and b/doc/_build/doctrees/services/networking/ports.doctree differ diff --git a/doc/_build/doctrees/services/networking/security-group-rules.doctree b/doc/_build/doctrees/services/networking/security-group-rules.doctree new file mode 100644 index 000000000..e869f80fa Binary files /dev/null and b/doc/_build/doctrees/services/networking/security-group-rules.doctree differ diff --git a/doc/_build/doctrees/services/networking/security-groups.doctree b/doc/_build/doctrees/services/networking/security-groups.doctree new file mode 100644 index 000000000..2c13db9de Binary files /dev/null and b/doc/_build/doctrees/services/networking/security-groups.doctree differ diff --git a/doc/_build/doctrees/services/networking/subnets.doctree b/doc/_build/doctrees/services/networking/subnets.doctree new file mode 100644 index 000000000..b1f486be8 Binary files /dev/null and b/doc/_build/doctrees/services/networking/subnets.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Access.md.doctree b/doc/_build/doctrees/services/object-store/Access.md.doctree new file mode 100644 index 000000000..0a0b56eab Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Access.md.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Account.md.doctree b/doc/_build/doctrees/services/object-store/Account.md.doctree new file mode 100644 index 000000000..e40aef4cb Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Account.md.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Container.md.cdn.doctree b/doc/_build/doctrees/services/object-store/Container.md.cdn.doctree new file mode 100644 index 000000000..f77efdab8 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Container.md.cdn.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Container.md.storage.doctree b/doc/_build/doctrees/services/object-store/Container.md.storage.doctree new file mode 100644 index 000000000..9253d676a Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Container.md.storage.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Migrating.md.storage.doctree b/doc/_build/doctrees/services/object-store/Migrating.md.storage.doctree new file mode 100644 index 000000000..ec37376a8 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Migrating.md.storage.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Object.md.cdn.doctree b/doc/_build/doctrees/services/object-store/Object.md.cdn.doctree new file mode 100644 index 000000000..6f9a4cea6 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Object.md.cdn.doctree differ diff --git a/doc/_build/doctrees/services/object-store/Object.md.storage.doctree b/doc/_build/doctrees/services/object-store/Object.md.storage.doctree new file mode 100644 index 000000000..d45ce3c71 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/Object.md.storage.doctree differ diff --git a/doc/_build/doctrees/services/object-store/README.md.doctree b/doc/_build/doctrees/services/object-store/README.md.doctree new file mode 100644 index 000000000..686a712b2 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/README.md.doctree differ diff --git a/doc/_build/doctrees/services/object-store/USERGUIDE.md.doctree b/doc/_build/doctrees/services/object-store/USERGUIDE.md.doctree new file mode 100644 index 000000000..0d4c777b8 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/USERGUIDE.md.doctree differ diff --git a/doc/_build/doctrees/services/object-store/access.doctree b/doc/_build/doctrees/services/object-store/access.doctree new file mode 100644 index 000000000..7e92330c6 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/access.doctree differ diff --git a/doc/_build/doctrees/services/object-store/account.doctree b/doc/_build/doctrees/services/object-store/account.doctree new file mode 100644 index 000000000..9384ca6e1 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/account.doctree differ diff --git a/doc/_build/doctrees/services/object-store/cdn.doctree b/doc/_build/doctrees/services/object-store/cdn.doctree new file mode 100644 index 000000000..ac85d5ed2 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/cdn.doctree differ diff --git a/doc/_build/doctrees/services/object-store/containers.doctree b/doc/_build/doctrees/services/object-store/containers.doctree new file mode 100644 index 000000000..dd54390bc Binary files /dev/null and b/doc/_build/doctrees/services/object-store/containers.doctree differ diff --git a/doc/_build/doctrees/services/object-store/index.doctree b/doc/_build/doctrees/services/object-store/index.doctree new file mode 100644 index 000000000..f3669757e Binary files /dev/null and b/doc/_build/doctrees/services/object-store/index.doctree differ diff --git a/doc/_build/doctrees/services/object-store/migrating-containers.doctree b/doc/_build/doctrees/services/object-store/migrating-containers.doctree new file mode 100644 index 000000000..879bd06ec Binary files /dev/null and b/doc/_build/doctrees/services/object-store/migrating-containers.doctree differ diff --git a/doc/_build/doctrees/services/object-store/objects.doctree b/doc/_build/doctrees/services/object-store/objects.doctree new file mode 100644 index 000000000..ddc9b3ca7 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/objects.doctree differ diff --git a/doc/_build/doctrees/services/object-store/rs-only.doctree b/doc/_build/doctrees/services/object-store/rs-only.doctree new file mode 100644 index 000000000..a007866b8 Binary files /dev/null and b/doc/_build/doctrees/services/object-store/rs-only.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/README.md.doctree b/doc/_build/doctrees/services/orchestration/README.md.doctree new file mode 100644 index 000000000..c83e1e453 Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/README.md.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/USERGUIDE.md.doctree b/doc/_build/doctrees/services/orchestration/USERGUIDE.md.doctree new file mode 100644 index 000000000..6f539a0ed Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/USERGUIDE.md.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/build-info.doctree b/doc/_build/doctrees/services/orchestration/build-info.doctree new file mode 100644 index 000000000..ba4319f0b Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/build-info.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/events.doctree b/doc/_build/doctrees/services/orchestration/events.doctree new file mode 100644 index 000000000..423416170 Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/events.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/index.doctree b/doc/_build/doctrees/services/orchestration/index.doctree new file mode 100644 index 000000000..fca3efa73 Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/index.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/resource-types.doctree b/doc/_build/doctrees/services/orchestration/resource-types.doctree new file mode 100644 index 000000000..2bfa5a6ed Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/resource-types.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/resources.doctree b/doc/_build/doctrees/services/orchestration/resources.doctree new file mode 100644 index 000000000..f65342c2d Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/resources.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/stacks.doctree b/doc/_build/doctrees/services/orchestration/stacks.doctree new file mode 100644 index 000000000..6b8df8f18 Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/stacks.doctree differ diff --git a/doc/_build/doctrees/services/orchestration/templates.doctree b/doc/_build/doctrees/services/orchestration/templates.doctree new file mode 100644 index 000000000..31a9416b6 Binary files /dev/null and b/doc/_build/doctrees/services/orchestration/templates.doctree differ diff --git a/doc/_build/doctrees/services/queues/Claim.md.doctree b/doc/_build/doctrees/services/queues/Claim.md.doctree new file mode 100644 index 000000000..2aaac997e Binary files /dev/null and b/doc/_build/doctrees/services/queues/Claim.md.doctree differ diff --git a/doc/_build/doctrees/services/queues/Message.md.doctree b/doc/_build/doctrees/services/queues/Message.md.doctree new file mode 100644 index 000000000..05bae7db7 Binary files /dev/null and b/doc/_build/doctrees/services/queues/Message.md.doctree differ diff --git a/doc/_build/doctrees/services/queues/Queue.md.doctree b/doc/_build/doctrees/services/queues/Queue.md.doctree new file mode 100644 index 000000000..432648360 Binary files /dev/null and b/doc/_build/doctrees/services/queues/Queue.md.doctree differ diff --git a/doc/_build/doctrees/services/queues/claims.doctree b/doc/_build/doctrees/services/queues/claims.doctree new file mode 100644 index 000000000..273db56e8 Binary files /dev/null and b/doc/_build/doctrees/services/queues/claims.doctree differ diff --git a/doc/_build/doctrees/services/queues/index.doctree b/doc/_build/doctrees/services/queues/index.doctree new file mode 100644 index 000000000..8e3b60341 Binary files /dev/null and b/doc/_build/doctrees/services/queues/index.doctree differ diff --git a/doc/_build/doctrees/services/queues/messages.doctree b/doc/_build/doctrees/services/queues/messages.doctree new file mode 100644 index 000000000..d7e276ff2 Binary files /dev/null and b/doc/_build/doctrees/services/queues/messages.doctree differ diff --git a/doc/_build/doctrees/services/queues/queues.doctree b/doc/_build/doctrees/services/queues/queues.doctree new file mode 100644 index 000000000..773851323 Binary files /dev/null and b/doc/_build/doctrees/services/queues/queues.doctree differ diff --git a/doc/_build/doctrees/services/volume/index.doctree b/doc/_build/doctrees/services/volume/index.doctree new file mode 100644 index 000000000..0d576b202 Binary files /dev/null and b/doc/_build/doctrees/services/volume/index.doctree differ diff --git a/doc/_build/doctrees/services/volume/snapshots.doctree b/doc/_build/doctrees/services/volume/snapshots.doctree new file mode 100644 index 000000000..41b745a3b Binary files /dev/null and b/doc/_build/doctrees/services/volume/snapshots.doctree differ diff --git a/doc/_build/doctrees/services/volume/volume-types.doctree b/doc/_build/doctrees/services/volume/volume-types.doctree new file mode 100644 index 000000000..9312757a9 Binary files /dev/null and b/doc/_build/doctrees/services/volume/volume-types.doctree differ diff --git a/doc/_build/doctrees/services/volume/volumes.doctree b/doc/_build/doctrees/services/volume/volumes.doctree new file mode 100644 index 000000000..2fc63a76c Binary files /dev/null and b/doc/_build/doctrees/services/volume/volumes.doctree differ diff --git a/doc/_build/doctrees/url-types.doctree b/doc/_build/doctrees/url-types.doctree new file mode 100644 index 000000000..2840a54f5 Binary files /dev/null and b/doc/_build/doctrees/url-types.doctree differ diff --git a/doc/_build/doctrees/using-php-5.3.doctree b/doc/_build/doctrees/using-php-5.3.doctree new file mode 100644 index 000000000..dfb43ad20 Binary files /dev/null and b/doc/_build/doctrees/using-php-5.3.doctree differ diff --git a/doc/_build/html/.buildinfo b/doc/_build/html/.buildinfo new file mode 100644 index 000000000..5ba10c9e0 --- /dev/null +++ b/doc/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: da7e999e4172075fe9536fec2c0e5662 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/_build/html/_sources/auth.txt b/doc/_build/html/_sources/auth.txt new file mode 100644 index 000000000..ce5ba7233 --- /dev/null +++ b/doc/_build/html/_sources/auth.txt @@ -0,0 +1,54 @@ +Authentication +============== + +The client does not automatically authenticate against the API when it is +instantiated - it waits for an API call. When this happens, it checks +whether the current “token” has expired, and (re-)authenticates if +necessary. + +You can force authentication, by calling: + +.. code-block:: php + + $client->authenticate(); + +If the credentials are incorrect, a ``401`` error will be returned. If +credentials are correct, a ``200`` status is returned with your Service +Catalog. + + +Service Catalog +--------------- + +The Service Catalog is returned on successful authentication, and is +composed of all the different API services available to the current +tenant. All of this functionality is encapsulated in the ``Catalog`` +object, which allows you greater control and interactivity. + +.. code-block:: php + + /** @var OpenCloud\Common\Service\Catalog */ + $catalog = $client->getCatalog(); + + // Return a list of OpenCloud\Common\Service\CatalogItem objects + foreach ($catalog->getItems() as $catalogItem) { + + $name = $catalogItem->getName(); + $type = $catalogItem->getType(); + + if ($name == 'cloudServersOpenStack' && $type == 'compute') { + break; + } + + // Array of OpenCloud\Common\Service\Endpoint objects + $endpoints = $catalogItem->getEndpoints(); + foreach ($endpoints as $endpoint) { + if ($endpoint->getRegion() == 'DFW') { + echo $endpoint->getPublicUrl(); + } + } + } + +As you can see, you have access to each Service’s name, type and list of +endpoints. Each endpoint provides access to the specific region, along +with its public and private endpoint URLs. diff --git a/doc/_build/html/_sources/caching-creds.txt b/doc/_build/html/_sources/caching-creds.txt new file mode 100644 index 000000000..4eb5be5c8 --- /dev/null +++ b/doc/_build/html/_sources/caching-creds.txt @@ -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/_build/html/_sources/customizing-clients.txt b/doc/_build/html/_sources/customizing-clients.txt new file mode 100644 index 000000000..ab3b6a441 --- /dev/null +++ b/doc/_build/html/_sources/customizing-clients.txt @@ -0,0 +1,144 @@ +Customizing Clients +=================== + +Logger injection +---------------- + +As the ``Rackspace`` client extends the ``OpenStack`` client, they both support +passing ``$options`` as an array via the constructor's third parameter. The +options are passed as a config to the `Guzzle` client, but also allow to inject +your own logger. + +Your logger should implement the ``Psr\Log\LoggerInterface`` `as defined in +PSR-3 `_. +One example of a compatible logger is `Monolog `_. +When the client does create a service, it will inject the logger if one is +available. + +To inject a ``LoggerInterface`` compatible logger into a new client: + +.. code-block:: php + + use Monolog\Logger; + use OpenCloud\OpenStack; + + // create a log channel + $logger = new Logger('name'); + + $client = new OpenStack('http://identity.my-openstack.com/v2.0', array( + 'username' => 'foo', + 'password' => 'bar' + ), array( + 'logger' => $logger, + )); + + +Authentication +-------------- + +The client does not automatically authenticate against the API when it is +instantiated - it waits for an API call. When this happens, it checks +whether the current “token” has expired, and (re-)authenticates if +necessary. + +You can force authentication, by calling: + +.. code-block:: php + + $client->authenticate(); + +If the credentials are incorrect, a ``401`` error will be returned. If +credentials are correct, a ``200`` status is returned with your Service +Catalog. + + +Service Catalog +--------------- + +The Service Catalog is returned on successful authentication, and is +composed of all the different API services available to the current +tenant. All of this functionality is encapsulated in the ``Catalog`` +object, which allows you greater control and interactivity. + +.. code-block:: php + + /** @var OpenCloud\Common\Service\Catalog */ + $catalog = $client->getCatalog(); + + // Return a list of OpenCloud\Common\Service\CatalogItem objects + foreach ($catalog->getItems() as $catalogItem) { + + $name = $catalogItem->getName(); + $type = $catalogItem->getType(); + + if ($name == 'cloudServersOpenStack' && $type == 'compute') { + break; + } + + // Array of OpenCloud\Common\Service\Endpoint objects + $endpoints = $catalogItem->getEndpoints(); + foreach ($endpoints as $endpoint) { + if ($endpoint->getRegion() == 'DFW') { + echo $endpoint->getPublicUrl(); + } + } + } + +As you can see, you have access to each Service’s name, type and list of +endpoints. Each endpoint provides access to the specific region, along +with its public and private endpoint URLs. + + +Default HTTP headers +-------------------- + +To set default HTTP headers: + +.. code-block:: php + + $client->setDefaultOption('headers/X-Custom-Header', 'FooBar'); + + +User agents +----------- + +php-opencloud will send a default ``User-Agent`` header for every HTTP +request, unless a custom value is provided by the end-user. The default +header will be in this format: + + User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz + +where ``xxx`` is the current version of the SDK, ``yyy`` is the current +version of cURL, and ``zzz`` is the current PHP version. To override +this default, you must run: + +.. code-block:: php + + $client->setUserAgent('MyCustomUserAgent'); + +which will result in: + + User-Agent: MyCustomUserAgent + +If you want to set a *prefix* for the user agent, but retain the default +``User-Agent`` as a suffix, you must run: + +.. code-block:: php + + $client->setUserAgent('MyPrefix', true); + +which will result in: + + User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz + +where ``$client`` is an instance of ``OpenCloud\OpenStack`` or +``OpenCloud\Rackspace``. + + +Other functionality +------------------- + +For a full list of functionality provided by Guzzle, please consult the +`official documentation`_. + +.. _official documentation: http://docs.guzzlephp.org/en/latest/http-client/client.html diff --git a/doc/_build/html/_sources/debugging.txt b/doc/_build/html/_sources/debugging.txt new file mode 100644 index 000000000..5d35d5bc1 --- /dev/null +++ b/doc/_build/html/_sources/debugging.txt @@ -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/_build/html/_sources/getting-started-with-openstack.txt b/doc/_build/html/_sources/getting-started-with-openstack.txt new file mode 100644 index 000000000..da6c6ee24 --- /dev/null +++ b/doc/_build/html/_sources/getting-started-with-openstack.txt @@ -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/_build/html/_sources/getting-started-with-rackspace.txt b/doc/_build/html/_sources/getting-started-with-rackspace.txt new file mode 100644 index 000000000..73aa3a8d4 --- /dev/null +++ b/doc/_build/html/_sources/getting-started-with-rackspace.txt @@ -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/_build/html/_sources/http-clients.txt b/doc/_build/html/_sources/http-clients.txt new file mode 100644 index 000000000..49828509b --- /dev/null +++ b/doc/_build/html/_sources/http-clients.txt @@ -0,0 +1,56 @@ +HTTP Clients +============ + +Default HTTP headers +-------------------- + +To set default HTTP headers: + +.. code-block:: php + + $client->setDefaultOption('headers/X-Custom-Header', 'FooBar'); + + +User agents +----------- + +php-opencloud will send a default ``User-Agent`` header for every HTTP +request, unless a custom value is provided by the end-user. The default +header will be in this format: + + User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz + +where ``xxx`` is the current version of the SDK, ``yyy`` is the current +version of cURL, and ``zzz`` is the current PHP version. To override +this default, you must run: + +.. code-block:: php + + $client->setUserAgent('MyCustomUserAgent'); + +which will result in: + + User-Agent: MyCustomUserAgent + +If you want to set a *prefix* for the user agent, but retain the default +``User-Agent`` as a suffix, you must run: + +.. code-block:: php + + $client->setUserAgent('MyPrefix', true); + +which will result in: + + User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz + +where ``$client`` is an instance of ``OpenCloud\OpenStack`` or +``OpenCloud\Rackspace``. + + +Other functionality +------------------- + +For a full list of functionality provided by Guzzle, please consult the +`official documentation`_. + +.. _official documentation: http://docs.guzzlephp.org/en/latest/http-client/client.html diff --git a/doc/_build/html/_sources/index.txt b/doc/_build/html/_sources/index.txt new file mode 100644 index 000000000..3c47091cc --- /dev/null +++ b/doc/_build/html/_sources/index.txt @@ -0,0 +1,80 @@ +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. + +.. note:: + + If you are running PHP 5.3, please see our :doc:`using-php-5.3` guide. + +Services +-------- + +.. toctree:: + :glob: + :maxdepth: 1 + + services/**/index + +Usage tips +---------- + +.. toctree:: + :maxdepth: 1 + + debugging + caching-creds + iterators + regions + url-types + logging + http-clients + auth + +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/_build/html/_sources/iterators.txt b/doc/_build/html/_sources/iterators.txt new file mode 100644 index 000000000..bef59e339 --- /dev/null +++ b/doc/_build/html/_sources/iterators.txt @@ -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/_build/html/_sources/logging.txt b/doc/_build/html/_sources/logging.txt new file mode 100644 index 000000000..bb2a3de09 --- /dev/null +++ b/doc/_build/html/_sources/logging.txt @@ -0,0 +1,33 @@ +Logging +======= + +Logger injection +---------------- + +As the ``Rackspace`` client extends the ``OpenStack`` client, they both support +passing ``$options`` as an array via the constructor's third parameter. The +options are passed as a config to the `Guzzle` client, but also allow to inject +your own logger. + +Your logger should implement the ``Psr\Log\LoggerInterface`` `as defined in +PSR-3 `_. +One example of a compatible logger is `Monolog `_. +When the client does create a service, it will inject the logger if one is +available. + +To inject a ``LoggerInterface`` compatible logger into a new client: + +.. code-block:: php + + use Monolog\Logger; + use OpenCloud\OpenStack; + + // create a log channel + $logger = new Logger('name'); + + $client = new OpenStack('http://identity.my-openstack.com/v2.0', array( + 'username' => 'foo', + 'password' => 'bar' + ), array( + 'logger' => $logger, + )); diff --git a/doc/_build/html/_sources/regions.txt b/doc/_build/html/_sources/regions.txt new file mode 100644 index 000000000..42c14595c --- /dev/null +++ b/doc/_build/html/_sources/regions.txt @@ -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/_build/html/_sources/services/autoscale/group-config.txt b/doc/_build/html/_sources/services/autoscale/group-config.txt new file mode 100644 index 000000000..5dcfb6ce4 --- /dev/null +++ b/doc/_build/html/_sources/services/autoscale/group-config.txt @@ -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/_build/html/_sources/services/autoscale/groups.txt b/doc/_build/html/_sources/services/autoscale/groups.txt new file mode 100644 index 000000000..a6caf3f9d --- /dev/null +++ b/doc/_build/html/_sources/services/autoscale/groups.txt @@ -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/_build/html/_sources/services/autoscale/index.txt b/doc/_build/html/_sources/services/autoscale/index.txt new file mode 100644 index 000000000..1bfd20e68 --- /dev/null +++ b/doc/_build/html/_sources/services/autoscale/index.txt @@ -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/_build/html/_sources/services/autoscale/policies.txt b/doc/_build/html/_sources/services/autoscale/policies.txt new file mode 100644 index 000000000..e103d328e --- /dev/null +++ b/doc/_build/html/_sources/services/autoscale/policies.txt @@ -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/_build/html/_sources/services/autoscale/service.sample.txt b/doc/_build/html/_sources/services/autoscale/service.sample.txt new file mode 100644 index 000000000..dc9a94fbd --- /dev/null +++ b/doc/_build/html/_sources/services/autoscale/service.sample.txt @@ -0,0 +1,9 @@ +.. include:: ../common/rs-client.sample.rst + +Now, set up the Auto Scale service: + +.. code-block:: php + + $service = $client->autoscaleService(); + +.. include:: ../common/service-args.rst diff --git a/doc/_build/html/_sources/services/autoscale/webhooks.txt b/doc/_build/html/_sources/services/autoscale/webhooks.txt new file mode 100644 index 000000000..9133aa9ed --- /dev/null +++ b/doc/_build/html/_sources/services/autoscale/webhooks.txt @@ -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/_build/html/_sources/services/common/clients.sample.txt b/doc/_build/html/_sources/services/common/clients.sample.txt new file mode 100644 index 000000000..a952da730 --- /dev/null +++ b/doc/_build/html/_sources/services/common/clients.sample.txt @@ -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/_build/html/_sources/services/common/os-client.sample.txt b/doc/_build/html/_sources/services/common/os-client.sample.txt new file mode 100644 index 000000000..b00e0dece --- /dev/null +++ b/doc/_build/html/_sources/services/common/os-client.sample.txt @@ -0,0 +1,9 @@ +or if you're an OpenStack user: + +.. code-block:: php + + $client = new OpenCloud\OpenStack('{keystoneUrl}', array( + 'username' => '{username}', + 'password' => '{apiKey}', + 'tenantId' => '{tenantId}', + )); diff --git a/doc/_build/html/_sources/services/common/rs-client.sample.txt b/doc/_build/html/_sources/services/common/rs-client.sample.txt new file mode 100644 index 000000000..88a37d819 --- /dev/null +++ b/doc/_build/html/_sources/services/common/rs-client.sample.txt @@ -0,0 +1,29 @@ +Rackspace setup +~~~~~~~~~~~~~~~ + +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}', + )); + + +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/_build/html/_sources/services/common/rs-client.txt b/doc/_build/html/_sources/services/common/rs-client.txt new file mode 100644 index 000000000..46f9a5291 --- /dev/null +++ b/doc/_build/html/_sources/services/common/rs-client.txt @@ -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/_build/html/_sources/services/common/rs-only.sample.txt b/doc/_build/html/_sources/services/common/rs-only.sample.txt new file mode 100644 index 000000000..9a1ccdf93 --- /dev/null +++ b/doc/_build/html/_sources/services/common/rs-only.sample.txt @@ -0,0 +1,8 @@ +.. note:: + + This service is only available for Rackspace users. + +Setup +----- + +.. include:: /services/common/rs-client.rst diff --git a/doc/_build/html/_sources/services/common/service-args.txt b/doc/_build/html/_sources/services/common/service-args.txt new file mode 100644 index 000000000..c1cc754b8 --- /dev/null +++ b/doc/_build/html/_sources/services/common/service-args.txt @@ -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/_build/html/_sources/services/compute/Images.md.txt b/doc/_build/html/_sources/services/compute/Images.md.txt new file mode 100644 index 000000000..66f1fff83 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/Images.md.txt @@ -0,0 +1,98 @@ +Compute Images +============== + +Intro +----- + +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. + +In addition to creating images manually, you can also schedule images of +your server automatically. Please consult the `official +docs `__ +for more information about this extension, including enabling and +disabling scheduled images and showing scheduled images. + +With standard servers, the entire disk (OS and data) is captured in the +image. With Performance servers, only the system 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. + +Setup +----- + +You first need to setup a Compute service. For information, please +consult the `Compute service `__ documentation. + +List images +----------- + +.. code:: php + + $images = $service->imageList(); + + foreach ($images as $image) { + + } + +For more information about `iterators `__, +please consult the official documentation. + +Query parameters +~~~~~~~~~~~~~~~~ + +You can also refine the list of images returned by providing specific +URL parameters: + ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Field name | 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``. | ++-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Example +~~~~~~~ + +You can return more information about each image by setting the +``$details`` argument to ``true``. The second argument can be an array +of query parameters: + +.. code:: php + + use OpenCloud\Compute\Constants\ImageState; + + $list = $service->imageList(true, array( + 'server' => 'fooBar', + 'status' => ImageState::ACTIVE + )); + +Get an image +------------ + +.. code:: php + + $imageId = '3afe97b2-26dc-49c5-a2cc-a2fc8d80c001'; + $image = $service->image($imageId); + +Delete an image +--------------- + +.. code:: php + + $image->delete(); + diff --git a/doc/_build/html/_sources/services/compute/Keypair.md.txt b/doc/_build/html/_sources/services/compute/Keypair.md.txt new file mode 100644 index 000000000..46f3e3795 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/Keypair.md.txt @@ -0,0 +1,103 @@ +Keypairs +======== + +Generate new keypair +-------------------- + +This operation creates a new keypair under a provided name; the public +key value is automatically generated for you. + +.. code:: php + + $keypair = $service->keypair(); + + $keypair->create(array( + 'name' => 'jamie_keypair_1' + )); + + echo $keypair->getPublicKey(); + + // Save private key to a file so you can use it to SSH into + // your server later. + $sshPrivateKeyFilename = 'jamie_keypair_1_rsa'; + $privateKey = $keypair->getPrivateKey(); + file_put_contents($sshPrivateKeyFilename, $privateKey); + chmod($sshPrivateKeyFilename, 0600); + +Upload existing keypair +----------------------- + +This operation creates a new keypair under a provided name using a +provided public key value. This public key will probably exist on your +local filesystem, and so provide easy access to your server when +uploaded. + +.. code:: php + + $keypair = $service->keypair(); + + $key = <<create(array( + 'name' => 'jamie_macbook', + 'publicKey' => $key + )); + +List keypairs +------------- + +To list all existing keypairs: + +.. code:: php + + $keys = $service->listKeypairs(); + + foreach ($keys as $key) { + // ... + } + +For more information about iterators, please see `the +docs <../Iterators.md>`__. + +Delete keypairs +--------------- + +To delete a specific keypair: + +.. code:: php + + $keypair->delete(); + +Creating a server with a keypair +-------------------------------- + +In order to spawn 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:: php + + use Guzzle\Http\Exception\BadResponseException; + use OpenCloud\Compute\Constants\Network; + + $server = $compute->server(); + + try { + $response = $server->create(array( + 'name' => 'New server', + 'image' => $ubuntuImage, + 'flavor' => $twoGbFlavor, + 'networks' => array( + $compute->network(Network::RAX_PUBLIC), + $compute->network(Network::RAX_PRIVATE) + ), + 'keypair' => 'jamie_macbook' + )); + } catch (BadResponseException $e) { + // error... + } + +So, as you can see, you specify the **name** of an existing keypair that +you previously created on the API. diff --git a/doc/_build/html/_sources/services/compute/Server.md.txt b/doc/_build/html/_sources/services/compute/Server.md.txt new file mode 100644 index 000000000..871071e17 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/Server.md.txt @@ -0,0 +1,242 @@ +Servers +======= + +Intro +----- + +A server is a virtual machine instance in the Cloud Servers environment. + +Setup +----- + +Server objects are instantiated from the Compute service. For more +details, see the `Service `__ docs. + +Get server +---------- + +The easiest way to retrieve a specific server is by its unique ID: + +.. code:: php + + $serverId = 'ef08aa7a-b5e4-4bb8-86df-5ac56230f841'; + $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:: 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 +~~~~~~~~~~~~~~ + +There are a few parameter requirements when creating a server using an +image: + +- **name** - needs to be a string; +- **flavor** - a ``OpenCloud\Compute\Resource\Flavor`` object, that is + populated with the values of a real API flavor; +- **image** - a ``OpenCloud\Compute\Resource\Image`` object, that is + populated with the values of a real API image; + +Firstly we need to find our flavor and image using their UUIDs. For more +information about these concepts, including how to find flavor/image +UUIDs, please consult §§ 3-4 in the `Getting Started +guide `__. + +.. code:: php + + $ubuntuImage = $compute->image('868a0966-0553-42fe-b8b3-5cadc0e0b3c5'); + $twoGbFlavor = $compute->flavor('4'); + +Now we're ready to create our instance: + +.. code:: php + + use OpenCloud\Compute\Constants\Network; + + $server = $compute->server(); + + try { + $response = $server->create(array( + 'name' => 'My lovely server', + 'image' => $ubuntuImage, + 'flavor' => $twoGbFlavor + )); + } catch (\Guzzle\Http\Exception\BadResponseException $e) { + + // No! Something failed. Let's find out: + $responseBody = (string) $e->getResponse()->getBody(); + $statusCode = $e->getResponse()->getStatusCode(); + $headers = $e->getResponse()->getHeaderLines(); + + echo sprintf('Status: %s\nBody: %s\nHeaders: %s', $statusCode, $responseBody, implode(', ', $headers); + } + +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 +~~~~~~~~~~~~~~~~~~~~~~~ + +There are a few parameter requirements when creating a server using a +bootable volume: + +- **name** - needs to be a string; +- **flavor** - a ``OpenCloud\Compute\Resource\Flavor`` object, that is + populated with the values of a real API flavor; +- **volume** - a ``OpenCloud\Volume\Resource\Volume`` object, that is + populated with the values of a real API volume; + +Firstly we need to find our flavor and volume using their IDs. + +.. code:: php + + $volumeService = $client->volumeService(); + $bootableVolume = $volumeService->volume(''); + $flavor = $compute->flavor(''); + +Now we're ready to create our instance: + +.. code:: php + + use OpenCloud\Compute\Constants\Network; + + $server = $compute->server(); + + try { + $response = $server->create(array( + 'name' => 'My lovely server', + 'volume' => $bootableVolume, + 'flavor' => $flavor + )); + } catch (\Guzzle\Http\Exception\BadResponseException $e) { + // No! Something failed. Let's find out: + echo $e->getRequest() . PHP_EOL . PHP_EOL; + echo $e->getResponse(); + } + +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 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Please see the `Keypair `__ docs for more information. + +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:: 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:: 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:: php + + $server->delete(); + diff --git a/doc/_build/html/_sources/services/compute/Service.md.txt b/doc/_build/html/_sources/services/compute/Service.md.txt new file mode 100644 index 000000000..bc0e8cb28 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/Service.md.txt @@ -0,0 +1,27 @@ +Compute service +=============== + +Setup +----- + +To instantiate a Compute service object, you first need to setup a +Rackspace/OpenStack client. To do this, or for more information, please +consult the `Clients documentation <../Clients.md>`__. + +.. code:: php + + $service = $client->computeService(); + +If no arguments are provided to the above method, certain values are set +to their default values: + ++----------------+-------------------------+ +| Param | Default value | ++================+=========================+ +| ``$name`` | cloudServersOpenStack | ++----------------+-------------------------+ +| ``$region`` | DFW | ++----------------+-------------------------+ +| ``$urltype`` | publicURL | ++----------------+-------------------------+ + diff --git a/doc/_build/html/_sources/services/compute/flavors.txt b/doc/_build/html/_sources/services/compute/flavors.txt new file mode 100644 index 000000000..470ce8368 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/flavors.txt @@ -0,0 +1,62 @@ +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 */ + } + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/compute/images.txt b/doc/_build/html/_sources/services/compute/images.txt new file mode 100644 index 000000000..570790c04 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/images.txt @@ -0,0 +1,85 @@ +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) { + + } + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/compute/index.txt b/doc/_build/html/_sources/services/compute/index.txt new file mode 100644 index 000000000..ee27bce8e --- /dev/null +++ b/doc/_build/html/_sources/services/compute/index.txt @@ -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/_build/html/_sources/services/compute/keypair.txt b/doc/_build/html/_sources/services/compute/keypair.txt new file mode 100644 index 000000000..369b91a37 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/keypair.txt @@ -0,0 +1,71 @@ +Keypairs +======== + +Setup +----- + +.. include:: service.sample.rst + + +Generate a new keypair +---------------------- + +This operation creates a new keypair under a provided name; the public key +value is automatically generated for you. + +.. code:: 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:: 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:: php + + $keys = $service->listKeypairs(); + + foreach ($keys as $key) { + + } + + +Delete keypairs +--------------- + +To delete a specific keypair: + +.. code:: php + + $keypair->delete(); diff --git a/doc/_build/html/_sources/services/compute/keypairs.txt b/doc/_build/html/_sources/services/compute/keypairs.txt new file mode 100644 index 000000000..823fcf5a2 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/keypairs.txt @@ -0,0 +1,70 @@ +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(); + +`Get the executable PHP script for this example `_ + + +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 + )); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/compute/server.txt b/doc/_build/html/_sources/services/compute/server.txt new file mode 100644 index 000000000..17daddb79 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/server.txt @@ -0,0 +1,202 @@ +Servers +======= + +Setup +----- + +.. include:: service.sample.rst + +Get server +---------- + +The easiest way to retrieve a specific server is by its unique ID: + +.. code:: 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:: 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:: 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:: php + + $bootableVolume = $client->volumeService()->volume('{volumeId}'); + +Now we're ready to create our instance: + +.. code:: 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:: 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:: 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:: 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:: php + + $server->delete(); diff --git a/doc/_build/html/_sources/services/compute/servers.txt b/doc/_build/html/_sources/services/compute/servers.txt new file mode 100644 index 000000000..0709bda9a --- /dev/null +++ b/doc/_build/html/_sources/services/compute/servers.txt @@ -0,0 +1,250 @@ +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 | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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' + )); + + +`Get the executable PHP script for this example `_ + + +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. | ++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + + +Updating the access IP address(es) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For example, you may have a private cloud with internal addresses in the +10.1.x range. However, you can access a server via a firewall device at +address 50.57.94.244. In this case, you can change the ``accessIPv4`` +attribute to point to the firewall: + +.. code-block:: php + + $server->update(array('accessIPv4' => '50.57.94.244')); + +When a client application retrieves the server’s information, it will +know that it needs to use the ``accessIPv4`` address to connect to the +server, and *not* the IP address assigned to one of the network +interfaces. + + +Retrieving the server’s IP address +---------------------------------- + +The ``Server::ip()`` method is used to retrieve the server’s IP address. +It has one optional parameter: the format (either IPv4 or IPv6) of the +address to return (by default, it returns the IPv4 address): + +.. code-block:: php + + // IPv4 + echo $server->ip(); + echo $server->ip(4); + + // IPv6 + echo $server->ip(6); + + +Delete server +------------- + +.. code-block:: php + + $server->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/_build/html/_sources/services/compute/service.sample.txt b/doc/_build/html/_sources/services/compute/service.sample.txt new file mode 100644 index 000000000..e75252148 --- /dev/null +++ b/doc/_build/html/_sources/services/compute/service.sample.txt @@ -0,0 +1,9 @@ +.. include:: ../common/rs-client.sample.rst + +Now, set up the Auto Scale service: + +.. code-block:: php + + $service = $client->computeService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst diff --git a/doc/_build/html/_sources/services/database/README.md.txt b/doc/_build/html/_sources/services/database/README.md.txt new file mode 100644 index 000000000..3f6bdd3c2 --- /dev/null +++ b/doc/_build/html/_sources/services/database/README.md.txt @@ -0,0 +1,125 @@ +Databases +========= + +A **cloud database** is a MySQL relational database service that allows +customers to programatically provision database instances of varying +virtual resource sizes without the need to maintain and/or update MySQL. + +Getting started +--------------- + +1. Instantiate a Rackspace client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + use OpenCloud\Rackspace; + use OpenCloud\Common\Constants\State; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +2. Create a database server instance. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $databaseService = $client->databaseService('cloudDatabases', 'DFW'); + + $twoGbFlavor = $databaseService->flavor(3); + + $dbInstance = $databaseService->instance(); + $dbInstance->name = 'Demo database instance'; + $dbInstance->volume = new stdClass(); + $dbInstance->volume->size = 20; // GB + $dbInstance->flavor = $twoGbFlavor; + $dbInstance->create(); + + $dbInstance->waitFor(State::ACTIVE, null, function ($dbInstance) { + + printf("Database instance build status: %s\n", $dbInstance->status); + + }); + +The example above creates a database server instance with 20GB of disk +space and 2GB of memory, then waits for it to become ACTIVE. + +3. Create a database on the database server instance. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $db = $dbInstance->database(); + $db->name = 'demo_db'; + + $db->create(); + +The example above creates a database named ``demo_db`` on the database +server instance created in the previous step. + +4. Create database user and give it access to database. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $user = $dbInstance->user(); + $user->name = 'demo_user'; + $user->password = 'h@X0r!'; + $user->databases = array('demo_db'); + + $user->create(); + +The example above creates a database user named ``demo_user``, sets its +password and gives it access to the ``demo_db`` database created in the +previous step. + +5. Optional step: Create a load balancer to allow access to the database from the Internet. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The database 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:: php + + $loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW'); + + $loadBalancer = $loadBalancerService->loadBalancer(); + + $loadBalancer->name = 'Load balancer - DB'; + $loadBalancer->addNode($dbInstance->hostname, 3306); + $loadBalancer->port = 3306; + $loadBalancer->protocol = 'MYSQL'; + $loadBalancer->addVirtualIp('PUBLIC'); + + $loadBalancer->create(); + + $loadBalancer->waitFor(State::ACTIVE, null, function ($lb) { + printf("Load balancer build status: %s\n", $lb->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. diff --git a/doc/_build/html/_sources/services/database/configurations.txt b/doc/_build/html/_sources/services/database/configurations.txt new file mode 100644 index 000000000..f50619914 --- /dev/null +++ b/doc/_build/html/_sources/services/database/configurations.txt @@ -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/_build/html/_sources/services/database/databases.txt b/doc/_build/html/_sources/services/database/databases.txt new file mode 100644 index 000000000..83d07c5e2 --- /dev/null +++ b/doc/_build/html/_sources/services/database/databases.txt @@ -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/_build/html/_sources/services/database/datastores.txt b/doc/_build/html/_sources/services/database/datastores.txt new file mode 100644 index 000000000..ad6d90e85 --- /dev/null +++ b/doc/_build/html/_sources/services/database/datastores.txt @@ -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/_build/html/_sources/services/database/index.txt b/doc/_build/html/_sources/services/database/index.txt new file mode 100644 index 000000000..32888e27d --- /dev/null +++ b/doc/_build/html/_sources/services/database/index.txt @@ -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/_build/html/_sources/services/database/instances.txt b/doc/_build/html/_sources/services/database/instances.txt new file mode 100644 index 000000000..6f3afc1e0 --- /dev/null +++ b/doc/_build/html/_sources/services/database/instances.txt @@ -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/_build/html/_sources/services/database/service.sample.txt b/doc/_build/html/_sources/services/database/service.sample.txt new file mode 100644 index 000000000..60964126d --- /dev/null +++ b/doc/_build/html/_sources/services/database/service.sample.txt @@ -0,0 +1,9 @@ +.. include:: ../common/rs-client.sample.rst + +Now, set up the Database service: + +.. code-block:: php + + $service = $client->databaseService('{catalogName}', '{region}', '{urlType}'); + +.. include:: ../common/service-args.rst diff --git a/doc/_build/html/_sources/services/database/users.txt b/doc/_build/html/_sources/services/database/users.txt new file mode 100644 index 000000000..0343c4904 --- /dev/null +++ b/doc/_build/html/_sources/services/database/users.txt @@ -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/_build/html/_sources/services/dns/Domains.md.txt b/doc/_build/html/_sources/services/dns/Domains.md.txt new file mode 100644 index 000000000..824c05099 --- /dev/null +++ b/doc/_build/html/_sources/services/dns/Domains.md.txt @@ -0,0 +1,290 @@ +Domains +======= + +A domain is an entity/container of all DNS-related information +containing one or more records. + +Setup +----- + +Limit methods will be called on the DNS service, an instance of +``OpenCloud\DNS\Service``. Please see the `DNS service `__ +documentation for setup instructions. + +Get domain +---------- + +To retrieve a specific domain, you will need the domain's **id**, not +its domain name. + +.. code:: php + + $domain = $service->domain(12345); + +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:: php + + $domains = $service->domainList(); + + # Return detailed information for each domain + $domains = $service->domainList(true); + +Please consult the `iterator +documentation `__ for more information +about iterators. + +Filter parameters +~~~~~~~~~~~~~~~~~ + +You can filter the aforementioned search by using the ``name`` parameter +in a key/value array supplied as a method argument. For example, +providing ``array('name' => 'hoola.com')`` will return hoola.com and +similar names such as main.hoola.com and sub.hoola.com. + +.. code:: php + + $hoolaDomains = $service->domainList(array( + 'name' => 'hoola.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 +~~~~~~~~~~~~~~~~~~~ + +If you know a domain's name, but not its unique identifier, you can do +this: + +.. code:: php + + $domains = $service->domainList(array( + 'name' => 'foo.com' + )); + + foreach ($domains as $domain) { + $id = $domain->id; + } + +List domain changes +------------------- + +This call shows all changes to the specified domain since the specified +date/time. The since parameter is optional and defaults to midnight of +the current day. + +.. code:: php + + $changes = $domain->changes(); + + # Changes since last week + $since = date('c', strtotime('last week')); + $changes = $domain->changes($since); + + 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); + } + } + +Export domain +------------- + +This call provides the BIND (Berkeley Internet Name Domain) 9 formatted +contents of 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 (that is, no subdomain information is provided). + +.. code:: php + + $asyncResponse = $domain->export(); + $body = $asyncResponse->waitFor('COMPLETED'); + echo $body['contents']; + +Create domain +------------- + +A domain is composed of DNS records (e.g. ``A``, ``CNAME`` or ``MX`` +records) and an optional list of sub-domains. You will need to specify +these before creating the domain itself: + +.. code:: 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); + + // add optional C record + $cRecord = $domain->record(array( + 'type' => 'CNAME', + 'name' => 'www.example.com', + 'data' => 'example.com', + 'ttl' => 3600 + )); + $domain->addRecord($cRecord); + + // add optional MX record + $mxRecord = $domain->record(array( + 'type' => 'MX', + 'data' => 'mail.example.com', + 'name' => 'example.com', + 'ttl' => 3600, + 'priority' => 5 + )); + $domain->addRecord($mxRecord); + + // add optional NS records + $nsRecord1 = $domain->record(array( + 'type' => 'NS', + 'data' => 'dns1.stabletransit.com', + 'name' => 'example.com', + 'ttl' => 5400 + )); + $domain->addRecord($nsRecord1); + + $nsRecord2 = $domain->record(array( + 'type' => 'NS', + 'data' => 'dns2.stabletransit.com', + 'name' => 'example.com', + 'ttl' => 5400 + )); + $domain->addRecord($nsRecord2); + + // add optional subdomains + $sub1 = $domain->subdomain(array( + 'emailAddress' => 'foo@example.com', + 'name' => 'dev.example.com', + 'comment' => 'Dev portal' + )); + $domain->addSubdomain($sub1); + + // send to API + $domain->create(array( + 'emailAddress' => 'webmaster@example.com', + 'ttl' => 3600, + 'name' => 'example.com', + 'comment' => 'Optional comment' + )); + +Clone domain +------------ + +This call will duplicate a single existing domain configuration with a +new domain name for the specified Cloud account. By default, all records +and, optionally, subdomain(s) are duplicated as well. + +The method signature you will need to use is: + +.. code:: php + + cloneDomain ( string $newDomainName [, bool $subdomains [, bool $comments [, bool $email [, bool $records ]]]] ) + ++----------------------+--------------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Name | Data type | Default | Description | ++======================+==============+============+====================================================================================================================================================================================+ +| ``$newDomainName`` | ``string`` | - | The new name for your cloned domain | ++----------------------+--------------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``$subdomains`` | ``bool`` | ``true`` | Set to ``TRUE`` to clone all the subdomains for this domain | ++----------------------+--------------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``$comments`` | ``bool`` | ``true`` | Set to ``TRUE`` to replace occurrences of the reference domain name with the new domain name in comments on the cloned (new) domain. | ++----------------------+--------------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``$email`` | ``bool`` | ``true`` | 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:: php + + $asyncResponse = $domain->cloneDomain('new-name.com', true); + +Import domain +------------- + +This call provisions a new DNS domain under the account specified by the +BIND 9 formatted file configuration contents defined in the request +object. + +You will need to ensure that the BIND 9 formatted file configuration +contents are valid by adhering 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:: php + + $bind9Data = <<import($bind9Data); + +Modify domain +------------- + +This call modifies DNS domain(s) attributes only. 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:: php + + $domain->update(array( + 'ttl' => ($domain->ttl + 100), + 'emailAddress' => 'new_dev@foo.com' + )); + +Remove domain +------------- + +.. code:: php + + $domain->delete(); + diff --git a/doc/_build/html/_sources/services/dns/Limits.md.txt b/doc/_build/html/_sources/services/dns/Limits.md.txt new file mode 100644 index 000000000..72f8219a0 --- /dev/null +++ b/doc/_build/html/_sources/services/dns/Limits.md.txt @@ -0,0 +1,70 @@ +Limits +====== + +Setup +----- + +Limit methods will be called on the DNS service, an instance of +``OpenCloud\DNS\Service``. Please see the `DNS service `__ +documentation for setup instructions. + +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; + + >>> 500 + diff --git a/doc/_build/html/_sources/services/dns/Records.md.txt b/doc/_build/html/_sources/services/dns/Records.md.txt new file mode 100644 index 000000000..4e492e8ef --- /dev/null +++ b/doc/_build/html/_sources/services/dns/Records.md.txt @@ -0,0 +1,111 @@ +Records +======= + +A DNS record belongs to a particular domain and is used to specify +information about the domain. + +There are several types of DNS records. 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. + +It is represented by the ``OpenCloud\DNS\Resource\Record`` class. +Records belong to a `Domain `__. + +Get record +---------- + +In order to retrieve details for a specific DNS record, you will need +its **id**: + +.. code:: php + + $record = $domain->record('NS-1234567'); + +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); + } + +Please consult the `iterator +documentation `__ for more information +about iterators. + +Query parameters +~~~~~~~~~~~~~~~~ + +You can pass in an array of query parameters for greater control over +your search: + ++------------+--------------+------------------------+---------------+ +| Name | Data type | Default | 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(123456); + $record->ttl -= 100; + $record->update(); + +Delete record +------------- + +.. code:: php + + $record->delete(); + diff --git a/doc/_build/html/_sources/services/dns/Reverse-DNS.md.txt b/doc/_build/html/_sources/services/dns/Reverse-DNS.md.txt new file mode 100644 index 000000000..b8a5c0e76 --- /dev/null +++ b/doc/_build/html/_sources/services/dns/Reverse-DNS.md.txt @@ -0,0 +1,96 @@ +Reverse DNS +=========== + +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. + +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, a ``$parent`` 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/Server.md>`__ and `load +balancer documentation <../LoadBalancer/USERGUIDE.md>`__ for more +detailed usage instructions. + +List PTR records +---------------- + +.. code:: php + + /** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */ + + $ptrRecords = $service->ptrRecordList($parent); + + foreach ($ptrRecords as $ptrRecord) { + + } + +Please consult the `iterator +documentation `__ for more information +about iterators. + +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/_build/html/_sources/services/dns/Service.md.txt b/doc/_build/html/_sources/services/dns/Service.md.txt new file mode 100644 index 000000000..29ea79193 --- /dev/null +++ b/doc/_build/html/_sources/services/dns/Service.md.txt @@ -0,0 +1,13 @@ +DNS Service +=========== + +To instantiate a Compute service object, you first need to setup a +Rackspace/OpenStack client. To do this, or for more information, please +consult the `Clients documentation <../Clients.md>`__. + +You will then need to run: + +.. code:: php + + $service = $client->dnsService(); + diff --git a/doc/_build/html/_sources/services/dns/domains.txt b/doc/_build/html/_sources/services/dns/domains.txt new file mode 100644 index 000000000..0a7b83b96 --- /dev/null +++ b/doc/_build/html/_sources/services/dns/domains.txt @@ -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/_build/html/_sources/services/dns/index.txt b/doc/_build/html/_sources/services/dns/index.txt new file mode 100644 index 000000000..39db3d675 --- /dev/null +++ b/doc/_build/html/_sources/services/dns/index.txt @@ -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/_build/html/_sources/services/dns/limits.txt b/doc/_build/html/_sources/services/dns/limits.txt new file mode 100644 index 000000000..289c3888d --- /dev/null +++ b/doc/_build/html/_sources/services/dns/limits.txt @@ -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/_build/html/_sources/services/dns/records.txt b/doc/_build/html/_sources/services/dns/records.txt new file mode 100644 index 000000000..26e17ee5e --- /dev/null +++ b/doc/_build/html/_sources/services/dns/records.txt @@ -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/_build/html/_sources/services/dns/reverse-dns.txt b/doc/_build/html/_sources/services/dns/reverse-dns.txt new file mode 100644 index 000000000..4d0eb671c --- /dev/null +++ b/doc/_build/html/_sources/services/dns/reverse-dns.txt @@ -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/_build/html/_sources/services/identity/Roles.md.txt b/doc/_build/html/_sources/services/identity/Roles.md.txt new file mode 100644 index 000000000..96a56488f --- /dev/null +++ b/doc/_build/html/_sources/services/identity/Roles.md.txt @@ -0,0 +1,92 @@ +Roles +===== + +Intro +----- + +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. + +Setup +----- + +Role objects are instantiated from the Identity service. For more +details, see the `Service `__ docs. + +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:: php + + $roles = $service->getRoles(); + + foreach ($roles as $role) { + // ... + } + +For more information about how to use iterators, see the +`documentation <../Iterators.md>`__. + +Get role +-------- + +This call lists detailed information (id, name, description) for a +specified role. + +.. code:: php + + $roleId = '123abc'; + $role = $service->getRole($roleId); + +Add/delete user roles +--------------------- + +To add/remove user roles, you must first instantiate a +`user `__ object: + +.. code:: php + + $roleId = '123abc'; + + // 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:: php + + $roles = $user->getRoles(); + + foreach ($roles as $role) { + // ... + } + +For more information about how to use iterators, see the +`documentation <../Iterators.md>`__. diff --git a/doc/_build/html/_sources/services/identity/Service.md.txt b/doc/_build/html/_sources/services/identity/Service.md.txt new file mode 100644 index 000000000..a89f19358 --- /dev/null +++ b/doc/_build/html/_sources/services/identity/Service.md.txt @@ -0,0 +1,13 @@ +Identity service +================ + +Intro +----- + +The Identity service is regionless, so you do not need to specify a +region when instantiating the service object. Although this was +primarily based on Rackspace's implementation of Cloud Identity, it +should also work for OpenStack Keystone. + +A note on object creation +------------------------- diff --git a/doc/_build/html/_sources/services/identity/Tenants.md.txt b/doc/_build/html/_sources/services/identity/Tenants.md.txt new file mode 100644 index 000000000..9b58efd1a --- /dev/null +++ b/doc/_build/html/_sources/services/identity/Tenants.md.txt @@ -0,0 +1,29 @@ +Tenants +======= + +Intro +----- + +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. + +Setup +----- + +Tenant objects are instantiated from the Identity service. For more +details, see the `Service `__ docs. + +List tenants +------------ + +.. code:: php + + $tenants = $service->getTenants(); + + foreach ($tenants as $tenant) { + // ... + } + +For more information about how to use iterators, see the +`documentation <../Iterators.md>`__. diff --git a/doc/_build/html/_sources/services/identity/Tokens.md.txt b/doc/_build/html/_sources/services/identity/Tokens.md.txt new file mode 100644 index 000000000..c42ce1573 --- /dev/null +++ b/doc/_build/html/_sources/services/identity/Tokens.md.txt @@ -0,0 +1,105 @@ +Tokens +====== + +Intro +----- + +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. + +Setup +----- + +Token objects are instantiated from the Identity service. For more +details, see the `Service `__ docs. + +Useful object properties/methods +-------------------------------- + ++------------+-------------------------------------------+----------------------------------------+--------------------+ +| Property | Description | Getter | Setter | ++============+===========================================+========================================+====================+ +| id | The unique ID of the token | ``getId()`` | ``setId()`` | ++------------+-------------------------------------------+----------------------------------------+--------------------+ +| expires | Timestamp of when the token will expire | ``getExpires()`` or ``hasExpired()`` | ``setExpires()`` | ++------------+-------------------------------------------+----------------------------------------+--------------------+ + +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. + +Request body for Rackspace's generate token operation: + +.. code:: json + + { + "auth": { + "RAX-KSKEY:apiKeyCredentials": { + "username": "foo", + "apiKey": "aaaaa-bbbbb-ccccc-12345678" + }, + "tenantId": "1100111" + } + } + +Request body for Keystone's generate token operation: + +.. code:: json + + { + "auth": { + "passwordCredentials":{ + "username":"demoauthor", + "password":"theUsersPassword" + }, + "tenantId": "12345678" + } + } + +The only real differences you'll notice is the name of the object key +(``RAX-KSKEY:apiKeyCredentials``/``passwordCredentials``) and the secret +(``apiKey``/``password``). The ``tenantId`` property in both templates +are optional. You can also add ``tenantName`` too. + +.. code:: php + + use OpenCloud\Common\Http\Message\Formatter; + + $template = sprintf( + '{"auth": {"RAX-KSKEY:apiKeyCredentials":{"username": "%s", "apiKey": "%s"}}}', + 'my_username', + 'my_api_key' + ); + + $response = $service->generateToken($template); + + $body = Formatter::decode($response); + + // service catalog + $catalog = $body->access->serviceCatalog; + + // token + $token = $body->access->token; + + // user + $user = $body->access->user; + +As you will notice, these variables will be stdClass objects - for fully +fledged functionality, let the client authenticate by itself because it +ends up stocking the necessary models for you. + +To see the response body structure, consult the `official +docs `__. + +Revoke token (destroy session) +------------------------------ + +.. code:: php + + $tokenId = '1234567'; + $service->revokeToken($tokenId); + diff --git a/doc/_build/html/_sources/services/identity/Users.md.txt b/doc/_build/html/_sources/services/identity/Users.md.txt new file mode 100644 index 000000000..e8c2e6d63 --- /dev/null +++ b/doc/_build/html/_sources/services/identity/Users.md.txt @@ -0,0 +1,170 @@ +Users +===== + +Intro +----- + +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. + +Setup +----- + +User objects are instantiated from the Identity service. For more +details, see the `Service `__ docs. + +Useful 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:: php + + $users = $service->getUsers(); + + foreach ($users as $user) { + // ... + } + +For more information about how to use iterators, see the +`documentation <../Iterators.md>`__. + +Get user +-------- + +There are various ways to get a specific user: by name, ID and email +address. + +.. code:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + // Get user by name + $user1 = $service->getUser('jamie'); + + // Get user by ID + $user2 = $service->getUser(123456, UserConst::MODE_ID); + + // Get user by email + $user3 = $service->getUser('jamie.hannaford@rackspace.com', UserConst::MODE_EMAIL); + +Create user +----------- + +There are a few things to remember 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. + +- Within an account, a maximum of 100 account users can be added. + +- 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:: php + + use Guzzle\Http\Exception\ClientErrorResponseException; + + try { + // execute operation + $user = $service->createUser(array( + 'username' => 'newUser', + 'email' => 'foo@bar.com' + )); + } catch (ClientErrorResponseException $e) { + // catch 4xx HTTP errors + echo $e->getResponse()->toString(); + } + + // show generated password + echo $user->getPassword(); + +Update user +----------- + +When updating a user, specify which attribute/property you want to +update: + +.. code:: php + + $user->update(array( + 'email' => 'new_email@bar.com' + )); + +Updating a user password +~~~~~~~~~~~~~~~~~~~~~~~~ + +Updating a user password requires calling a distinct method: + +.. code:: php + + $user->updatePassword('password123'); + +Delete user +----------- + +.. code:: php + + $user->delete(); + +List credentials +---------------- + +This operation allows you to see your non-password credential types for +all authentication methods available. + +.. code:: php + + $creds = $user->getOtherCredentials(); + +Get user API key +---------------- + +.. code:: php + + echo $user->getApiKey(); + +Reset user API key +------------------ + +When resetting an API key, a new one will be automatically generated for +you: + +.. code:: php + + $user->resetApiKey(); + echo $user->getApiKey(); + diff --git a/doc/_build/html/_sources/services/identity/index.txt b/doc/_build/html/_sources/services/identity/index.txt new file mode 100644 index 000000000..6cb4dfdf4 --- /dev/null +++ b/doc/_build/html/_sources/services/identity/index.txt @@ -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/_build/html/_sources/services/identity/roles.txt b/doc/_build/html/_sources/services/identity/roles.txt new file mode 100644 index 000000000..614518b9b --- /dev/null +++ b/doc/_build/html/_sources/services/identity/roles.txt @@ -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/_build/html/_sources/services/identity/tenants.txt b/doc/_build/html/_sources/services/identity/tenants.txt new file mode 100644 index 000000000..a27417cca --- /dev/null +++ b/doc/_build/html/_sources/services/identity/tenants.txt @@ -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/_build/html/_sources/services/identity/tokens.txt b/doc/_build/html/_sources/services/identity/tokens.txt new file mode 100644 index 000000000..e4601c7c4 --- /dev/null +++ b/doc/_build/html/_sources/services/identity/tokens.txt @@ -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/_build/html/_sources/services/identity/users.txt b/doc/_build/html/_sources/services/identity/users.txt new file mode 100644 index 000000000..944888902 --- /dev/null +++ b/doc/_build/html/_sources/services/identity/users.txt @@ -0,0 +1,175 @@ +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) { + // ... + } + +`Get the executable PHP script for this example `_ + + +Retrieve a user by username +--------------------------- + +.. code-block:: php + + $user = $service->getUser('jamie'); + +`Get the executable PHP script for this example `_ + + +Retrieve a user by user ID +-------------------------- + +.. code-block:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + $user = $service->getUser('{userId}', UserConst::MODE_ID); + +`Get the executable PHP script for this example `_ + + +Retrieve a user by email address +-------------------------------- + +.. code-block:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + $user = $service->getUser('{emailAddress}', UserConst::MODE_EMAIL); + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ diff --git a/doc/_build/html/_sources/services/image/Images.md.txt b/doc/_build/html/_sources/services/image/Images.md.txt new file mode 100644 index 000000000..ef187f083 --- /dev/null +++ b/doc/_build/html/_sources/services/image/Images.md.txt @@ -0,0 +1,107 @@ +Images +====== + +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). + +An Image is represented by the ``OpenCloud\Image\Resource\Image`` class. + +Setup +----- + +You instantiate an Image object from its ``OpenCloud\Image\Service`` +class, which is available from the OpenStack/Rackspace client: + +.. code:: php + + $service = $client->imageService('cloudImages', 'IAD'); + +View the guides for more information about `clients <../Clients.md>`__ +or `services <../Services.md>`__. + +List images +----------- + +.. code:: php + + $images = $service->listImages(); + + foreach ($images as $image) { + /** @param $image OpenCloud\Image\Resource\Image */ + } + +For more information about working with iterators, please see the +`iterators documentation <../Iterators.md>`__. + +Get image details +----------------- + +.. code:: php + + /** @param $image OpenCloud\Image\Resource\Image */ + $image = $service->getImage(''); + +A note on schema classes +~~~~~~~~~~~~~~~~~~~~~~~~ + +Both ``OpenCloud\Image\Resource\Image`` and +``OpenCloud\Image\Resource\Member`` extend the +``AbstractSchemaResource`` abstract 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 way +different 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:: php + + $image = $service->getImage(''); + + $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:: 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:: php + + $image->delete(); + diff --git a/doc/_build/html/_sources/services/image/Schemas.md.txt b/doc/_build/html/_sources/services/image/Schemas.md.txt new file mode 100644 index 000000000..8f792c4c0 --- /dev/null +++ b/doc/_build/html/_sources/services/image/Schemas.md.txt @@ -0,0 +1,170 @@ +JSON schemas +============ + +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. + +A JSON Schema is represented by the +``OpenCloud\Image\Resource\Schema\Schema`` class. + +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:: 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:: 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:: 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:: 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: + +:: + + [ + {"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/_build/html/_sources/services/image/Sharing.md.txt b/doc/_build/html/_sources/services/image/Sharing.md.txt new file mode 100644 index 000000000..b1a1ea382 --- /dev/null +++ b/doc/_build/html/_sources/services/image/Sharing.md.txt @@ -0,0 +1,129 @@ +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 this up first. + +List image members +------------------ + +This operation is available for both producers and consumers. + +.. code:: php + + $members = $image->listMembers(); + + foreach ($members as $member) { + /** @param $member OpenCloud\Image\Resource\Member */ + } + +For more information about working with iterators, please see the +`iterators documentation <../Iterators.md>`__. + +Create image member +------------------- + +This operation is only available for producers. + +.. code:: php + + $tenantId = 12345; + + /** @param $response Guzzle\Http\Message\Response */ + $response = $image->createMember($tenantId); + +Delete image member +------------------- + +This operation is only available for producers. + +.. code:: php + + $tenantId = 12345; + + /** @param $member OpenCloud\Image\Resource\Member */ + $member = $image->getMember($tenantId); + + $member->delete(); + +Update image member status +-------------------------- + +This operation is only available for consumers. + +.. code:: php + + use OpenCloud\Images\Enum\MemberStatus; + + $tenantId = 12345; + + /** @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/_build/html/_sources/services/image/Tags.md.txt b/doc/_build/html/_sources/services/image/Tags.md.txt new file mode 100644 index 000000000..af5baf157 --- /dev/null +++ b/doc/_build/html/_sources/services/image/Tags.md.txt @@ -0,0 +1,28 @@ +Image tags +========== + +An image tag is a string of characters used to identify a specific image +or images. + +Setup +----- + +All member operations are executed against an `Image `__, so +you will need to set this up first. + +Add image tag +------------- + +.. code:: php + + /** @param $response Guzzle\Http\Message\Response */ + $response = $image->addTag('jamie_dev'); + +Delete image tag +---------------- + +.. code:: php + + /** @param $response Guzzle\Http\Message\Response */ + $response = $image->deleteTag('jamie_dev'); + diff --git a/doc/_build/html/_sources/services/image/images.txt b/doc/_build/html/_sources/services/image/images.txt new file mode 100644 index 000000000..ec1a17c34 --- /dev/null +++ b/doc/_build/html/_sources/services/image/images.txt @@ -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/_build/html/_sources/services/image/index.txt b/doc/_build/html/_sources/services/image/index.txt new file mode 100644 index 000000000..a7331b430 --- /dev/null +++ b/doc/_build/html/_sources/services/image/index.txt @@ -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/_build/html/_sources/services/image/schemas.txt b/doc/_build/html/_sources/services/image/schemas.txt new file mode 100644 index 000000000..c1b85b8de --- /dev/null +++ b/doc/_build/html/_sources/services/image/schemas.txt @@ -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/_build/html/_sources/services/image/sharing.txt b/doc/_build/html/_sources/services/image/sharing.txt new file mode 100644 index 000000000..5edf63ab4 --- /dev/null +++ b/doc/_build/html/_sources/services/image/sharing.txt @@ -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/_build/html/_sources/services/image/tags.txt b/doc/_build/html/_sources/services/image/tags.txt new file mode 100644 index 000000000..0a376e6de --- /dev/null +++ b/doc/_build/html/_sources/services/image/tags.txt @@ -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/_build/html/_sources/services/index.txt b/doc/_build/html/_sources/services/index.txt new file mode 100644 index 000000000..52a449084 --- /dev/null +++ b/doc/_build/html/_sources/services/index.txt @@ -0,0 +1,4 @@ +.. toctree:: + :maxdepth: 2 + + autoscale/index.rst diff --git a/doc/_build/html/_sources/services/load-balancer/README.md.txt b/doc/_build/html/_sources/services/load-balancer/README.md.txt new file mode 100644 index 000000000..862cf20d2 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/README.md.txt @@ -0,0 +1,92 @@ +Load Balancers +============== + +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. + +Getting started +--------------- + +1. Instantiate a Rackspace client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +2. Retrieve the server instances you want to add as nodes of the load balancer. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $computeService = $client->computeService('cloudServersOpenStack', 'DFW'); + + $serverOne = $computeService->server('e836fc4e-056d-4447-a80e-fefcaa640216'); + $serverTwo = $computeService->server('5399cd36-a23f-41a6-bdf7-20902aec0e74'); + +The example above uses two server instances that have already been +created. It retrieves the server instances using their IDs. See also: +`creating server instances <>`__. + +3. Obtain a Load Balancer service object from the client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This object will be used to first define the load balancer nodes and +later create the load balancer itself. + +.. code:: php + + $loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW'); + +4. Define a load balancer node for each server. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer = $loadBalancerService->loadBalancer(); + + $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'; + +In the example above, each node runs a service that listens on port +8080. Further, each node will start out as ``ENABLED``, which means it +will be ready to receive network traffic from the load balancer as soon +as it is created. + +5. Create the load balancer with the two nodes. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer->addVirtualIp('PUBLIC'); + $loadBalancer->create(array( + 'name' => 'My smart load balancer', + 'port' => 80, + 'protocol' => 'HTTP', + 'nodes' => array($serverOneNode, $serverTwoNode) + )); + +In the example above, the load balancer will have a virtual IP address +accessible from the public Internet. Also notice that the port the load +balancer listens on (80) does not need to match the ports of its nodes +(8080). + +Next steps +---------- + +Once you have created a load balancer, there is a lot you can do with +it. See the `complete user guide for load balancers `__. diff --git a/doc/_build/html/_sources/services/load-balancer/USERGUIDE.md.txt b/doc/_build/html/_sources/services/load-balancer/USERGUIDE.md.txt new file mode 100644 index 000000000..788651f2b --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/USERGUIDE.md.txt @@ -0,0 +1,840 @@ +The Complete User Guide to Load Balancers +========================================= + +Prerequisites +------------- + +Client +~~~~~~ + +To use the load balancers service, you must first instantiate a +``Rackspace`` client object. + +.. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +Load Balancer Service +~~~~~~~~~~~~~~~~~~~~~ + +All operations on load balancers are done via a load balancer service +object. + +.. code:: php + + $loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW'); + +Cloud Servers +~~~~~~~~~~~~~ + +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. + +Load Balancers +-------------- + +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. + +Create Load Balancer +~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer = $loadBalancerService->loadBalancer(); + + $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'; + + $loadBalancer->addVirtualIp('PUBLIC'); + $loadBalancer->create(array( + 'name' => 'My smart load balancer', + 'port' => 80, + 'protocol' => 'HTTP', + 'nodes' => array($serverOneNode, $serverTwoNode) + )); + +List Load Balancer Details +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve a single load balancer's details by using its ID. + +.. code:: php + + $loadBalancer = $loadBalancerService->loadBalancer('254889'); + + /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ + +List Load Balancers +~~~~~~~~~~~~~~~~~~~ + +You can retrieve a list of all your load balancers. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $loadBalancers = $loadBalancerService->loadBalancerList(); + foreach ($loadBalancers as $loadBalancer) { + /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ + } + +Update Load Balancer Attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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>`__. + +Updating a single attribute of a load balancer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: php + + $loadBalancer->update(array( + 'name' => 'New name' + )); + +Updating multiple attributes of a load balancer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: 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:: php + + $loadBalancer->delete(); + +Nodes +----- + +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. + +List Nodes +~~~~~~~~~~ + +You can list the nodes attached to a load balancer. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: 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:: php + + $address = $serverThree->addresses->private[0]->addr; + $loadBalancer->addNode($address, 8080); + $loadBalancer->addNodes(); + +The ``addNode`` method accepts three more optional parameters, in +addition to the two shown above: + +| Position \| Description \| Data type \| Required? \| Default value \| +| ----------- \| --------------- \| --------------\| -------------- \| +----------------- \| +|  1 \| IP address of node \| String \| Yes \| - \| +|  2 \| Port used by node's service \| Integer \| Yes \| - \| +|  3 \| Starting condition of node: +|  4 \| Type of node to add: +|  5 \| 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. \| Integer \| +No \| 1 \| + +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. + +Modifying a single attribute of a node +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: php + + use OpenCloud\LoadBalancer\Enum\NodeCondition; + + $node->update(array( + 'condition' => NodeCondition::DISABLED + )); + +Modifying multiple attributes of a node +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: 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. + +Given an ``OpenCloud\LoadBalancer\Resource\Node`` instance +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: php + + $node->delete(); + +Given an ``OpenCloud\LoadBalancer\Resource\LoadBalancer`` instance and a node ID +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: php + + $loadBalancer->removeNode(490639); + +The ``removeNode`` method, as shown above, accepts the following +arguments: + ++------------+---------------+-------------+-------------+-----------------+ +| Position | Description | Data type | Required? | Default value | ++============+===============+=============+=============+=================+ +| 1 | ID of node | Integer | Yes | - | ++------------+---------------+-------------+-------------+-----------------+ + +View Node Service Events +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can view events associated with the activity between a node and a +load balancer. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $nodeEvents = $loadBalancer->nodeEventList(); + foreach ($nodeEvents as $nodeEvent) { + /** @var $nodeEvent OpenCloud\LoadBalancer\Resource\NodeEvent **/ + } + +Virtual IPs +----------- + +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. + +List Virtual IPs +~~~~~~~~~~~~~~~~ + +You can list the VIPs associated with a load balancer. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $vips = $loadBalancer->virtualIpList(); + foreach ($vips as $vip) { + /** @var $vip of OpenCloud\LoadBalancer\Resource\VirtualIp **/ + } + +Add Virtual IPv6 +~~~~~~~~~~~~~~~~ + +You can add additional IPv6 VIPs to a load balancer. + +.. code:: php + + use OpenCloud\LoadBalancer\Enum\IpType; + + $loadBalancer->addVirtualIp(IpType::PUBLIC, 6); + +The ``addVirtualIp`` method, as shown above, accepts the following +arguments: + +| Position \| Description \| Data type \| Required? \| Default value \| +| ----------- \| --------------- \| -------------- \|-------------- \| +----------------- \| +|  1 \| Type of VIP: +|  2 \| IP version: Must be ``6`` \| Integer \| Yes \| - \| + +Remove Virtual IPs +~~~~~~~~~~~~~~~~~~ + +You can remove a VIP from a load balancer. + +.. code:: php + + $vip->remove(); + +Please note that 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. + +Algorithms +---------- + +Load balancers use an **algorithm** to determine how incoming traffic is +distributed amongst the back-end nodes. + +List Load Balancing Algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can list all supported load balancing algorithms using a load +balancer service object. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $algorithms = $loadBalancerService->algorithmList(); + foreach ($algorithms as $algorithm) { + /** @var $algorithm OpenCloud\LoadBalancer\Resource\Algorithm **/ + } + +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. + +List Load Balancing Protocols +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can list all supported network protocols using a load balancer +service object. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $protocols = $loadBalancerService->protocolList(); + foreach ($protocols as $protocol) { + /** @var $protocol OpenCloud\LoadBalancer\Resource\Protocol **/ + } + +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. + +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. | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +List Session Persistence Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $sessionPersistence = $loadBalancer->sessionPersistence(); + $sessionPersistenceType = $sessionPersistence->persistenceType; + + /** @var $sessionPersistenceType null | 'HTTP_COOKIE' | 'SOURCE_IP' **/ + +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:: php + + $sessionPersistence = $loadBalancer->sessionPersistence(); + $sessionPersistence->update(array( + 'persistenceType' => 'HTTP_COOKIE' + )); + +Disable Session Persistence +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $sessionPersistence = $loadBalancer->sessionPersistence(); + $sessionPersistence->delete(); + +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. + +Check Logging Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + /** @var $connectionLogging bool **/ + + $connectionLogging = $loadBalancer->hasConnectionLogging(); + +In the example above: + +- If connection logging is enabled, the value of ``$connectionLogging`` + is ``true``. +- If connection logging is disabled, the value of + ``$connectionLogging`` is ``false``. + +Enable Connection Logging +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer->enableConnectionLogging(true); + +Disable Connection Logging +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer->enableConnectionLogging(false); + +Error Page +---------- + +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:: 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:: php + + $errorPage = $loadBalancer->errorPage(); + $errorPage->update(array( + 'content' => '' + )); + +Delete Custom Error Page +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $errorPage = $loadBalancer->errorPage(); + $errorPage->delete(); + +Allowed Domains +--------------- + +**Allowed domains** are a restricted set of domain names that are +allowed to add load balancer nodes. + +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:: php + + $allowedDomains = $loadBalancerService->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``. + +View Access List +~~~~~~~~~~~~~~~~ + +You can view a load balancer's access list. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: 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:: 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:: php + + $networkItem->delete(); + +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. + +Check Content Caching Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + /** @var $contentCaching bool **/ + + $contentCaching = $loadBalancer->hasContentCaching(); + +In the example above: + +- If content caching is enabled, the value of ``$contentCaching`` is + ``true``. +- If content caching is disabled, the value of ``$contentCaching`` is + ``false``. + +Enable Content Caching +~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer->enableContentCaching(true); + +Disable Content Caching +~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $loadBalancer->enableContentCaching(false); + +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. + +View current SSL termination config +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + /** @var $sslConfig OpenCloud\LoadBalancer\Resource\SSLTermination **/ + + $sslConfig = $loadBalancer->SSLTermination(); + +Update SSL termination config +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: 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 SSL termination config +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $sslConfig->delete(); + +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. + +List metadata +~~~~~~~~~~~~~ + +.. code:: php + + $metadataList = $loadBalancer->metadataList(); + + foreach ($metadataList as $metadataItem) { + printf("Key: %s, Value: %s", $metadataItem->key, $metadataItem->value); + } + +Please consult the `iterator +documentation `__ for more information +about iterators. + +Add metadata +~~~~~~~~~~~~ + +.. code:: php + + $metadataItem = $loadBalancer->metadata(); + $metadataItem->create(array( + 'key' => 'foo', + 'value' => 'bar' + )); + +Modify metadata +~~~~~~~~~~~~~~~ + +.. code:: php + + $metadataItem = $loadBalancer->metadata('foo'); + $metadataItem->update(array( + 'value' => 'baz' + )); + +Remove metadata +~~~~~~~~~~~~~~~ + +.. code:: php + + $metadataItem->delete(); + +Monitors +-------- + +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. + +.. code:: 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 or delete +~~~~~~~~~~~~~~~~ + +.. code:: php + + // Update + $healthMonitor->update(array( + 'delay' => 120, + 'timeout' => 60, + 'type' => 'CONNECT' + 'attemptsBeforeDeactivation' => 3 + )); + + // Delete + $healthMonitor->delete(); + +Statistics +---------- + +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:: 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:: 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/_build/html/_sources/services/load-balancer/access.txt b/doc/_build/html/_sources/services/load-balancer/access.txt new file mode 100644 index 000000000..42cd68315 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/access.txt @@ -0,0 +1,84 @@ +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. + +Get the executable PHP scripts for this example: + +* `Blacklist IP range `_ +* `Limit access to 1 IP `_ + + +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/_build/html/_sources/services/load-balancer/caching.txt b/doc/_build/html/_sources/services/load-balancer/caching.txt new file mode 100644 index 000000000..6678e048a --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/caching.txt @@ -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/_build/html/_sources/services/load-balancer/errors.txt b/doc/_build/html/_sources/services/load-balancer/errors.txt new file mode 100644 index 000000000..041c19d45 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/errors.txt @@ -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/_build/html/_sources/services/load-balancer/index.txt b/doc/_build/html/_sources/services/load-balancer/index.txt new file mode 100644 index 000000000..9ea7614ad --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/index.txt @@ -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/_build/html/_sources/services/load-balancer/lb-setup.sample.txt b/doc/_build/html/_sources/services/load-balancer/lb-setup.sample.txt new file mode 100644 index 000000000..d82c80a1f --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/lb-setup.sample.txt @@ -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/_build/html/_sources/services/load-balancer/load-balancer.txt b/doc/_build/html/_sources/services/load-balancer/load-balancer.txt new file mode 100644 index 000000000..d7867755d --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/load-balancer.txt @@ -0,0 +1,171 @@ +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. + +`Get the executable PHP script for this example `_ + + +Get 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 **/ + } + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/load-balancer/logging.txt b/doc/_build/html/_sources/services/load-balancer/logging.txt new file mode 100644 index 000000000..29c37aee2 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/logging.txt @@ -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/_build/html/_sources/services/load-balancer/metadata.txt b/doc/_build/html/_sources/services/load-balancer/metadata.txt new file mode 100644 index 000000000..2b38de129 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/metadata.txt @@ -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/_build/html/_sources/services/load-balancer/monitors.txt b/doc/_build/html/_sources/services/load-balancer/monitors.txt new file mode 100644 index 000000000..9c463f270 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/monitors.txt @@ -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/_build/html/_sources/services/load-balancer/nodes.txt b/doc/_build/html/_sources/services/load-balancer/nodes.txt new file mode 100644 index 000000000..dfaadc404 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/nodes.txt @@ -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/_build/html/_sources/services/load-balancer/sessions.txt b/doc/_build/html/_sources/services/load-balancer/sessions.txt new file mode 100644 index 000000000..3d7f71cfe --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/sessions.txt @@ -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/_build/html/_sources/services/load-balancer/ssl.txt b/doc/_build/html/_sources/services/load-balancer/ssl.txt new file mode 100644 index 000000000..413bdc612 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/ssl.txt @@ -0,0 +1,54 @@ +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 `__ + +`Get the executable PHP script for this example `_ + + +Delete configuration +-------------------- + +.. code-block:: php + + $sslConfig->delete(); diff --git a/doc/_build/html/_sources/services/load-balancer/stats.txt b/doc/_build/html/_sources/services/load-balancer/stats.txt new file mode 100644 index 000000000..65077643f --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/stats.txt @@ -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/_build/html/_sources/services/load-balancer/virtual-ips.txt b/doc/_build/html/_sources/services/load-balancer/virtual-ips.txt new file mode 100644 index 000000000..fa0add613 --- /dev/null +++ b/doc/_build/html/_sources/services/load-balancer/virtual-ips.txt @@ -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/_build/html/_sources/services/monitoring/Agents.md.txt b/doc/_build/html/_sources/services/monitoring/Agents.md.txt new file mode 100644 index 000000000..943983f7e --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Agents.md.txt @@ -0,0 +1,202 @@ +Agents +====== + +Intro +----- + +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 `__. + +Setup +----- + +.. code:: php + + $agentId = '00-agent.example.com'; + $agent = $service->getAgent($agentId); + +You can view the `service page `__ for more information +about setting up the Cloud Monitoring service. + +List agents +----------- + +.. code:: php + + $agents = $service->getAgents(); + + foreach ($agents as $agent) { + echo $agent->getLastConnected(); + } + +Please consult the `iterator doc `__ for +more information about iterators. + +List connections +---------------- + +.. code:: php + + $connections = $agent->getConnections(); + +Please consult the `iterator doc `__ for +more information about iterators. + +Get connection +-------------- + +.. code:: php + + /** @var \OpenCloud\CloudMonitoring\Resource\AgentConnection */ + $connection = $agent->getConnection('cntl4qsIbA'); + +Agent Connection properties +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++--------------------+---------------+--------+---------------------------+ +| Name | Description | Type | Method | ++====================+===============+========+===========================+ +| id | - | - | ``getId()`` | ++--------------------+---------------+--------+---------------------------+ +| guid | - | - | ``getGuid()`` | ++--------------------+---------------+--------+---------------------------+ +| agent\_id | - | - | ``getAgentId()`` | ++--------------------+---------------+--------+---------------------------+ +| endpoint | - | - | ``getEndpoint()`` | ++--------------------+---------------+--------+---------------------------+ +| process\_version | - | - | ``getProcessVersion()`` | ++--------------------+---------------+--------+---------------------------+ +| bundle\_version | - | - | ``getBundleVersion()`` | ++--------------------+---------------+--------+---------------------------+ +| agent\_ip | - | - | ``getAgentIp()`` | ++--------------------+---------------+--------+---------------------------+ + +Agent tokens +============ + +Intro +----- + +Agent tokens are used to authenticate Monitoring agents to the +Monitoring Service. Multiple agents can share a single token. + +Setup +----- + +.. code:: php + + $tokenId = '4c5e28f0-0b3f-11e1-860d-c55c4705a286:1234'; + $agentToken = $service->getAgentToken($tokenId); + +Create agent token +------------------ + +.. code:: php + + $newToken = $service->getAgentToken(); + $newToken->create(array('label' => 'Foobar')); + +List agent tokens +----------------- + +.. code:: php + + $agentTokens = $service->getAgentTokens(); + + foreach ($agentTokens as $token) { + echo $token->getLabel(); + } + +Please consult the `iterator doc `__ for +more information about iterators. + +Update and delete Agent Token +----------------------------- + +.. code:: php + + // Update + $token->update(array( + 'label' => 'New label' + )); + + // Delete + $token->delete(); + +Agent Host Information +====================== + +Info +---- + +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:: php + + $host = $monitoringService->getAgentHost(); + +Get some metrics +---------------- + +.. code:: 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 +============= + +Info +---- + +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:: php + + $targets = $service->getAgentTargets(); + + foreach ($targets as $target) { + echo $target->getType(); + } + diff --git a/doc/_build/html/_sources/services/monitoring/Alarms.md.txt b/doc/_build/html/_sources/services/monitoring/Alarms.md.txt new file mode 100644 index 000000000..2918637e9 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Alarms.md.txt @@ -0,0 +1,81 @@ +Alarms +====== + +Info +---- + +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 +----- + +Alarms are sub-resources of Entities: + +.. code:: php + + $alarmId = 'alAAAA'; + $alarm = $check->getAlarm(); + +For more information about working with Checks, please see the +`appropriate documentation `__. + +Attributes +---------- + ++--------------------------+-----------------------------------------------------------------------------+-------------+---------------------------------+ +| 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:: php + + $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:: php + + $alarms = $entity->getAlarms(); + + foreach ($alarms as $alarm) { + echo $alarm->getId(); + } + +Update and delete Alarm +----------------------- + +.. code:: php + + // Update + $alarm->update(array( + 'criteria' => 'if (metric["duration"] >= 5) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);' + )); + + // Delete + $alarm->delete(); + diff --git a/doc/_build/html/_sources/services/monitoring/Changelogs.md.txt b/doc/_build/html/_sources/services/monitoring/Changelogs.md.txt new file mode 100644 index 000000000..2e9059e26 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Changelogs.md.txt @@ -0,0 +1,21 @@ +Changelogs +========== + +Info +---- + +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. + +Working with Changelogs +----------------------- + +.. code:: php + + $changelog = $service->getChangelog(); + + foreach ($changelog as $item) { + $entity = $item->getEntityId(); + } + diff --git a/doc/_build/html/_sources/services/monitoring/Checks.md.txt b/doc/_build/html/_sources/services/monitoring/Checks.md.txt new file mode 100644 index 000000000..0e8e902a5 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Checks.md.txt @@ -0,0 +1,211 @@ +Checks +====== + +Info +---- + +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). + +Setup +----- + +Checks are sub-resources of Entities: + +.. code:: php + + $checkId = 'chAAAA'; + $check = $entity->getCheck($checkId); + +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) | ++------------+-------------------------------------------------------------------------------------------------------------+-------------+------------------------------------------+ + +Attributes used for 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 (before create) +------------------------------- + +.. code:: 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' + ); + + // You can do a test to see what would happen + // if a Check is launched with these params + $response = $entity->testNewCheckParams($params); + + echo $response->timestamp; // When was it executed? + echo $response->available; // Was it available? + echo $response->status; // Status code + +Create a Check +-------------- + +.. code:: php + + $entity->createCheck($params); + +Test existing Check +------------------- + +.. code:: php + + // Set arg to TRUE for debug information + $response = $check->test(true); + + echo $response->debug_info; + +List Checks +----------- + +.. code:: php + + $checks = $entity->getChecks(); + + foreach ($checks as $check) { + echo $check->getId(); + } + +Update and delete Check +~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + // Update + $check->update(array('period' => 500)); + + // Delete + $check->delete(); + +Check types +=========== + +Info +---- + +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. + +Setup +----- + +If you want to see the type for an existing Check: + +.. code:: php + + /** @var \OpenCloud\CloudMonitoring\Resource\CheckType */ + $checkType = $check->getCheckType(); + +Alternatively, you can retrieve a specific type based on its ID: + +.. code:: php + + $checkTypeId = 'remote.dns'; + $checkType = $service->getCheckType($checkTypeId); + +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()`` | ++------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------------------+ + +List all possible check types +----------------------------- + +.. code:: php + + $checkTypes = $service->getCheckTypes(); + + foreach ($checkTypes as $checkType) { + echo $checkType->getId(); + } + diff --git a/doc/_build/html/_sources/services/monitoring/Entities.md.txt b/doc/_build/html/_sources/services/monitoring/Entities.md.txt new file mode 100644 index 000000000..068aec122 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Entities.md.txt @@ -0,0 +1,77 @@ + Entities +========= + +Info +---- + +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. + +Setup +----- + +.. code:: php + + $entity = $service->getEntity(); + +For more information about setting up the ``$service`` object, please +see the userguide tutorial for `services `__. + +Attributes +---------- + ++-----------------+-------------------------------------------------------------------------+-------------+-----------------------------------------------------+------------------------+ +| Name | Description | Required? | Data type | Method | ++=================+=========================================================================+=============+=====================================================+========================+ +| label | Defines a name for the entity. | Required | String (1..255 chars) | ``getLabel()`` | ++-----------------+-------------------------------------------------------------------------+-------------+-----------------------------------------------------+------------------------+ +| agent\_id | Agent to which this entity is bound to. | Optional | String matching the regex: ``/^[-\.\w]{1,255}$/`` | ``getAgentId()`` | ++-----------------+-------------------------------------------------------------------------+-------------+-----------------------------------------------------+------------------------+ +| ip\_addresses | Hash of IP addresses that can be referenced by checks on this entity. | Optional | Array | ``getIpAddresses()`` | ++-----------------+-------------------------------------------------------------------------+-------------+-----------------------------------------------------+------------------------+ +| metadata | Arbitrary key/value pairs that are passed during the alerting phase. | Optional | ``OpenCloud\Common\Metadata`` | ``getMetadata()`` | ++-----------------+-------------------------------------------------------------------------+-------------+-----------------------------------------------------+------------------------+ + +Create Entity +------------- + +.. code:: 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' + ) + )); + +Update and delete Entity +------------------------ + +.. code:: php + + // Update + $entity->update(array( + 'label' => 'New label for my entity' + )); + + // Delete + $entity->delete(); + diff --git a/doc/_build/html/_sources/services/monitoring/Metrics.md.txt b/doc/_build/html/_sources/services/monitoring/Metrics.md.txt new file mode 100644 index 000000000..4231cf914 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Metrics.md.txt @@ -0,0 +1,131 @@ + Metrics +======== + +Info +---- + +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 +------ + +Metrics are sub-resources of Checks. For more information about working +with Checks, please see the `relevant documentation `__. + +List all metrics +---------------- + +.. code:: php + + $metrics = $check->getMetrics(); + + foreach ($metrics as $metric) { + echo $metric->getName(); + } + +Fetch data points +----------------- + +.. code:: php + + $data = $check->fetchDataPoints('mzdfw.available', array( + 'resolution' => 'FULL', + 'from' => 1369756378450, + 'to' => 1369760279018 + )); + diff --git a/doc/_build/html/_sources/services/monitoring/Notifications.md.txt b/doc/_build/html/_sources/services/monitoring/Notifications.md.txt new file mode 100644 index 000000000..f361e3c9c --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Notifications.md.txt @@ -0,0 +1,281 @@ +Notifications +============= + +Info +---- + +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). + +Setup +----- + +.. code:: php + + $id = 'ntAAAA'; + $notification = $service->getNotification($id); + +Attributes +---------- + ++-----------+---------------------------------------------------------------------------+-----------------------------------------------------------+--------------------+ +| 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()`` | ++-----------+---------------------------------------------------------------------------+-----------------------------------------------------------+--------------------+ + +Test parameters +--------------- + +.. code:: php + + $params = array( + 'label' => 'My webhook #1', + 'type' => 'webhook', + 'details' => array( + 'url' => 'http://example.com' + ) + ); + + // Test it + $response = $notification->testParams($params); + + if ($response->status == 'Success') { + echo $response->message; + } + +Create Notification +------------------- + +.. code:: php + + $notification->create($params); + +Test existing notification +-------------------------- + +.. code:: php + + $response = $notification->testExisting(true); + echo $response->debug_info; + +List Notifications +------------------ + +.. code:: php + + $notifications = $service->getNotifications(); + + foreach ($notifications as $notification) { + echo $notification->getId(); + } + +Update and delete Notifications +------------------------------- + +.. code:: php + + // Update + $notification->update(array( + 'label' => 'New notification label' + )); + + // Delete + $notification->delete(); + +Notification types +================== + +Info +---- + +Pretty self-explanatory. 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:: php + + $type = $notification->getNotificationType(); + +Alternatively, you can retrieve an independent resource using the ID: + +.. code:: php + + $typeId = 'pagerduty'; + $type = $service->getNotificationType($typeId); + +List all possible notification types +------------------------------------ + +.. code:: php + + $types = $service->getNotificationTypes(); + + foreach ($types as $type) { + echo sprintf('%s %s', $type->getName(), $type->getDescription()); + } + +Notification plans +================== + +Info +---- + +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. + +Setup +----- + +.. code:: php + + $planId = 'npAAAA'; + $plan = $service->getNotificationPlan(); + +Attributes +---------- + ++-------------------+--------------------------------------------------------------------+-------------+-------------------------+--------------------------+ +| 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:: php + + $plan->create(array( + 'label' => 'New Notification Plan', + 'critical_state' => array('ntAAAA'), + 'ok_state' => array('ntBBBB'), + 'warning_state' => array('ntCCCC') + )); + +Update and delete Notification Plan +----------------------------------- + +.. code:: php + + // Update + $plan->update(array( + 'label' => 'New label for my plan' + )); + + // Delete + $plan->delete(); + +Alarm Notification History +========================== + +Info +---- + +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 +------ + +Notification History is a sub-resource of an Alarm. For more information +about working with Alarms, please consult the relevant +`documentation `__. + +Discover which Checks have a Notification History +------------------------------------------------- + +This operation list checks for which alarm notification history is +available: + +.. code:: php + + $checks = $alarm->getRecordedChecks(); + +List Alarm Notification History for a particular Check +------------------------------------------------------ + +.. code:: php + + $checkHistory = $alarm->getNotificationHistoryForCheck('chAAAA'); + +Get a particular Notification History item +------------------------------------------ + +.. code:: php + + $checkId = 'chAAAA'; + $itemUuid = '646ac7b0-0b34-11e1-a0a1-0ff89fa2fa26'; + + $singleItem = $history->getNotificationHistoryItem($checkId, $itemUuid); + diff --git a/doc/_build/html/_sources/services/monitoring/Service.md.txt b/doc/_build/html/_sources/services/monitoring/Service.md.txt new file mode 100644 index 000000000..09c25c21d --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Service.md.txt @@ -0,0 +1,23 @@ +Cloud Monitoring Service +======================== + +Initializing the Cloud Monitoring is easy - and can be done in a similar +way to all other Rackspace services: + +1. Create client and pass in auth details. For more information about + creating clients, please consult the `Client + documentation <../Clients.md>`__. +2. Use the factory method, specifying additional parameters where + necessary: + +.. code:: php + + $service = $client->cloudMonitoringService('cloudMonitoring', 'ORD', 'publicURL'); + +All three parameters are optional - if not specified, it will revert to +the service's default values which are: + +- Name = ``cloudMonitoring`` +- Region = ``DFW`` +- URL type = ``publicURL`` + diff --git a/doc/_build/html/_sources/services/monitoring/Views.md.txt b/doc/_build/html/_sources/services/monitoring/Views.md.txt new file mode 100644 index 000000000..a5b7245fa --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Views.md.txt @@ -0,0 +1,27 @@ +Views +===== + +Info +---- + +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 +-------------- + +\`\`\`php $views = $service->getViews(); + +foreach ($views as $view) { $entity = $view->getEntity(); + +:: + + echo $view->getTimestamp(); + +} \`\`\` + +Please consult the `iterator doc `__ for +more information about iterators. diff --git a/doc/_build/html/_sources/services/monitoring/Zones.md.txt b/doc/_build/html/_sources/services/monitoring/Zones.md.txt new file mode 100644 index 000000000..ffe4bba1e --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/Zones.md.txt @@ -0,0 +1,67 @@ +Zones +===== + +Info +---- + +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. + + Setup +------ + +.. code:: php + + $zoneId = 'mzAAAAA'; + $zone = $monitoringService->getMonitoringZone($zoneId); + +Attributes +---------- + ++-----------------+------------------+-----------------------------------+------------------------+ +| 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:: php + + $zones = $service->getMonitoringZones(); + +Please consult the `iterator doc `__ for +more information about iterators. + +Perform a traceroute +-------------------- + +.. code:: 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/_build/html/_sources/services/monitoring/agents.txt b/doc/_build/html/_sources/services/monitoring/agents.txt new file mode 100644 index 000000000..f4c673608 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/agents.txt @@ -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/_build/html/_sources/services/monitoring/alarms.txt b/doc/_build/html/_sources/services/monitoring/alarms.txt new file mode 100644 index 000000000..297a57407 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/alarms.txt @@ -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/_build/html/_sources/services/monitoring/changelogs.txt b/doc/_build/html/_sources/services/monitoring/changelogs.txt new file mode 100644 index 000000000..a6b26af25 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/changelogs.txt @@ -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/_build/html/_sources/services/monitoring/checks.txt b/doc/_build/html/_sources/services/monitoring/checks.txt new file mode 100644 index 000000000..73474c170 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/checks.txt @@ -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/_build/html/_sources/services/monitoring/entities.txt b/doc/_build/html/_sources/services/monitoring/entities.txt new file mode 100644 index 000000000..7e4132af1 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/entities.txt @@ -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/_build/html/_sources/services/monitoring/index.txt b/doc/_build/html/_sources/services/monitoring/index.txt new file mode 100644 index 000000000..0a7225e36 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/index.txt @@ -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/_build/html/_sources/services/monitoring/metrics.txt b/doc/_build/html/_sources/services/monitoring/metrics.txt new file mode 100644 index 000000000..0b412a6a3 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/metrics.txt @@ -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/_build/html/_sources/services/monitoring/notifications.txt b/doc/_build/html/_sources/services/monitoring/notifications.txt new file mode 100644 index 000000000..d7e289ad5 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/notifications.txt @@ -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/_build/html/_sources/services/monitoring/views.txt b/doc/_build/html/_sources/services/monitoring/views.txt new file mode 100644 index 000000000..e83b97154 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/views.txt @@ -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/_build/html/_sources/services/monitoring/zones.txt b/doc/_build/html/_sources/services/monitoring/zones.txt new file mode 100644 index 000000000..bb588a303 --- /dev/null +++ b/doc/_build/html/_sources/services/monitoring/zones.txt @@ -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/_build/html/_sources/services/networking/README.md.txt b/doc/_build/html/_sources/services/networking/README.md.txt new file mode 100644 index 000000000..605805fe1 --- /dev/null +++ b/doc/_build/html/_sources/services/networking/README.md.txt @@ -0,0 +1,108 @@ +Networking +========== + +**Networking** is a service that you can use to create virtual networks +and attach cloud devices such as servers to these networks. + +Concepts +-------- + +Concepts +-------- + +To use the Networking service effectively, you should understand the +following key concepts: + +- **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. + +Getting started +--------------- + +1. Instantiate an OpenStack or Rackspace client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the Networking service, you must first instantiate a +``OpenStack`` or ``Rackspace`` client object. + +- If you are working with an OpenStack cloud, instantiate an + ``OpenCloud\OpenStack`` client as follows: + + .. code:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + +- If you are working with the Rackspace cloud, instantiate a + ``OpenCloud\Rackspace`` client as follows: + + .. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +2. Obtain an Networking service object from the client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All Networking operations are done via an *networking service object*. +To instantiate this object, call the ``networkingService`` method on the +``$client`` object. This method takes two arguments: + ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+---------------------+ +| Position | Description | Data type | Required? | Default value | Example value | ++============+=============================================================+=============+=============+====================================================+=====================+ +| 1 | Name of the service, as it appears in the service catalog | String | No | ``null``; automatically determined when possible | ``cloudNetworks`` | ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+---------------------+ +| 2 | Cloud region | String | Yes | - | ``DFW`` | ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+---------------------+ + +.. code:: php + + $region = ''; + $networkingService = $client->networkingService(null, $region); + +Any networks, subnets, and ports created with this +``$networkingService`` instance will be stored in the cloud region +specified by ``$region``. + +3. Create a network. +~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $network = $networkingService->createNetwork(array( + 'name' => 'My private backend network' + )); + +[ `Get the executable PHP script for this +example `__ ] + +Next steps +---------- + +Once you have created a network, there is more you can do with it. See +`complete user guide for networking `__. diff --git a/doc/_build/html/_sources/services/networking/USERGUIDE.md.txt b/doc/_build/html/_sources/services/networking/USERGUIDE.md.txt new file mode 100644 index 000000000..bfeb27774 --- /dev/null +++ b/doc/_build/html/_sources/services/networking/USERGUIDE.md.txt @@ -0,0 +1,582 @@ +Complete User Guide for the Networking Service +============================================== + +Networking is a service that you can use to create virtual networks and +attach cloud devices such as servers to these networks. + +This user guide introduces you the entities in the Networking service — +networks, subnets, and ports — and shows you how to create and manage +these entities. + +Table of contents +----------------- + +- `Concepts <#concepts>`__ +- `Prerequisites <#prerequisites>`__ + + - `Client <#client>`__ + - `Networking service <#networking-service>`__ + +- `Networks <#networks>`__ + + - `Create a network <#create-a-network>`__ + - `Create multiple networks <#create-multiple-networks>`__ + - `List networks <#list-networks>`__ + - `Get a network <#get-a-network>`__ + - `Update a network <#update-a-network>`__ + - `Delete a network <#delete-a-network>`__ + +- `Subnets <#subnets>`__ + + - `Create a subnet <#create-a-subnet>`__ + - `Create multiple subnets <#create-multiple-subnets>`__ + - `List subnets <#list-subnets>`__ + - `Get a subnet <#get-a-subnet>`__ + - `Update a subnet <#update-a-subnet>`__ + - `Delete a subnet <#delete-a-subnet>`__ + +- `Ports <#ports>`__ + + - `Create a port <#create-a-port>`__ + - `Create multiple ports <#create-multiple-ports>`__ + - `List ports <#list-ports>`__ + - `Get a port <#get-a-port>`__ + - `Update a port <#update-a-port>`__ + - `Delete a port <#delete-a-port>`__ + +Concepts +-------- + +To use the Networking service effectively, you should understand the +following key concepts: + +- **Network**: An isolated virtual layer-2 broadcast domain that is + typically reserved for the tenant who created it unless it is + configured to be shared. The network is the main entity in the + Networking service. Ports and subnets are always associated with a + network. + +- **Subnet**: 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 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 or addresses to be assigned to the interfaces + plugged into them. When IP addresses are associated with a port, this + also implies the port is associated with a subnet because the IP + address is taken from the allocation pool for a specific subnet. + +Prerequisites +------------- + +Client +~~~~~~ + +To use the Networking service, you must first instantiate a +``OpenStack`` or ``Rackspace`` client object. + +- If you are working with an OpenStack cloud, instantiate an + ``OpenCloud\OpenStack`` client as follows: + + .. code:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + +- If you are working with the Rackspace cloud, instantiate an + ``OpenCloud\Rackspace`` client as follows: + + .. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +Networking service +~~~~~~~~~~~~~~~~~~ + +All Networking operations are done via a *networking service object*. To +instantiate this object, call the ``networkingService`` method on the +``$client`` object. This method takes the following arguments: + ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+---------------------+ +| Position | Description | Data type | Required? | Default value | Example value | ++============+=============================================================+=============+=============+====================================================+=====================+ +| 1 | Name of the service, as it appears in the service catalog | String | No | ``null``; automatically determined when possible | ``cloudNetworks`` | ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+---------------------+ +| 2 | Cloud region | String | Yes | - | ``DFW`` | ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+---------------------+ + +.. code:: php + + $region = ''; + $networkingService = $client->networkingService(null, $region); + +Any networks, subnets, and ports created with this +``$networkingService`` instance are stored in the cloud region specified +by ``$region``. + +Networks +-------- + +A network is an isolated virtual layer-2 broadcast domain that is +typically reserved for the tenant who created it unless it is configured +to be shared. The network is the main entity in the Networking service. +Ports and subnets are always associated with a network. + +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:: php + + $network = $networkingService->createNetwork(array( + 'name' => 'My private backend network' + )); + /** @var $network OpenCloud\Networking\Resource\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:: 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:: 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:: php + + $network = $networkingService->getNetwork('eb60583c-57ea-41b9-8d5c-8fab2d22224c'); + /** @var $network OpenCloud\Networking\Resource\Network **/ + +[ `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:: 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:: php + + $network->delete(); + +[ `Get the executable PHP script for this +example `__ ] + +Subnets +------- + +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. + +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:: php + + $subnet = $networkingService->createSubnet(array( + 'name' => 'My subnet', + 'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c', + 'ipVersion' => 4, + 'cidr' => '192.168.199.0/25' + )); + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ + +[ `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:: 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:: 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:: php + + $subnet = $networkingService->getSubnet('d3f15879-fb11-49bd-a30b-7704fb98ab1e'); + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ + +[ `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:: 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:: php + + $subnet->delete(); + +[ `Get the executable PHP script for this +example `__ ] + +Ports +----- + +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 or addresses to be assigned to the interfaces +plugged into them. When IP addresses are associated with a port, this +also implies the port is associated with a subnet because the IP address +is taken from the allocation pool for a specific subnet. + +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:: php + + $port = $networkingService->createPort(array( + 'name' => 'My port', + 'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c' + )); + /** @var $port OpenCloud\Networking\Resource\Port **/ + +[ `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:: 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:: 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:: php + + $port = $networkingService->getPort('75906d20-6625-11e4-9803-0800200c9a66'); + /** @var $port OpenCloud\Networking\Resource\Port **/ + +[ `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:: 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:: php + + $port->delete(); + +[ `Get the executable PHP script for this +example `__ ] diff --git a/doc/_build/html/_sources/services/networking/index.txt b/doc/_build/html/_sources/services/networking/index.txt new file mode 100644 index 000000000..335f6a10c --- /dev/null +++ b/doc/_build/html/_sources/services/networking/index.txt @@ -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/_build/html/_sources/services/networking/networks.txt b/doc/_build/html/_sources/services/networking/networks.txt new file mode 100644 index 000000000..b95d44eba --- /dev/null +++ b/doc/_build/html/_sources/services/networking/networks.txt @@ -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/_build/html/_sources/services/networking/ports.txt b/doc/_build/html/_sources/services/networking/ports.txt new file mode 100644 index 000000000..8eeb07bf0 --- /dev/null +++ b/doc/_build/html/_sources/services/networking/ports.txt @@ -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/_build/html/_sources/services/networking/security-group-rules.txt b/doc/_build/html/_sources/services/networking/security-group-rules.txt new file mode 100644 index 000000000..1ca6041d1 --- /dev/null +++ b/doc/_build/html/_sources/services/networking/security-group-rules.txt @@ -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/_build/html/_sources/services/networking/security-groups.txt b/doc/_build/html/_sources/services/networking/security-groups.txt new file mode 100644 index 000000000..cde5c9a2d --- /dev/null +++ b/doc/_build/html/_sources/services/networking/security-groups.txt @@ -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/_build/html/_sources/services/networking/subnets.txt b/doc/_build/html/_sources/services/networking/subnets.txt new file mode 100644 index 000000000..9a6c2a7b4 --- /dev/null +++ b/doc/_build/html/_sources/services/networking/subnets.txt @@ -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/_build/html/_sources/services/object-store/Access.md.txt b/doc/_build/html/_sources/services/object-store/Access.md.txt new file mode 100644 index 000000000..ee85a938e --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Access.md.txt @@ -0,0 +1,75 @@ +Setup +----- + +.. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(RACKSPACE_US, array( + + )); + + $service = $client->objectStoreService('cloudFiles', 'IAD'); # Second argument is the region you want + +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:: 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:: php + + $object->getTemporaryUrl(60, 'GET'); + +To allow PUT access for 1 hour: + +.. code:: php + + $object->getTemporaryUrl(360, 'PUT'); + +Hosting websites on CloudFiles +------------------------------ + +To host a static (i.e. HTML) website on CloudFiles, you must follow +these steps: + +1. CDN-enable a container +2. Upload all HTML content. You can use nested directory structures. +3. Tell CloudFiles what to use for your default index page like this: + +.. code:: php + + $container->setStaticIndexPage('index.html'); + +4. (Optional) Tell CloudFiles which error page to use by default: + +.. code:: 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/_build/html/_sources/services/object-store/Account.md.txt b/doc/_build/html/_sources/services/object-store/Account.md.txt new file mode 100644 index 000000000..a2d380b2a --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Account.md.txt @@ -0,0 +1,33 @@ +Setup +----- + +.. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(RACKSPACE_US, array( + + )); + + $service = $client->objectStoreService('cloudFiles'); + +View 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): + +.. code:: php + + $account = $service->getAccount(); + + // Either return the full Metadata object + $details = $account->getDetails(); + + // or individual values + $account->getContainerCount(); + $account->getObjectCount(); + $account->getBytesUsed(); + diff --git a/doc/_build/html/_sources/services/object-store/Container.md.cdn.txt b/doc/_build/html/_sources/services/object-store/Container.md.cdn.txt new file mode 100644 index 000000000..2f1c8ea68 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Container.md.cdn.txt @@ -0,0 +1,90 @@ +Setup +----- + +.. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(RACKSPACE_US, array( + + )); + + $service = $client->objectStoreService('cloudFiles'); + +To access the CDN functionality of a particular container: + +.. code:: php + + $container = $service->getContainer('foo_bar'); + + $cdn = $container->getCdn(); + +List CDN-enabled container +-------------------------- + +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:: php + + $cdnService = $service->getCdnService(); + $cdnContainers = $cdnService->listContainers(); + + foreach ($cdnContainers as $cdnContainer) { + + } + +CDN-enable and -disable 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:: php + + $container->enableCdn(); + $container->disableCdn(); + +Serving containers through SSL +------------------------------ + +.. code:: php + + $cdn->getCdnSslUri(); + +Streaming CDN-enabled containers +-------------------------------- + +.. code:: php + + $cdn->getCdnStreamingUri(); + +iOS streaming +------------- + +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:: php + + $cdn->getIosStreamingUri(); + +CDN logging +----------- + +To enable and disable logging for your CDN: + +.. code:: php + + $cdn->enableCdnLogging(); + $cdn->disableCdnLogging(); + diff --git a/doc/_build/html/_sources/services/object-store/Container.md.storage.txt b/doc/_build/html/_sources/services/object-store/Container.md.storage.txt new file mode 100644 index 000000000..89798fdd0 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Container.md.storage.txt @@ -0,0 +1,218 @@ +Setup +----- + +.. code:: php + + use OpenCloud\Rackspace; + + // Create a client object to communicate with various Rackspace Cloud services. + $client = new Rackspace(RACKSPACE_US, array( + 'username' => 'Replace this with your Rackspace Cloud user name', + 'apiKey' => 'Replace this with your Rackspace Cloud API key' + )); + + // Create a service object to use the object store service. The sample code + // creates the object store in the 'DFW' region. + $service = $client->objectStoreService('cloudFiles', 'DFW'); + +Create container +---------------- + +To create a new container, you just need to define its name: + +.. code:: 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 +--------------- + +Return a list of containers +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $containerList = $service->listContainers(); + + while ($container = $containerList->next()) { + // Do stuff; some examples below + 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. See 1.3 for ways to +limit and navigate this list. + +Return a formatted list of containers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently, the SDK only supports JSON-formatted responses. + +Controlling a large list of containers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You may limit and control this list of results 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:: php + + $someContainers = $service->listContainers(array( + 'marker' => 'container_55', + 'end_marker' => 'container_2001' + )); + +Or to return a limited set: + +.. code:: php + + $someContainers = $service->listContainers(array('limit' => 560)); + +Get container +------------- + +To retrieve a certain container, either to access its object or +metadata: + +.. code:: php + + $container = $service->getContainer('container_name'); + + echo $container->getObjectCount(); + echo $container->getBytesUsed(); + +Delete container +---------------- + +Deleting a container is easy: + +.. code:: 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:: php + + $container->delete(TRUE); + +You can also do it manually: + +.. code:: php + + $container->deleteAllObjects(); + $container->delete(); + +Create or update container metadata +----------------------------------- + +.. code:: 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:: php + + $metadata = $container->appendToMetadata(array( + 'Publisher' => 'Hogarth' + )); + +If you only want to set the metadata to the local object, and not +immediately retain these values on the API, you can use a standard +setter method - which can contribute to eventual actions like an update: + +.. code:: php + + $container->setMetadata(array('Foo' => 'Bar')); + +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:: php + + use OpenCloud\Common\Constants\Size; + + $container->setCountQuota(1000); + $container->setBytesQuota(2.5 * Size::GB); + +And to retrieve them: + +.. code:: 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:: 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:: php + + $container->uploadDirectory('/home/Jamie/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/_build/html/_sources/services/object-store/Migrating.md.storage.txt b/doc/_build/html/_sources/services/object-store/Migrating.md.storage.txt new file mode 100644 index 000000000..99738554b --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Migrating.md.storage.txt @@ -0,0 +1,101 @@ +Migrating containers (across regions) +===================================== + +Introduction +------------ + +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:: bash + + php composer.phar install --dev + +- Depending on the size and number of transfer items, you will need to + raise PHP's memory limit: + +.. code:: 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:: php + + use Guzzle\Plugin\Backoff\BackoffPlugin; + + $client->addSubscriber(BackoffPlugin::getExponentialBackoff(10, array(500, 503, 408))); + +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:: 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:: 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:: 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/_build/html/_sources/services/object-store/Object.md.cdn.txt b/doc/_build/html/_sources/services/object-store/Object.md.cdn.txt new file mode 100644 index 000000000..64ac143b3 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Object.md.cdn.txt @@ -0,0 +1,25 @@ +Setup +----- + +You will need to instantiate the container object and access its CDN +functionality as `documented +here `__. + +Purge CDN-enabled objects +------------------------- + +To remove a CDN object from public access: + +.. code:: 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:: php + + $object->purge('jamie.hannaford@rackspace.com'); + $object->purge('hello@example.com,hallo@example.com'); + diff --git a/doc/_build/html/_sources/services/object-store/Object.md.storage.txt b/doc/_build/html/_sources/services/object-store/Object.md.storage.txt new file mode 100644 index 000000000..16dab18f4 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/Object.md.storage.txt @@ -0,0 +1,330 @@ +Setup +----- + +Conceptually, a container contains objects (also known as files). In +order to work with objects, you will need to instantiate a container +object first as `documented +here `__. + +Note on object properties +------------------------- + +Please be aware that you cannot directly access the properties of +DataObject anymore, you **must** use appropriate getter/ setter methods: + ++----------------------+------------------------+ +| Property | Method | ++======================+========================+ +| Parent container | ``getContainer`` | ++----------------------+------------------------+ +| Name | ``getName`` | ++----------------------+------------------------+ +| Body of file | ``getContent`` | ++----------------------+------------------------+ +| Size of file | ``getContentLength`` | ++----------------------+------------------------+ +| Type of file | ``getContentType`` | ++----------------------+------------------------+ +| ETag checksum | ``getEtag`` | ++----------------------+------------------------+ +| Last modified date | ``getLastModified`` | ++----------------------+------------------------+ + +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 + +To upload a single/basic file: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + use OpenCloud\ObjectStore\Resource\DataObject; + + $data = fopen('/path/to/sample.mp3', 'r+'); + + // alternatively, you can pass in a string as the file contents `$data` argument (instead of a resource) + + $meta = array( + 'Author' => 'Camera Obscura', + 'Origin' => 'Glasgow' + ); + + $metaHeaders = DataObject::stockHeaders($meta); + $customHeaders = array(); + $allHeaders = $metaHeaders + $customHeaders; + + $container->uploadObject('sample.mp3', $data, $allHeaders); + +To upload multiple small-to-mid sized files: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: 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. + +To upload large files +~~~~~~~~~~~~~~~~~~~~~ + +For files over 5GB, you will need to use the +``OpenCloud\ObjectStore\Upload\TransferBuilder`` factory to build your +transfer, upon which you can execute your upload functionality. For your +convenience, the Container resource object contains a simple method to +do this heavy lifting for you: + +.. code:: php + + $transfer = $container->setupObjectTransfer(array( + 'name' => 'video.mov', + 'path' => '/home/jamie/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 manifest 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. + +List objects in a container +--------------------------- + +To return a list of objects: + +.. code:: php + + $files = $container->objectList(); + + foreach ($files as $file) { + // ... do something + } + +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:: php + + $container->objectList(array('prefix' => 'logFile_')); + +Get object +---------- + +To retrieve a specific file from Cloud Files: + +.. code:: php + + $file = $container->getObject('summer_vacation.mp4'); + +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:: 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): + +:: + + 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:: php + + $snippet = $container->getObject('output.log', array('range' => 'bytes=-20')); + +Update an existing object +------------------------- + +Updating content is easy: + +.. code:: 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 copy a file to another location, you need to specify a string-based +destination path: + +.. code:: php + + $object->copy('/container_2/new_object_name'); + +Delete object +------------- + +.. code:: php + + $object->delete(); + +Get object metadata +------------------- + +You can fetch just the object metadata without fetching the full +content: + +.. code:: php + + $container->getPartialObject('summer_vacation.mp4'); + +In order to access the metadata on a partial or complete object, use: + +.. code:: php + + $object->getMetadata(); + +You can turn a partial object into a full object to get the content +after looking at the metadata: + +.. code:: php + + $object->refresh(); + +You can also update to get the latest metadata: + +.. code:: 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:: 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:: 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:: 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:: 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. + +Bulk delete +----------- + +Bulk delete a set of paths: + +.. code:: php + + $pathsToBeDeleted = array('/container_1/old_file', '/container_2/notes.txt', '/container_1/older_file.log'); + + $service->bulkDelete($pathsToBeDeleted); + diff --git a/doc/_build/html/_sources/services/object-store/README.md.txt b/doc/_build/html/_sources/services/object-store/README.md.txt new file mode 100644 index 000000000..01cf26733 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/README.md.txt @@ -0,0 +1,86 @@ +Object Store +============ + +**Object Store** is an object-based storage system that stores content +and metadata as objects in a cloud. + +Specifically, a cloud is made up of one or more regions. Each region can +have several **containers**, created by a user. Each container can +container several **objects** (sometimes referred to as files), uploaded +by the user. + +Getting started +--------------- + +1. Instantiate an OpenStack or Rackspace client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Choose one of the following two options: + +- If you are working with a vanilla OpenStack cloud, instantiate an + ``OpenCloud\OpenStack`` client as shown below. + + .. code:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + +- If you are working with the Rackspace cloud, instantiate a + ``OpenCloud\Rackspace`` client as shown below. + + .. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +2. Obtain an Object Store service object from the client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $region = 'DFW'; + $objectStoreService = $client->objectStoreService(null, $region); + +In the example above, you are connecting to the ``DFW`` region of the +cloud. Any containers and objects created with this +``$objectStoreService`` instance will be stored in that cloud region. + +3. Create a container for your objects (also referred to as files). +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $container = $objectStoreService->createContainer('logos'); + + **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 + +4. Upload an object to the container. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $localFileName = '/path/to/local/php-elephant.jpg'; + $remoteFileName = 'php-elephant.jpg'; + + $fileData = fopen($localFileName, 'r'); + $container->uploadObject($remoteFileName, $fileData); + +[ `Get the executable PHP script for this +example `__ ] + +Next steps +---------- + +There is a lot more you can do with containers and objects. See the +`complete user guide to the Object Store service `__. diff --git a/doc/_build/html/_sources/services/object-store/USERGUIDE.md.txt b/doc/_build/html/_sources/services/object-store/USERGUIDE.md.txt new file mode 100644 index 000000000..d9732ea36 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/USERGUIDE.md.txt @@ -0,0 +1,900 @@ +The Complete User Guide to the Object Store Service +=================================================== + +**Object Store** is an object-based storage system that stores content +and metadata as objects in a cloud. + +Prerequisites +------------- + +Client +~~~~~~ + +To use the object store service, you must first instantiate a +``OpenStack`` or ``Rackspace`` client object. + +- If you are working with a vanilla OpenStack cloud, instantiate an + ``OpenCloud\OpenStack`` client as shown below. + + .. code:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'apiKey' => '' + )); + +- If you are working with the Rackspace cloud, instantiate a + ``OpenCloud\Rackspace`` client as shown below. + + .. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +Object Store Service +~~~~~~~~~~~~~~~~~~~~ + +All operations on the object store are done via an object store service +object. + +.. code:: php + + $region = 'DFW'; + $objectStoreService = $client->objectStoreService(null, $region); + +In the example above, you are connecting to the ``DFW`` region of the +cloud. Any containers and objects created with this +``$objectStoreService`` instance will be stored in that cloud region. + +Containers +---------- + +A **container** defines a namespace for **objects**. An object with the +same name in two different containers represents two different objects. + +For example, you may create a container called ``logos`` to hold all the +image files for your blog. + +A container may contain zero or more objects in it. + + **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 + +Create Container +~~~~~~~~~~~~~~~~ + +.. code:: php + + $container = $objectStoreService->createContainer('logos'); + +[ `Get the executable PHP script for this +example `__ ] + +Get Container Details +~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve a single container's details by using its name. An +instance of ``OpenCloud\ObjectStore\Resource\Container`` is returned. + +.. code:: php + + $container = $objectStoreService->getContainer('logos'); + + /** @var $container OpenCloud\ObjectStore\Resource\Container **/ + +[ `Get the executable PHP script for this +example `__ ] + +List Containers +~~~~~~~~~~~~~~~ + +You can retrieve a list of all your containers. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $containers = $objectStoreService->listContainers(); + foreach ($containers as $container) { + /** @var $container OpenCloud\ObjectStore\Resource\Container **/ + } + +[ `Get the executable PHP script for this +example `__ ] + +Set or Update Container Metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can set metadata on a container. + +.. code:: php + + $container->saveMetadata(array( + 'author' => 'John Doe' + )); + +[ `Get the executable PHP script for this +example `__ ] + +Get Container Metadata +~~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve the metadata for a container. + +.. code:: php + + $containerMetadata = $container->getMetadata(); + +[ `Get the executable PHP script for this +example `__ ] + +Delete Container +~~~~~~~~~~~~~~~~ + +When you no longer have a need for the container, you can remove it. + +If the container is empty (that is, it has no objects in it), you can +remove it as shown below: + +.. code:: php + + $container->delete(); + +[ `Get the executable PHP script for this +example `__ ] + +If the container is not empty (that is, it has objects in it), you have +two choices in how to remove it: + +- `Individually remove each object <#delete-object>`__ in the + container, then remove the container itself as shown above, or + +- Remove the container and all the objects within it as shown below: + + .. code:: php + + $container->delete(true); + + [ `Get the executable PHP script for this + example `__ ] + +Get Object Count +~~~~~~~~~~~~~~~~ + +You can quickly find out how many objects are in a container. + +.. code:: php + + $containerObjectCount = $container->getObjectCount(); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, ``$containerObjectCount`` will contain the number +of objects in the container represented by ``$container``. + +Get Bytes Used +~~~~~~~~~~~~~~ + +You can quickly find out the space used by a container, in bytes. + +.. code:: php + + $containerSizeInBytes = $container->getBytesUsed(); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, ``$containerSizeInBytes`` will contain the space +used, in bytes, by the container represented by ``$container``. + +Container Quotas +~~~~~~~~~~~~~~~~ + +Set Quota for Number of Objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can set a quota for the maximum number of objects that may be stored +in a container. + +.. code:: php + + $maximumNumberOfObjectsAllowedInContainer = 25; + $container->setCountQuota($maximumNumberOfObjectsAllowedInContainer); + +[ `Get the executable PHP script for this +example `__ ] + +Set Quota for Total Size of Objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can set a quota for the maximum total space (in bytes) used by +objects in a container. + +.. code:: php + + use OpenCloud\Common\Constants\Size; + + $maximumTotalSizeOfObjectsInContainer = 5 * Size::GB; + $container->setBytesQuota($maximumTotalSizeOfObjectsInContainer); + +[ `Get the executable PHP script for this +example `__ ] + +Get Quota for Number of Objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can retrieve the quota for the maximum number of objects that may be +stored in a container. + +.. code:: php + + $maximumNumberOfObjectsAllowedInContainer = $container->getCountQuota(); + +[ `Get the executable PHP script for this +example `__ ] + +Get Quota for Total Size of Objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can retrieve the quota for the maximum total space (in bytes) used +by objects in a container. + +.. code:: php + + $maximumTotalSizeOfObjectsAllowedInContainer = $container->getBytesQuota(); + +[ `Get the executable PHP script for this +example `__ ] + +Objects +------- + +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. + +For example, you may upload an object named ``php-elephant.jpg``, a JPEG +image file, to the ``logos`` container. Further, you may assign metadata +to this object to indicate that the author of this object was someone +named Jane Doe. + + **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 Object +~~~~~~~~~~~~~ + +Once you have created a container, you can upload objects to it. + +.. code:: php + + $localFileName = '/path/to/local/php-elephant.jpg'; + $remoteFileName = 'php-elephant.jpg'; + + $fileData = fopen($localFileName, 'r'); + $container->uploadObject($remoteFileName, $fileData); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, an image file from the local filesystem +(``path/to/local/php-elephant.jpg``) is uploaded to a container in the +Object Store. + +Note that while we call ``fopen`` to open the file resource, we do not +call ``fclose`` at the end. The file resource is automatically closed +inside the ``uploadObject`` call. + +It is also possible to upload an object and associate metadata with it. + +.. code:: php + + use OpenCloud\ObjectStore\Resource\DataObject; + + $localFileName = '/path/to/local/php-elephant.jpg'; + $remoteFileName = 'php-elephant.jpg'; + $metadata = array('author' => 'Jane Doe'); + + $customHeaders = array(); + $metadataHeaders = DataObject::stockHeaders($metadata); + $allHeaders = $customHeaders + $metadataHeaders; + + $fileData = fopen($localFileName, 'r'); + $container->uploadObject($remoteFileName, $fileData, $allHeaders); + +[ `Get the executable PHP script for this +example `__ ] + +Note that while we call ``fopen`` to open the file resource, we do not +call ``fclose`` at the end. The file resource is automatically closed +inside the ``uploadObject`` call. + +Pseudo-hierarchical Folders +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Although you cannot nest directories in an Object Store, you can +simulate a hierarchical structure within a single container by adding +forward slash characters (``/``) in the object name. + +.. code:: php + + $localFileName = '/path/to/local/php-elephant.jpg'; + $remoteFileName = 'languages/php/elephant.jpg'; + + $fileData = fopen($localFileName, 'r'); + $container->uploadObject($remoteFileName, $fileData); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, an image file from the local filesystem +(``/path/to/local/php-elephant.jpg``) is uploaded to a container in the +Object Store. Within that container, the filename is +``languages/php/elephant.jpg``, where ``languages/php/`` is a +pseudo-hierarchical folder hierarchy. + +Note that while we call ``fopen`` to open the file resource, we do not +call ``fclose`` at the end. The file resource is automatically closed +inside the ``uploadObject`` call. + +Upload Multiple Objects +^^^^^^^^^^^^^^^^^^^^^^^ + +You can upload more than one object at a time to a container. + +.. code:: php + + $objects = array( + array( + 'name' => 'php-elephant.jpg', + 'path' => '/path/to/local/php-elephant.jpg' + ), + array( + 'name' => 'python-snake.jpg', + 'path' => '/path/to/local/python-snake.jpg' + ), + a + ); + + $container->uploadObjects($objects); + +[ `Get the executable PHP script for this +example `__ ] + +In the above example, the contents of two files present on the local +filesystem are uploaded as objects to the container referenced by +``$container``. + +Instead of specifying the ``path`` key in an element of the ``$objects`` +array, you can specify a ``body`` key whose value is a string or a +stream representation. + +Finally, you can pass headers as the second parameter to the +``uploadObjects`` method. These headers will be applied to every object +that is uploaded. + +:: + + $metadata = array('author' => 'Jane Doe'); + + $customHeaders = array(); + $metadataHeaders = DataObject::stockHeaders($metadata); + $allHeaders = $customHeaders + $metadataHeaders; + + $container->uploadObjects($objects, $allHeaders); + +[ `Get the executable PHP script for this +example `__ +] + +In the example above, every object referenced within the ``$objects`` +array will be uploaded with the same metadata. + +Large Objects +~~~~~~~~~~~~~ + +If you want to upload objects larger than 5GB in size, you must use a +different upload process. + +.. code:: php + + $options = array( + 'name' => 'san_diego_vacation_video.mp4', + 'path' => '/path/to/local/videos/san_diego_vacation.mp4' + ); + $objectTransfer = $container->setupObjectTransfer($options); + $objectTransfer->upload(); + +[ `Get the executable PHP script for this +example `__ ] + +The process shown above will automatically partition your large object +into small chunks and upload them concurrently to the container +represented by ``$container``. + +You can tune the parameters of this process by specifying additional +options in the ``$options`` array. Here is a complete listing of keys +that can be specified in the ``$options`` array: + ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| Key name | Description | Data Type | Required? | Default Value | Example | ++===================+================================================================================================================================================================================================================================================================================================================+=================================================+=================================================+==================================================+====================================================+ +| ``name`` | Name of large object in container | String | Yes | - | ``san_diego_vacation_video.mp4`` | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| ``path`` | Path to file containing object data on local filesystem | String | One of ``path`` or ``body`` must be specified | - | ``/path/to/local/videos/san_diego_vacation.mp4`` | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| ``body`` | String or stream representation of object data | String \| Stream | One of ``path`` or ``body`` must be specified | - | ``... lots of data ...`` | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| ``metadata`` | Metadata for the object | Associative array of metadata key-value pairs | No | ``array()`` | ``array( "Author" => "Jane Doe" )`` | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| ``partSize`` | The size, in bytes, of each chunk that the large object is partitioned into prior to uploading | Integer | No | ``1073741824`` (1GB) | ``52428800`` (50MB) | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| ``concurrency`` | The number of concurrent transfers to execute as part of the upload | Integer | No | ``1`` (no concurrency; upload chunks serially) | ``10`` | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ +| ``progress`` | A `callable function or method `__ which is called to report progress of the the upload. See ```CURLOPT_PROGRESSFUNCTION`` documentation `__ for details on parameters passed to this callable function or method. | String (callable function or method name) | No | None | ``reportProgress`` | ++-------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+ + +Auto-extract Archive Files +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can upload a tar archive file and have the Object Store service +automatically extract it into a container. + +.. code:: php + + use OpenCloud\ObjectStore\Constants\UrlType; + + $localArchiveFileName = '/path/to/local/image_files.tar.gz'; + $remotePath = 'images/'; + + $fileData = fopen($localArchiveFileName, 'r'); + $objectStoreService->bulkExtract($remotePath, $fileData, UrlType::TAR_GZ); + +[ `Get the executable PHP script for this +example `__ ] + +In the above example, a local archive file named ``image_files.tar.gz`` +is uploaded to an Object Store container named ``images`` (defined by +the ``$remotePath`` variable). + +Note that while we call ``fopen`` to open a file resource, we do not +call ``fclose`` at the end. The file resource is automatically closed +inside the ``bulkExtract`` call. + +The third parameter to ``bulkExtract`` is the type of the archive file +being uploaded. The acceptable values for this are: + +- ``UrlType::TAR`` for tar archive files, *or*, +- ``UrlType:TAR_GZ`` for tar archive files that are compressed with + gzip, *or* +- ``UrlType::TAR_BZ`` for tar archive file that are compressed with + bzip + +Note that the value of ``$remotePath`` could have been a +(pseudo-hierarchical folder)[#pseudo-hierarchical-folders] such as +``images/blog`` as well. + +List Objects in a Container +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can list all the objects stored in a container. An instance of +``OpenCloud\Common\Collection\PaginatedIterator`` is returned. + +.. code:: php + + $objects = $container->objectList(); + foreach ($objects as $object) { + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ + } + +[ `Get the executable PHP script for this +example `__ ] + +You can list only those objects in the container whose names start with +a certain prefix. + +.. code:: php + + $options = array( + 'prefix' => 'php' + ); + + $objects = $container->objectList($options); + +[ `Get the executable PHP script for this +example `__ ] + +In general, the ``objectList()`` method described above takes an +optional parameter (``$options`` in the example above). This parameter +is an associative array of various options. Here is a complete listing +of keys that can be specified in the ``$options`` array: + ++------------------+-----------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------+ +| Key name | Description | Data Type | Required? | Default Value | Example | ++==================+=============================================================================+=============+=============+=================+=========================+ +| ``prefix`` | Given a string x, limits the results to object names beginning with x. | String | No | | ``php`` | ++------------------+-----------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------+ +| ``limit`` | Given an integer n, limits the number of results to at most n values. | Integer | No | | 10 | ++------------------+-----------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------+ +| ``marker`` | Given a string x, returns object names greater than the specified marker. | String | No | | ``php-elephant.jpg`` | ++------------------+-----------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------+ +| ``end_marker`` | Given a string x, returns object names less than the specified marker. | String | No | | ``python-snakes.jpg`` | ++------------------+-----------------------------------------------------------------------------+-------------+-------------+-----------------+-------------------------+ + +Retrieve Object +~~~~~~~~~~~~~~~ + +You can retrieve an object and its metadata, given the object's +container and name. + +.. code:: php + + $objectName = 'php-elephant.jpg'; + $object = $container->getObject($objectName); + + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ + + $objectContent = $object->getContent(); + + /** @var $objectContent Guzzle\Http\EntityBody **/ + + // Write object content to file on local filesystem. + $objectContent->rewind(); + $stream = $objectContent->getStream(); + $localFilename = tempnam("/tmp", 'php-opencloud-'); + file_put_contents($localFilename, $stream); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, ``$object`` is the object named +``php-elephant.jpg`` in the container represented by ``$container``. +Further, ``$objectContent`` represents the contents of the object. It is +of type +```Guzzle\Http\EntityBody`` `__. + +Retrieve Object Metadata +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve just an object's metadata without retrieving its +contents. + +.. code:: php + + $objectName = 'php-elephant.jpg'; + $object = $container->getPartialObject($objectName); + $objectMetadata = $object->getMetadata(); + + /** @var $objectMetadata \OpenCloud\Common\Metadata **/ + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, while ``$object`` is an instance of +``OpenCloud\ObjectStore\Resource\DataObject``, that instance is only +partially populated. Specifically, only properties of the instance +relating to object metadata are populated. + +Temporary URLs +~~~~~~~~~~~~~~ + +The Temporary URL feature allows you to create limited-time Internet +addresses that allow you to grant limited access to your Object Store +account. Using this feature, you can allow others to retrieve or place +objects in your Object Store account for a specified amount of time. +Access to the temporary URL is independent of whether or not your +account is `CDN-enabled <#cdn-containers>`__. Even if you do not +CDN-enable a container, you can still grant temporary public access +through a temporary URL. + +First, you must set the temporary URL secret on your account. This is a +one-time operation; you only need to perform it the very first time you +wish to use the temporary URLs feature. + +.. code:: php + + $account->setTempUrlSecret(); + +[ `Get the executable PHP script for this +example `__ ] + +Note that this operation is carried out on ``$account``, which is an +instance of ``OpenCloud\ObjectStore\Resource\Account``, a class +representing `your object store account <#accounts>`__. + +The above operation will generate a random secret and set it on your +account. Instead of a random secret, if you wish to provide a secret, +you can supply it as a parameter to the ``setTempUrlSecret`` method. + +.. code:: php + + $account->setTempUrlSecret(''); + +[ `Get the executable PHP script for this +example `__ +] + +Once a temporary URL secret has been set on your account, you can +generate a temporary URL for any object in your Object Store. + +.. code:: php + + $expirationTimeInSeconds = 3600; // one hour from now + $httpMethodAllowed = 'GET'; + $tempUrl = $object->getTemporaryUrl($expirationTimeInSeconds, $httpMethodAllowed); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, a temporary URL for the object is generated. This +temporary URL will provide public access to the object for an hour (3600 +seconds), as specified by the ``$expirationTimeInSeconds`` variable. +Further, only GET HTTP methods will be allowed on this URL, as specified +by the ``$httpMethodAllowed`` variable. The other value allowed for the +``$httpMethodAllowed`` variable would be ``PUT``. + +You can also retrieve the temporary URL secret that has been set on your +account. + +.. code:: php + + $tempUrlSecret = $account->getTempUrlSecret(); + +[ `Get the executable PHP script for this +example `__ ] + +Update Object +~~~~~~~~~~~~~ + +You can update an object's contents (as opposed to `updating its +metadata <#update-object-metadata>`__) by simply re-\ `uploading the +object <#upload-object>`__ to its container using the same object name +as before. + +Update Object Metadata +~~~~~~~~~~~~~~~~~~~~~~ + +You can update an object's metadata after it has been uploaded to a +container. + +.. code:: php + + $object->saveMetadata(array( + 'author' => 'John Doe' + )); + +[ `Get the executable PHP script for this +example `__ ] + +Copy Object +~~~~~~~~~~~ + +You can copy an object from one container to another, provided the +destination container already exists. + +.. code:: php + + $object->copy('logos_copy/php.jpg'); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, both the name of the destination container +(``logos_copy``)and the name of the destination object (``php.jpg``) +have to be specified, separated by a ``/``. + +Delete Object +~~~~~~~~~~~~~ + +When you no longer need an object, you can delete it. + +.. code:: php + + $object->delete(); + +[ `Get the executable PHP script for this +example `__ ] + +Bulk Delete +~~~~~~~~~~~ + +While you can delete individual objects as shown above, you can also +delete objects and empty containers in bulk. + +.. code:: php + + $objectStoreService->bulkDelete(array( + 'logos/php-elephant.png', + 'logos/python-snakes.png', + 'some_empty_container' + )); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, two objects (``some_container/object_a.png``, +``some_other_container/object_z.png``) and one empty container +(``some_empty_container``) are all being deleted in bulk via a single +command. + +CDN Containers +-------------- + +Note: The functionality described in this section is available only on +the Rackspace cloud. It will not work as described when working with a +vanilla OpenStack cloud. + +Any container can be converted to a CDN-enabled container. When this is +done, the objects within the container can be accessed from anywhere on +the Internet via a URL. + +Enable CDN Container +~~~~~~~~~~~~~~~~~~~~ + +To take advantage of CDN capabilities for a container and its objects, +you must CDN-enable that container. + +.. code:: php + + $container->enableCdn(); + +[ `Get the executable PHP script for this +example `__ ] + +Public URLs +~~~~~~~~~~~ + +Once you have CDN-enabled a container, you can retrieve a +publicly-accessible URL for any of its objects. There are four types of +publicly-accessible URLs for each object. Each type of URL is meant for +a different purpose. The sections below describe each of these URL types +and how to retrieve them. + +HTTP URL +^^^^^^^^ + +You can use this type of URL to access the object over HTTP. + +:: + + $httpUrl = $object->getPublicUrl(); + +[ `Get the executable PHP script for this +example `__ ] + +Secure HTTP URL +^^^^^^^^^^^^^^^ + +You can use this type of URL to access the object over HTTP + TLS/SSL. + +:: + + use OpenCloud\ObjectStore\Constants\UrlType; + + $httpsUrl = $object->getPublicUrl(UrlType::SSL); + +[ `Get the executable PHP script for this +example `__ ] + +Streaming URL +^^^^^^^^^^^^^ + +You can use this type of URL to stream a video or audio object using +Adobe's HTTP Dynamic Streaming. + +:: + + use OpenCloud\ObjectStore\Constants\UrlType; + + $streamingUrl = $object->getPublicUrl(UrlType::STREAMING); + +[ `Get the executable PHP script for this +example `__ ] + +IOS Streaming URL +^^^^^^^^^^^^^^^^^ + +You can use this type of URL to stream an audio or video object to an +iOS device. + +:: + + use OpenCloud\ObjectStore\Constants\UrlType; + + $iosStreamingUrl = $object->getPublicUrl(UrlType::IOS_STREAMING); + +[ `Get the executable PHP script for this +example `__ ] + +Update CDN Container TTL +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can update the TTL of a CDN-enabled container. + +.. code:: php + + $cdnContainer = $container->getCdn(); + $cdnContainer->setTtl(); + +[ `Get the executable PHP script for this +example `__ ] + +Disable CDN Container +~~~~~~~~~~~~~~~~~~~~~ + +If you no longer need CDN capabilities for a container, you can disable +them. + +.. code:: php + + $container->disableCdn(); + +[ `Get the executable PHP script for this +example `__ ] + +Accounts +-------- + +An **account** defines a namespace for **containers**. An account can +have zero or more containers in it. + +Retrieve Account +~~~~~~~~~~~~~~~~ + +You must retrieve the account before performing any operations on it. + +.. code:: php + + $account = $objectStoreService->getAccount(); + +Get Container Count +~~~~~~~~~~~~~~~~~~~ + +You can quickly find out how many containers are in your account. + +.. code:: php + + $accountContainerCount = $account->getContainerCount(); + +[ `Get the executable PHP script for this +example `__ ] + +Get Object Count +~~~~~~~~~~~~~~~~ + +You can quickly find out how many objects are in your account. + +.. code:: php + + $accountObjectCount = $account->getObjectCount(); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, ``$accountObjectCount`` will contain the number of +objects in the account represented by ``$account``. + +Get Bytes Used +~~~~~~~~~~~~~~ + +You can quickly find out the space used by your account, in bytes. + +.. code:: php + + $accountSizeInBytes = $account->getBytesUsed(); + +[ `Get the executable PHP script for this +example `__ ] + +In the example above, ``$accountSizeInBytes`` will contain the space +used, in bytes, by the account represented by ``$account``. diff --git a/doc/_build/html/_sources/services/object-store/access.txt b/doc/_build/html/_sources/services/object-store/access.txt new file mode 100644 index 000000000..40fe61670 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/access.txt @@ -0,0 +1,93 @@ +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. + +Get the executable PHP script for this example: + +* `Specify a URL secret `_ +* `Generate random URL secret `_ + + +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'); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/object-store/account.txt b/doc/_build/html/_sources/services/object-store/account.txt new file mode 100644 index 000000000..50c17f1a8 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/account.txt @@ -0,0 +1,52 @@ +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(); + +`Get the executable PHP script for this example `_ + + +Retrieve total object count +--------------------- + +.. code-block:: php + + $account->getObjectCount(); + +`Get the executable PHP script for this example `_ + + +Retrieve total bytes used +------------------------- + +.. code-block:: php + + $account->getBytesUsed(); + +`Get the executable PHP script for this example `_ diff --git a/doc/_build/html/_sources/services/object-store/cdn.txt b/doc/_build/html/_sources/services/object-store/cdn.txt new file mode 100644 index 000000000..eb29bb27f --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/cdn.txt @@ -0,0 +1,130 @@ +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 */ + } + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +CDN-disable a container +----------------------- + +.. code-block:: php + + $container->disableCdn(); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/object-store/containers.txt b/doc/_build/html/_sources/services/object-store/containers.txt new file mode 100644 index 000000000..a2f0485e8 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/containers.txt @@ -0,0 +1,247 @@ +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 + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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}'); + +`Get the executable PHP script for this example `_ + + +Retrieve a container's name +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $name = $container->name; + + +Retrieve a container's object count +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $count = $container->getObjectCount(); + +`Get the executable PHP script for this example `_ + + +Retrieve a container's total bytes used +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $bytes = $container->getBytesUsed(); + +`Get the executable PHP script for this example `_ + + +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``. + +`Get the executable PHP script for this example `_ + + +Deleting all objects inside a container +--------------------------------------- + +.. code-block:: php + + $container->deleteAllObjects(); + +`Get the executable PHP script for this example `_ + + +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' + )); + +`Get the executable PHP script for this example `_ + + +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(); + +Get the executable PHP scripts for this example: + +* `Set bytes quota `_ +* `Set count quota `_ + + +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/_build/html/_sources/services/object-store/index.txt b/doc/_build/html/_sources/services/object-store/index.txt new file mode 100644 index 000000000..fcdc5aff2 --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/index.txt @@ -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/_build/html/_sources/services/object-store/migrating-containers.txt b/doc/_build/html/_sources/services/object-store/migrating-containers.txt new file mode 100644 index 000000000..22adb839b --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/migrating-containers.txt @@ -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/_build/html/_sources/services/object-store/objects.txt b/doc/_build/html/_sources/services/object-store/objects.txt new file mode 100644 index 000000000..7d9b2120e --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/objects.txt @@ -0,0 +1,449 @@ +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``. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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 +`_. + +`Get the executable PHP script for this example `_ + + +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 the executable PHP script for this example `_ + + +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 $name string */ + $name = $object->getName(); + + +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 the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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); + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +Delete object +------------- + +.. code-block:: php + + $object->delete(); + +`Get the executable PHP script for this example `_ + + +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); + +`Get the executable PHP script for this example `_ diff --git a/doc/_build/html/_sources/services/object-store/rs-only.txt b/doc/_build/html/_sources/services/object-store/rs-only.txt new file mode 100644 index 000000000..fab4e423f --- /dev/null +++ b/doc/_build/html/_sources/services/object-store/rs-only.txt @@ -0,0 +1,3 @@ +.. note:: + + This feature is only available to Rackspace users. diff --git a/doc/_build/html/_sources/services/orchestration/README.md.txt b/doc/_build/html/_sources/services/orchestration/README.md.txt new file mode 100644 index 000000000..1a983d187 --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/README.md.txt @@ -0,0 +1,98 @@ +Orchestration +============= + +**Orchestration** is a service that can be used to create and manage +cloud resources. Examples of such resources are databases, load +balancers, servers and software installed on them. + +Concepts +-------- + +To use the Orchestration service effectively, you should understand +several key concepts: + +- **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. + +Getting started +--------------- + +1. Instantiate an OpenStack or Rackspace client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the Orchestration service, you must first instantiate a +``OpenStack`` or ``Rackspace`` client object. + +- If you are working with an OpenStack cloud, instantiate an + ``OpenCloud\OpenStack`` client as follows: + + .. code:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + +- If you are working with the Rackspace cloud, instantiate a + ``OpenCloud\Rackspace`` client as follows: + + .. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +2. Obtain an Orchestration service object from the client. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All Orchestration operations are done via an *orchestration service +object*. To instantiate this object, call the ``orchestrationService`` +method on the ``$client`` object as shown in the following example: + +.. code:: php + + $region = ''; + $orchestrationService = $client->orchestrationService(null, $region); + +Any stacks and resources created with this ``$orchestrationService`` +instance will be stored in the cloud region specified by ``$region``. + +3. Create a stack from a template. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + $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 `__ ] + +Next steps +---------- + +Once you have created a stack, there is more you can do with it. See +`complete user guide for orchestration `__. diff --git a/doc/_build/html/_sources/services/orchestration/USERGUIDE.md.txt b/doc/_build/html/_sources/services/orchestration/USERGUIDE.md.txt new file mode 100644 index 000000000..98bd51db7 --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/USERGUIDE.md.txt @@ -0,0 +1,672 @@ +Complete User Guide for the Orchestration Service +================================================= + +Orchestration is a service that you can use to create and manage cloud +resources such as databases, load balancers, and servers, and the +software installed on servers. + +Table of Contents +----------------- + +- `Concepts <#concepts>`__ +- `Prerequisites <#prerequisites>`__ +- `Client <#client>`__ +- `Orchestration service <#orchestration-service>`__ +- `Templates <#templates>`__ +- `Validate template <#validate-template>`__ + + - `Validate a template from a + file <#validate-a-template-from-a-file>`__ + - `Validate Template from URL <#validate-template-from-url>`__ + +- `Stacks <#stacks>`__ +- `Preview stack <#preview-stack>`__ + + - `Preview a stack from a template + file <#preview-a-stack-from-a-template-file>`__ + - `Preview a stack from a template + URL <#preview-a-stack-from-a-template-url>`__ + +- `Create stack <#create-stack>`__ + + - `Create a stack from a template + file <#create-a-stack-from-a-template-file>`__ + - `Create a stack from a template + URL <#create-a-stack-from-a-template-url>`__ + +- `List stacks <#list-stacks>`__ +- `Get stack <#get-stack>`__ +- `Get stack template <#get-stack-template>`__ +- `Update stack <#update-stack>`__ + + - `Update a stack from a template + file <#update-a-stack-from-a-template-file>`__ + - `Update Stack from Template + URL <#update-stack-from-template-url>`__ + +- `Delete stack <#delete-stack>`__ +- `Abandon Stack <#abandon-stack>`__ +- `Adopt stack <#adopt-stack>`__ +- `Stack resources <#stack-resources>`__ +- `List stack resources <#list-stack-resources>`__ +- `Get stack resource <#get-stack-resource>`__ +- `Get stack resource metadata <#get-stack-resource-metadata>`__ +- `Stack resource events <#stack-resource-events>`__ +- `List stack events <#list-stack-events>`__ +- `List stack resource events <#list-stack-resource-events>`__ +- `Get stack resource event <#get-stack-resource-event>`__ +- `Resource types <#resource-types>`__ +- `List resource types <#list-resource-types>`__ +- `Get resource type <#get-resource-type>`__ +- `Get resource type template <#get-resource-type-template>`__ +- `Build info <#build-info>`__ +- `Get build info <#get-build-info>`__ + +Concepts +-------- + +To use the Orchestration service effectively, you should understand the +following key concepts: + +- **Template**: A JSON or YAML document that describes how a set of + resources should be assembled to produce a working deployment. 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. + +- **Resource**: Some component of your architecture (a cloud server, a + group of scaled cloud servers, a load balancer, some configuration + management system, and so on) that is defined in a template. + +- **Stack**: A running instance of a template. When a stack is created, + the resources specified in the template are created. + +Prerequisites +------------- + +Client +~~~~~~ + +To use the Orchestration service, you must first instantiate a +``OpenStack`` or ``Rackspace`` client object. + +- If you are working with an OpenStack cloud, instantiate an + ``OpenCloud\OpenStack`` client as follows: + + .. code:: php + + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + +- If you are working with the Rackspace cloud, instantiate a + ``OpenCloud\Rackspace`` client as follows: + + .. code:: php + + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + +Orchestration service +~~~~~~~~~~~~~~~~~~~~~ + +All Orchestration operations are done via an *orchestration service +object*. To instantiate this object, call the ``orchestrationService`` +method on the ``$client`` object. This method takes two arguments: + ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+--------------------------+ +| Position | Description | Data type | Required? | Default value | Example value | ++============+=============================================================+=============+=============+====================================================+==========================+ +| 1 | Name of the service, as it appears in the service catalog | String | No | ``null``; automatically determined when possible | ``cloudOrchestration`` | ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+--------------------------+ +| 2 | Cloud region | String | Yes | - | ``DFW`` | ++------------+-------------------------------------------------------------+-------------+-------------+----------------------------------------------------+--------------------------+ + +.. code:: php + + $region = ''; + $orchestrationService = $client->orchestrationService(null, $region); + +Any stacks and resources created with this ``$orchestrationService`` +instance will be stored in the cloud region specified by ``$region``. + +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. + +Validate template +~~~~~~~~~~~~~~~~~ + +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:: 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:: 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 `__ +] + +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:: php + + $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)' + ) + )); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `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:: php + + $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)' + ) + )); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `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:: php + + $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 + )); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `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:: 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:: 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:: php + + $stack = $orchestrationService->getStack('simple-lamp-setup'); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `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:: php + + $stackTemplate = $stack->getTemplate(); + /** @var $stackTemplate string **/ + +[ `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:: php + + $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 + )); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `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:: php + + $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 + )); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `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:: php + + $stack->delete(); + +[ `Get the executable PHP script for this +example `__ ] + +Abandon Stack +~~~~~~~~~~~~~ + +If you want to delete a stack but preserve all its resources, you can +abandon the stack as shown in the following example: + +.. code:: php + + $abandonStackData = $stack->abandon(); + /** @var $abandonStackData string **/ + + file_put_contents(__DIR__ . '/sample_adopt_stack_data.json', $abandonStackData); + +[ `Get the executable PHP script for this +example `__ ] + +Note that 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. + +Adopt stack +~~~~~~~~~~~ + +If you have data from an abandoned stack, you can re-create the stack as +shown in the following example: + +.. code:: php + + $stack = $orchestrationService->adoptStack(array( + 'name' => 'simple-lamp-setup', + 'template' => file_get_contents(__DIR__ . '/lamp.yml'), + 'adoptStackData' => $abandonStackData, + 'timeoutMins' => 5 + )); + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ + +[ `Get the executable PHP script for this +example `__ ] + +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:: 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:: php + + $resource = $stack->getResource('load-balancer'); + /** @var $resource OpenCloud\Orchestration\Resource\Resource **/ + +[ `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:: php + + $resourceMetadata = $resource->getMetadata(); + /** @var $resourceMetadata \stdClass **/ + +[ `Get the executable PHP script for this +example `__ ] + +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:: 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:: 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:: php + + $resourceEvent = $resource->getEvent('c1342a0a-59e6-4413-9af5-07c9cae7d729'); + /** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/ + +[ `Get the executable PHP script for this +example `__ ] + +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:: 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:: php + + $resourceType = $orchestrationService->getResourceType('OS::Nova::Server'); + /** @var $resourceType OpenCloud\Orchestration\Resource\ResourceType **/ + +[ `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:: php + + $resourceTypeTemplate = $resourceType->getTemplate(); + /** @var $resourceTypeTemplate string **/ + +[ `Get the executable PHP script for this +example `__ ] + +Build info +---------- + +Get build info +~~~~~~~~~~~~~~ + +You can retrieve information about the current Orchestration service +build as shown in the following example: + +.. code:: php + + $buildInfo = $orchestrationService->getBuildInfo(); + /** @var $resourceType OpenCloud\Orchestration\Resource\BuildInfo **/ + +[ `Get the executable PHP script for this +example `__ ] diff --git a/doc/_build/html/_sources/services/orchestration/build-info.txt b/doc/_build/html/_sources/services/orchestration/build-info.txt new file mode 100644 index 000000000..b4016bab2 --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/build-info.txt @@ -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/_build/html/_sources/services/orchestration/events.txt b/doc/_build/html/_sources/services/orchestration/events.txt new file mode 100644 index 000000000..bceec0f5a --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/events.txt @@ -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/_build/html/_sources/services/orchestration/index.txt b/doc/_build/html/_sources/services/orchestration/index.txt new file mode 100644 index 000000000..bae5ec6aa --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/index.txt @@ -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/_build/html/_sources/services/orchestration/resource-types.txt b/doc/_build/html/_sources/services/orchestration/resource-types.txt new file mode 100644 index 000000000..caa58b013 --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/resource-types.txt @@ -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/_build/html/_sources/services/orchestration/resources.txt b/doc/_build/html/_sources/services/orchestration/resources.txt new file mode 100644 index 000000000..b04115122 --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/resources.txt @@ -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/_build/html/_sources/services/orchestration/stacks.txt b/doc/_build/html/_sources/services/orchestration/stacks.txt new file mode 100644 index 000000000..29b6c4f7f --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/stacks.txt @@ -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/_build/html/_sources/services/orchestration/templates.txt b/doc/_build/html/_sources/services/orchestration/templates.txt new file mode 100644 index 000000000..24bc896bc --- /dev/null +++ b/doc/_build/html/_sources/services/orchestration/templates.txt @@ -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/_build/html/_sources/services/queues/Claim.md.txt b/doc/_build/html/_sources/services/queues/Claim.md.txt new file mode 100644 index 000000000..42161536d --- /dev/null +++ b/doc/_build/html/_sources/services/queues/Claim.md.txt @@ -0,0 +1,164 @@ +1. Introduction +--------------- + +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. + +2. Setup +-------- + +A Claim is initialized on its parent object, a Queue: + +.. code:: php + + // To initialize an empty object: + $claim = $queue->getClaim(); + + // or retrieve a specific claim: + $claim = $queue->getClaim('51db7067821e727dc24df754'); + +3. Claim messages +----------------- + +3.1 Description +~~~~~~~~~~~~~~~ + +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. + +3.2 Attributes +~~~~~~~~~~~~~~ + +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. + +3.3 Code +~~~~~~~~ + +.. code:: php + + use OpenCloud\Common\Constants\Datetime; + + $queue->claimMessages(array( + 'limit' => 15, + 'grace' => 5 * Datetime::MINUTE, + 'ttl' => 5 * Datetime::MINUTE + )); + +4. Query claim +-------------- + +4.1 Description +~~~~~~~~~~~~~~~ + +This operation queries the specified claim for the specified queue. +Claims with malformed IDs or claims that are not found by ID are +ignored. + +4.2 Attributes +~~~~~~~~~~~~~~ + +Claim ID. + +4.3 Code +~~~~~~~~ + +.. code:: php + + $claim = $queue->getClaim('51db7067821e727dc24df754'); + +5. Update claim +--------------- + +5.1 Description +~~~~~~~~~~~~~~~ + +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. + +5.2 Attributes +~~~~~~~~~~~~~~ + +See section 4.2. + +5.3 Code +~~~~~~~~ + +.. code:: php + + use OpenCloud\Common\Constants\Datetime; + + $claim->update(array( + 'ttl' => 10 * Datetime::MINUTE + )); + +6. Release claim +---------------- + +6.1 Description +~~~~~~~~~~~~~~~ + +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. + +6.2 Attributes +~~~~~~~~~~~~~~ + +See section 4.2. + +6.3 Code +~~~~~~~~ + +.. code:: php + + $message->delete(); + diff --git a/doc/_build/html/_sources/services/queues/Message.md.txt b/doc/_build/html/_sources/services/queues/Message.md.txt new file mode 100644 index 000000000..ca67e22bb --- /dev/null +++ b/doc/_build/html/_sources/services/queues/Message.md.txt @@ -0,0 +1,257 @@ +1. Introduction +--------------- + +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. + +2. Setup +-------- + +A message is initialized from its parent object, a Queue: + +.. code:: php + + // Setup an empty object + $message = $queue->getMessage(); + + // or retrieve an existing one + $message = $queue->getMessage(''); + +3. Post message +--------------- + +3.1 Description +~~~~~~~~~~~~~~~ + +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. + +3.2 Parameters +~~~~~~~~~~~~~~ + +How you pass through the array structure depends on whether you are +executing multiple (3.3.2) or single (3.3.3) 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. + +3.3 Code samples +~~~~~~~~~~~~~~~~ + +3.3.1 Posting a single message +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + use OpenCloud\Common\Constants\Datetime; + + $queue->createMessage(array( + 'body' => (object) array( + 'event' => 'BackupStarted', + 'deadline' => '26.12.2013 + ), + 'ttl' => 2 * Datetime::DAY + )); + +3.3.2 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:: 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); + +4. Get messages +--------------- + +4.1 Description +~~~~~~~~~~~~~~~ + +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. + +4.2 Parameters +~~~~~~~~~~~~~~ + +A hash of 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. | ++--------------------+---------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +4.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $messages = $queue->listMessages(array( + 'marker' => '51db6f78c508f17ddc924357', + 'limit' => 20, + 'echo' => true + )); + + while ($message = $messages->next()) { + echo $message->getId() . PHP_EOL; + } + +5. Get a set of messages by ID +------------------------------ + +5.1 Description +~~~~~~~~~~~~~~~ + +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. + +5.2 Parameters +~~~~~~~~~~~~~~ + +A hash of options. + +\|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\|​String\|Specifies +the claim ID with which the message is associated. Optional.\| +\|----\|-----\|----\|-----------\| + +5.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $ids = array('51db6f78c508f17ddc924357', 'f5b8c8a7c62b0150b68a50d6'); + + $messages = $queue->listMessages(array('ids' => $ids)); + + while ($message = $messages->next()) { + echo $message->getId() . PHP_EOL; + } + +6. Delete a set of messages by ID +--------------------------------- + +6.1 Description +~~~~~~~~~~~~~~~ + +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. + +6.2 Parameters +~~~~~~~~~~~~~~ + +An array of IDs. + +6.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $ids = array('51db6f78c508f17ddc924357', 'f5b8c8a7c62b0150b68a50d6'); + + $response = $queue->deleteMessages($ids); + +7. Get a specific message +------------------------- + +7.1 Description +~~~~~~~~~~~~~~~ + +This operation gets the specified message from the specified queue. + +7.2 Parameters +~~~~~~~~~~~~~~ + +Message ID. + +7.3 Object properties +~~~~~~~~~~~~~~~~~~~~~ + +``href`` is an opaque relative URI that the client can use to uniquely +identify a message resource and interact with it. + +``ttl`` is the TTL that was set on the message when it was posted. The +message expires after (ttl - age) seconds. + +``age`` is the number of seconds relative to the server's clock. + +``body`` is the arbitrary document that was submitted with the original +request to post the message. + +7.4 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $message = $queue->getMessage('51db6f78c508f17ddc924357'); + +8. Delete message +----------------- + +8.1 Description +~~~~~~~~~~~~~~~ + +This operation immediately deletes the specified message. + +8.2 Parameters +~~~~~~~~~~~~~~ + +None. + +8.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $message->delete(); + diff --git a/doc/_build/html/_sources/services/queues/Queue.md.txt b/doc/_build/html/_sources/services/queues/Queue.md.txt new file mode 100644 index 000000000..1fe9f7036 --- /dev/null +++ b/doc/_build/html/_sources/services/queues/Queue.md.txt @@ -0,0 +1,197 @@ +1. Introduction +--------------- + +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. + +2. Setup +-------- + +.. code:: php + + $service = $client->queuesService('cloudQueues', 'ORD'); + +3. Client IDs +------------- + +With most of Marconi's operation, 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:: php + + $service->setClientId(); + + echo $service->getClientId(); + +If you call ``setClientId`` without any parameters, a UUID is +automatically generated for you. + +4. List queues +-------------- + +4.1 Description +~~~~~~~~~~~~~~~ + +This operation lists queues for the project. The queues are sorted +alphabetically by name. + +4.2 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.\| +\|----\|-----\|----\|-----------\| + +4.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $queues = $service->listQueues(); + + while ($queue = $queues->next()) { + echo $queue->getName() . PHP_EOL; + } + +5. Create queue +--------------- + +5.1 Description +~~~~~~~~~~~~~~~ + +This operation creates a new queue. + +5.2 Parameters +~~~~~~~~~~~~~~ + +A string representation of the name for your new Queue. The name must +not exceed 64 bytes in length, and it is limited to US-ASCII letters, +digits, underscores, and hyphens. + +5.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $queue = $service->createQueue('new_queue'); + +6. Retrieve queue +----------------- + +6.1 Description +~~~~~~~~~~~~~~~ + +Returns a ``Queue`` object for use. + +6.2 Parameters +~~~~~~~~~~~~~~ + +Queue name. + +6.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $queue = $service->getQueue('new_queue'); + +7. Check queue existence +------------------------ + +7.1 Description +~~~~~~~~~~~~~~~ + +This operation verifies whether the specified queue exists by returning +``TRUE`` or ``FALSE``. + +7.2 Parameters +~~~~~~~~~~~~~~ + +7.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + if ($service->hasQueue('new_queue')) { + // do something + } + +8. Update queue metadata (permanently to the API) +------------------------------------------------- + +4.1 Description +~~~~~~~~~~~~~~~ + +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. + +4.2 Parameters +~~~~~~~~~~~~~~ + +Hash of key pairs. + +4.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $queue->saveMetadata(array( + 'foo' => 'bar' + )); + +9. Retrieve the queue metadata (fresh from the API) +--------------------------------------------------- + +4.1 Description +~~~~~~~~~~~~~~~ + +This operation returns metadata, such as message TTL, for the queue. + +4.2 Parameters +~~~~~~~~~~~~~~ + +None. + +4.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $metadata = $queue->retrieveMetadata(); + + print_r($metadata->toArray()); + +10. Get queue stats +------------------- + +4.1 Description +~~~~~~~~~~~~~~~ + +This operation returns queue statistics, including how many messages are +in the queue, categorized by status. + +4.2 Parameters +~~~~~~~~~~~~~~ + +None. + +4.3 Code sample +~~~~~~~~~~~~~~~ + +.. code:: php + + $queue->getStats(); + diff --git a/doc/_build/html/_sources/services/queues/claims.txt b/doc/_build/html/_sources/services/queues/claims.txt new file mode 100644 index 000000000..1111cb9eb --- /dev/null +++ b/doc/_build/html/_sources/services/queues/claims.txt @@ -0,0 +1,121 @@ +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 + )); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/queues/index.txt b/doc/_build/html/_sources/services/queues/index.txt new file mode 100644 index 000000000..4175df760 --- /dev/null +++ b/doc/_build/html/_sources/services/queues/index.txt @@ -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/_build/html/_sources/services/queues/messages.txt b/doc/_build/html/_sources/services/queues/messages.txt new file mode 100644 index 000000000..3a5dee89d --- /dev/null +++ b/doc/_build/html/_sources/services/queues/messages.txt @@ -0,0 +1,203 @@ +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 + )); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/services/queues/queues.txt b/doc/_build/html/_sources/services/queues/queues.txt new file mode 100644 index 000000000..f324e3f3b --- /dev/null +++ b/doc/_build/html/_sources/services/queues/queues.txt @@ -0,0 +1,135 @@ +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'); + +`Get the executable PHP script for this example `_ + + +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(); + +Delete queue +------------ + +.. code-block:: php + + $queue->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/_build/html/_sources/services/volume/index.txt b/doc/_build/html/_sources/services/volume/index.txt new file mode 100644 index 000000000..bee589086 --- /dev/null +++ b/doc/_build/html/_sources/services/volume/index.txt @@ -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/_build/html/_sources/services/volume/snapshots.txt b/doc/_build/html/_sources/services/volume/snapshots.txt new file mode 100644 index 000000000..555824a9d --- /dev/null +++ b/doc/_build/html/_sources/services/volume/snapshots.txt @@ -0,0 +1,56 @@ +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 + )); + +`Get the executable PHP script for this example `_ + + +List snapshots +-------------- + +.. code-block:: php + + $snapshots = $service->snapshotList(); + + foreach ($snapshots as $snapshot) { + /** @param $snapshot OpenCloud\Volume\Resource\Snapshot */ + } + +`Get the executable PHP script for this example `_ + + +To get details on a single snapshot +----------------------------------- + +.. code-block:: php + + $snapshot = $dallas->snapshot('{snapshotId}'); + +`Get the executable PHP script for this example `_ + + +To delete a snapshot +-------------------- + +.. code-block:: php + + $snapshot->delete(); + +`Get the executable PHP script for this example `_ diff --git a/doc/_build/html/_sources/services/volume/volume-types.txt b/doc/_build/html/_sources/services/volume/volume-types.txt new file mode 100644 index 000000000..ba3176df9 --- /dev/null +++ b/doc/_build/html/_sources/services/volume/volume-types.txt @@ -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/_build/html/_sources/services/volume/volumes.txt b/doc/_build/html/_sources/services/volume/volumes.txt new file mode 100644 index 000000000..a84ed0421 --- /dev/null +++ b/doc/_build/html/_sources/services/volume/volumes.txt @@ -0,0 +1,88 @@ +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' + )); + +`Get the executable PHP script for this example `_ + + +List volumes +------------ + +.. code-block:: php + + $volumes = $service->volumeList(); + + foreach ($volumes as $volume) { + /** @param $volumeType OpenCloud\Volume\Resource\Volume */ + } + +`Get the executable PHP script for this example `_ + + +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; + +`Get the executable PHP script for this example `_ + + +To delete a volume +------------------ + +.. code-block:: php + + $volume->delete(); + +`Get the executable PHP script for this example `_ + + +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/_build/html/_sources/url-types.txt b/doc/_build/html/_sources/url-types.txt new file mode 100644 index 000000000..26a0410bd --- /dev/null +++ b/doc/_build/html/_sources/url-types.txt @@ -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. diff --git a/doc/_build/html/_sources/using-php-5.3.txt b/doc/_build/html/_sources/using-php-5.3.txt new file mode 100644 index 000000000..8790710f2 --- /dev/null +++ b/doc/_build/html/_sources/using-php-5.3.txt @@ -0,0 +1,20 @@ +Using the SDK with PHP v5.3 +=========================== + +Since PHP 5.3 has entered EOL and no longer receives security updates, we have bumped the minimum requirement to 5.4. Using 5.3 is still possible, however, but you will need to use an older stable version of the SDK. There are two ways to do this. + +The first way is by requiring it through the command line: + +.. code-block:: bash + + composer require rackspace/php-opencloud:1.12 + +The second way is by updating your composer.json file, and specifying the appropriate version of the SDK: + +.. code-block:: json + + "require": { + "rackspace/php-opencloud": "~1.12" + } + +Note that **1.12** is the last minor release supporting PHP 5.3. Version 1.13 and above has shifted to PHP 5.4. diff --git a/doc/_build/html/_static/ajax-loader.gif b/doc/_build/html/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/doc/_build/html/_static/ajax-loader.gif differ diff --git a/doc/_build/html/_static/basic.css b/doc/_build/html/_static/basic.css new file mode 100644 index 000000000..967e36ce0 --- /dev/null +++ b/doc/_build/html/_static/basic.css @@ -0,0 +1,537 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/doc/_build/html/_static/comment-bright.png b/doc/_build/html/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/doc/_build/html/_static/comment-bright.png differ diff --git a/doc/_build/html/_static/comment-close.png b/doc/_build/html/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/doc/_build/html/_static/comment-close.png differ diff --git a/doc/_build/html/_static/comment.png b/doc/_build/html/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/doc/_build/html/_static/comment.png differ diff --git a/doc/_build/html/_static/css/badge_only.css b/doc/_build/html/_static/css/badge_only.css new file mode 100644 index 000000000..4868a0027 --- /dev/null +++ b/doc/_build/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:"\f02d"}.icon-book:before{content:"\f02d"}.fa-caret-down:before{content:"\f0d7"}.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} diff --git a/doc/_build/html/_static/css/theme.css b/doc/_build/html/_static/css/theme.css new file mode 100644 index 000000000..f595aab86 --- /dev/null +++ b/doc/_build/html/_static/css/theme.css @@ -0,0 +1,4 @@ +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:20px 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.0.3");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.0.3") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.0.3") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.pull-left.icon{margin-right:.3em}.fa.pull-right,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before,.icon-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before,.icon-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:"\f057"}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before,.icon-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before,.icon-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:"\f0a8"}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before,.icon-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-asc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-desc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-reply-all:before{content:"\f122"}.fa-mail-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before,.icon-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .icon,.nav .fa,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .icon{display:inline}.btn .fa.fa-large,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a{color:#2980b9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:60px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:60px}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27ae60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27ae60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#e74c3c !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#e67e22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980b9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:0.5em 1em 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:0.5em}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#999;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{display:block;float:left;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{display:block;float:left;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{display:block;float:left;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:0.5em 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#ccc;font-size:70%;margin-top:0.3125em;font-style:italic}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#f3f6f6;color:#cad2d3}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e74c3c}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:0.8em;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fff;color:#cad2d3;border-color:transparent}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{padding:6px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #e74c3c}.wy-control-group.wy-control-group-error textarea{border:solid 1px #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px;margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980b9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27ae60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#e74c3c !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}code,.rst-content tt{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:"Incosolata","Consolata","Monaco",monospace;color:#e74c3c;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9b59b6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:"Incosolata","Consolata","Monaco",monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:"Incosolata","Consolata","Monaco",monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#eaf2f5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#2980b9;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980b9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:absolute;top:0;left:0;width:300px;overflow:hidden;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}nav.stickynav{position:fixed;top:0}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{visibility:visible;content:"\f0c1";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt{color:#000}.rst-content tt big,.rst-content tt em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt{font-weight:bold}.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040} diff --git a/doc/_build/html/_static/default.css b/doc/_build/html/_static/default.css new file mode 100644 index 000000000..5f1399abd --- /dev/null +++ b/doc/_build/html/_static/default.css @@ -0,0 +1,256 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} \ No newline at end of file diff --git a/doc/_build/html/_static/doctools.js b/doc/_build/html/_static/doctools.js new file mode 100644 index 000000000..c5455c905 --- /dev/null +++ b/doc/_build/html/_static/doctools.js @@ -0,0 +1,238 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/doc/_build/html/_static/down-pressed.png b/doc/_build/html/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/doc/_build/html/_static/down-pressed.png differ diff --git a/doc/_build/html/_static/down.png b/doc/_build/html/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/doc/_build/html/_static/down.png differ diff --git a/doc/_build/html/_static/file.png b/doc/_build/html/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/doc/_build/html/_static/file.png differ diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.eot b/doc/_build/html/_static/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..7c79c6a6b Binary files /dev/null and b/doc/_build/html/_static/fonts/fontawesome-webfont.eot differ diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.svg b/doc/_build/html/_static/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..45fdf3383 --- /dev/null +++ b/doc/_build/html/_static/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.ttf b/doc/_build/html/_static/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..e89738de5 Binary files /dev/null and b/doc/_build/html/_static/fonts/fontawesome-webfont.ttf differ diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.woff b/doc/_build/html/_static/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..8c1748aab Binary files /dev/null and b/doc/_build/html/_static/fonts/fontawesome-webfont.woff differ diff --git a/doc/_build/html/_static/jquery.js b/doc/_build/html/_static/jquery.js new file mode 100644 index 000000000..83589daa7 --- /dev/null +++ b/doc/_build/html/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/doc/_build/html/_static/js/theme.js b/doc/_build/html/_static/js/theme.js new file mode 100644 index 000000000..60520cc3a --- /dev/null +++ b/doc/_build/html/_static/js/theme.js @@ -0,0 +1,47 @@ +$( document ).ready(function() { + // Shift nav in mobile when clicking the menu. + $(document).on('click', "[data-toggle='wy-nav-top']", function() { + $("[data-toggle='wy-nav-shift']").toggleClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + // Close menu when you click a link. + $(document).on('click', ".wy-menu-vertical .current ul li a", function() { + $("[data-toggle='wy-nav-shift']").removeClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + $(document).on('click', "[data-toggle='rst-current-version']", function() { + $("[data-toggle='rst-versions']").toggleClass("shift-up"); + }); + // Make tables responsive + $("table.docutils:not(.field-list)").wrap("
"); +}); + +window.SphinxRtdTheme = (function (jquery) { + var stickyNav = (function () { + var navBar, + win, + stickyNavCssClass = 'stickynav', + applyStickNav = function () { + if (navBar.height() <= win.height()) { + navBar.addClass(stickyNavCssClass); + } else { + navBar.removeClass(stickyNavCssClass); + } + }, + enable = function () { + applyStickNav(); + win.on('resize', applyStickNav); + }, + init = function () { + navBar = jquery('nav.wy-nav-side:first'); + win = jquery(window); + }; + jquery(init); + return { + enable : enable + }; + }()); + return { + StickyNav : stickyNav + }; +}($)); diff --git a/doc/_build/html/_static/minus.png b/doc/_build/html/_static/minus.png new file mode 100644 index 000000000..da1c5620d Binary files /dev/null and b/doc/_build/html/_static/minus.png differ diff --git a/doc/_build/html/_static/plus.png b/doc/_build/html/_static/plus.png new file mode 100644 index 000000000..b3cb37425 Binary files /dev/null and b/doc/_build/html/_static/plus.png differ diff --git a/doc/_build/html/_static/pygments.css b/doc/_build/html/_static/pygments.css new file mode 100644 index 000000000..57eadc030 --- /dev/null +++ b/doc/_build/html/_static/pygments.css @@ -0,0 +1,63 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/doc/_build/html/_static/searchtools.js b/doc/_build/html/_static/searchtools.js new file mode 100644 index 000000000..6e1f06bd1 --- /dev/null +++ b/doc/_build/html/_static/searchtools.js @@ -0,0 +1,622 @@ +/* + * searchtools.js_t + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + + +/** + * Simple result scoring code. + */ +var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + // query found in terms + term: 5 +}; + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, + dataType: "script", cache: true, + complete: function(jqxhr, textstatus) { + if (textstatus != "success") { + document.getElementById("searchindexloader").src = url; + } + }}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + var i; + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + } + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

').appendTo(this.out); + this.output = $('
'); + } + // Prettify the comment rating. + comment.pretty_rating = comment.rating + ' point' + + (comment.rating == 1 ? '' : 's'); + // Make a class (for displaying not yet moderated comments differently) + comment.css_class = comment.displayed ? '' : ' moderate'; + // Create a div for this comment. + var context = $.extend({}, opts, comment); + var div = $(renderTemplate(commentTemplate, context)); + + // If the user has voted on this comment, highlight the correct arrow. + if (comment.vote) { + var direction = (comment.vote == 1) ? 'u' : 'd'; + div.find('#' + direction + 'v' + comment.id).hide(); + div.find('#' + direction + 'u' + comment.id).show(); + } + + if (opts.moderator || comment.text != '[deleted]') { + div.find('a.reply').show(); + if (comment.proposal_diff) + div.find('#sp' + comment.id).show(); + if (opts.moderator && !comment.displayed) + div.find('#cm' + comment.id).show(); + if (opts.moderator || (opts.username == comment.username)) + div.find('#dc' + comment.id).show(); + } + return div; + } + + /** + * A simple template renderer. Placeholders such as <%id%> are replaced + * by context['id'] with items being escaped. Placeholders such as <#id#> + * are not escaped. + */ + function renderTemplate(template, context) { + var esc = $(document.createElement('div')); + + function handle(ph, escape) { + var cur = context; + $.each(ph.split('.'), function() { + cur = cur[this]; + }); + return escape ? esc.text(cur || "").html() : cur; + } + + return template.replace(/<([%#])([\w\.]*)\1>/g, function() { + return handle(arguments[2], arguments[1] == '%' ? true : false); + }); + } + + /** Flash an error message briefly. */ + function showError(message) { + $(document.createElement('div')).attr({'class': 'popup-error'}) + .append($(document.createElement('div')) + .attr({'class': 'error-message'}).text(message)) + .appendTo('body') + .fadeIn("slow") + .delay(2000) + .fadeOut("slow"); + } + + /** Add a link the user uses to open the comments popup. */ + $.fn.comment = function() { + return this.each(function() { + var id = $(this).attr('id').substring(1); + var count = COMMENT_METADATA[id]; + var title = count + ' comment' + (count == 1 ? '' : 's'); + var image = count > 0 ? opts.commentBrightImage : opts.commentImage; + var addcls = count == 0 ? ' nocomment' : ''; + $(this) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-open' + addcls, + id: 'ao' + id + }) + .append($(document.createElement('img')).attr({ + src: image, + alt: 'comment', + title: title + })) + .click(function(event) { + event.preventDefault(); + show($(this).attr('id').substring(2)); + }) + ) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-close hidden', + id: 'ah' + id + }) + .append($(document.createElement('img')).attr({ + src: opts.closeCommentImage, + alt: 'close', + title: 'close' + })) + .click(function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }) + ); + }); + }; + + var opts = { + processVoteURL: '/_process_vote', + addCommentURL: '/_add_comment', + getCommentsURL: '/_get_comments', + acceptCommentURL: '/_accept_comment', + deleteCommentURL: '/_delete_comment', + commentImage: '/static/_static/comment.png', + closeCommentImage: '/static/_static/comment-close.png', + loadingImage: '/static/_static/ajax-loader.gif', + commentBrightImage: '/static/_static/comment-bright.png', + upArrow: '/static/_static/up.png', + downArrow: '/static/_static/down.png', + upArrowPressed: '/static/_static/up-pressed.png', + downArrowPressed: '/static/_static/down-pressed.png', + voting: false, + moderator: false + }; + + if (typeof COMMENT_OPTIONS != "undefined") { + opts = jQuery.extend(opts, COMMENT_OPTIONS); + } + + var popupTemplate = '\ +
\ +

\ + Sort by:\ + best rated\ + newest\ + oldest\ +

\ +
Comments
\ +
\ + loading comments...
\ +
    \ +
    \ +

    Add a comment\ + (markup):

    \ +
    \ + reStructured text markup: *emph*, **strong**, \ + ``code``, \ + code blocks: :: and an indented block after blank line
    \ +
    \ + \ +

    \ + \ + Propose a change ▹\ + \ + \ + Propose a change ▿\ + \ +

    \ + \ + \ + \ + \ + \ +
    \ +
    '; + + var commentTemplate = '\ +
    \ +
    \ +
    \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +
    \ +

    \ + <%username%>\ + <%pretty_rating%>\ + <%time.delta%>\ +

    \ +
    <#text#>
    \ +

    \ + \ + reply ▿\ + proposal ▹\ + proposal ▿\ + \ + \ +

    \ +
    \
    +<#proposal_diff#>\
    +        
    \ +
      \ +
      \ +
      \ +
      \ + '; + + var replyTemplate = '\ +
    • \ +
      \ +
      \ + \ + \ + \ + \ + \ + \ +
      \ +
    • '; + + $(document).ready(function() { + init(); + }); +})(jQuery); + +$(document).ready(function() { + // add comment anchors for all paragraphs that are commentable + $('.sphinx-has-comment').comment(); + + // highlight search words in search results + $("div.context").each(function() { + var params = $.getQueryParameters(); + var terms = (params.q) ? params.q[0].split(/\s+/) : []; + var result = $(this); + $.each(terms, function() { + result.highlightText(this.toLowerCase(), 'highlighted'); + }); + }); + + // directly open comment window if requested + var anchor = document.location.hash; + if (anchor.substring(0, 9) == '#comment-') { + $('#ao' + anchor.substring(9)).click(); + document.location.hash = '#s' + anchor.substring(9); + } +}); diff --git a/doc/_build/html/auth.html b/doc/_build/html/auth.html new file mode 100644 index 000000000..41fec27c3 --- /dev/null +++ b/doc/_build/html/auth.html @@ -0,0 +1,334 @@ + + + + + + + + + + Authentication — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Authentication

      +

      The client does not automatically authenticate against the API when it is +instantiated - it waits for an API call. When this happens, it checks +whether the current “token” has expired, and (re-)authenticates if +necessary.

      +

      You can force authentication, by calling:

      +
      $client->authenticate();
      +
      +
      +

      If the credentials are incorrect, a 401 error will be returned. If +credentials are correct, a 200 status is returned with your Service +Catalog.

      +
      +

      Service Catalog

      +

      The Service Catalog is returned on successful authentication, and is +composed of all the different API services available to the current +tenant. All of this functionality is encapsulated in the Catalog +object, which allows you greater control and interactivity.

      +
      /** @var OpenCloud\Common\Service\Catalog */
      +$catalog = $client->getCatalog();
      +
      +// Return a list of OpenCloud\Common\Service\CatalogItem objects
      +foreach ($catalog->getItems() as $catalogItem) {
      +
      +    $name = $catalogItem->getName();
      +    $type = $catalogItem->getType();
      +
      +    if ($name == 'cloudServersOpenStack' && $type == 'compute') {
      +        break;
      +    }
      +
      +    // Array of OpenCloud\Common\Service\Endpoint objects
      +    $endpoints = $catalogItem->getEndpoints();
      +    foreach ($endpoints as $endpoint) {
      +        if ($endpoint->getRegion() == 'DFW') {
      +            echo $endpoint->getPublicUrl();
      +        }
      +    }
      +}
      +
      +
      +

      As you can see, you have access to each Service’s name, type and list of +endpoints. Each endpoint provides access to the specific region, along +with its public and private endpoint URLs.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/caching-creds.html b/doc/_build/html/caching-creds.html new file mode 100644 index 000000000..20807585c --- /dev/null +++ b/doc/_build/html/caching-creds.html @@ -0,0 +1,330 @@ + + + + + + + + + + Caching credentials — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/customizing-clients.html b/doc/_build/html/customizing-clients.html new file mode 100644 index 000000000..23fd45fe9 --- /dev/null +++ b/doc/_build/html/customizing-clients.html @@ -0,0 +1,398 @@ + + + + + + + + + + Customizing Clients — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Customizing Clients

      +
      +

      Logger injection

      +

      As the Rackspace client extends the OpenStack client, they both support +passing $options as an array via the constructor’s third parameter. The +options are passed as a config to the Guzzle client, but also allow to inject +your own logger.

      +

      Your logger should implement the Psr\Log\LoggerInterface as defined in +PSR-3. +One example of a compatible logger is Monolog. +When the client does create a service, it will inject the logger if one is +available.

      +

      To inject a LoggerInterface compatible logger into a new client:

      +
      use Monolog\Logger;
      +use OpenCloud\OpenStack;
      +
      +// create a log channel
      +$logger = new Logger('name');
      +
      +$client = new OpenStack('http://identity.my-openstack.com/v2.0', array(
      +  'username' => 'foo',
      +  'password' => 'bar'
      +), array(
      +  'logger' => $logger,
      +));
      +
      +
      +
      +
      +

      Authentication

      +

      The client does not automatically authenticate against the API when it is +instantiated - it waits for an API call. When this happens, it checks +whether the current “token” has expired, and (re-)authenticates if +necessary.

      +

      You can force authentication, by calling:

      +
      $client->authenticate();
      +
      +
      +

      If the credentials are incorrect, a 401 error will be returned. If +credentials are correct, a 200 status is returned with your Service +Catalog.

      +
      +
      +

      Service Catalog

      +

      The Service Catalog is returned on successful authentication, and is +composed of all the different API services available to the current +tenant. All of this functionality is encapsulated in the Catalog +object, which allows you greater control and interactivity.

      +
      /** @var OpenCloud\Common\Service\Catalog */
      +$catalog = $client->getCatalog();
      +
      +// Return a list of OpenCloud\Common\Service\CatalogItem objects
      +foreach ($catalog->getItems() as $catalogItem) {
      +
      +    $name = $catalogItem->getName();
      +    $type = $catalogItem->getType();
      +
      +    if ($name == 'cloudServersOpenStack' && $type == 'compute') {
      +        break;
      +    }
      +
      +    // Array of OpenCloud\Common\Service\Endpoint objects
      +    $endpoints = $catalogItem->getEndpoints();
      +    foreach ($endpoints as $endpoint) {
      +        if ($endpoint->getRegion() == 'DFW') {
      +            echo $endpoint->getPublicUrl();
      +        }
      +    }
      +}
      +
      +
      +

      As you can see, you have access to each Service’s name, type and list of +endpoints. Each endpoint provides access to the specific region, along +with its public and private endpoint URLs.

      +
      +
      +

      Default HTTP headers

      +

      To set default HTTP headers:

      +
      $client->setDefaultOption('headers/X-Custom-Header', 'FooBar');
      +
      +
      +
      +
      +

      User agents

      +

      php-opencloud will send a default User-Agent header for every HTTP +request, unless a custom value is provided by the end-user. The default +header will be in this format:

      +
      +
      User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz
      +

      where xxx is the current version of the SDK, yyy is the current +version of cURL, and zzz is the current PHP version. To override +this default, you must run:

      +
      $client->setUserAgent('MyCustomUserAgent');
      +
      +
      +

      which will result in:

      +
      +
      User-Agent: MyCustomUserAgent
      +

      If you want to set a prefix for the user agent, but retain the default +User-Agent as a suffix, you must run:

      +
      $client->setUserAgent('MyPrefix', true);
      +
      +
      +

      which will result in:

      +
      +
      User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz
      +

      where $client is an instance of OpenCloud\OpenStack or +OpenCloud\Rackspace.

      +
      +
      +

      Other functionality

      +

      For a full list of functionality provided by Guzzle, please consult the +official documentation.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/debugging.html b/doc/_build/html/debugging.html new file mode 100644 index 000000000..1024ec86a --- /dev/null +++ b/doc/_build/html/debugging.html @@ -0,0 +1,375 @@ + + + + + + + + + + Debugging — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

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

      +
      // 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

      +
      composer require guzzle/guzzle
      +
      +
      +
      +
      +

      Add to your client

      +
      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.

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/genindex.html b/doc/_build/html/genindex.html new file mode 100644 index 000000000..af30558df --- /dev/null +++ b/doc/_build/html/genindex.html @@ -0,0 +1,615 @@ + + + + + + + + + + + Index — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      +
        +
      • Docs »
      • + +
      • +
      • + +
      • +
      +
      +
      +
      + + +

      Index

      + +
      + A + | C + | D + | E + | F + | G + | I + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + +
      +

      A

      +
      + + +
      + +
      account +
      + + +
      addNodes() (global function) +
      + + +
      agent +
      + +
      + +
      agent token +
      + + +
      alarm +
      + +
      + +

      C

      + + + +
      + +
      cdn +
      + + +
      check +
      + + +
      claim +
      + +
      + +
      cloneDomain() (global function) +
      + + +
      configuration group +
      + + +
      container +
      + +
      + +

      D

      + + + +
      + +
      database +
      + +
      + +
      datastore +
      + +
      + +

      E

      + + +
      + +
      entity +
      + +
      + +

      F

      + + +
      + +
      flavor, [1] +
      + +
      + +

      G

      + + + +
      + +
      group +
      + +
      + +
      group configuration +
      + +
      + +

      I

      + + + +
      + +
      image +
      + +
      + +
      instance +
      + +
      + +

      L

      + + +
      + +
      launch configuration +
      + +
      + +

      M

      + + + +
      + +
      message +
      + + +
      metadata +
      + +
      + +
      monitoring zone +
      + +
      + +

      N

      + + + +
      + +
      network +
      + + +
      notification +
      + +
      + +
      notification plan +
      + +
      + +

      O

      + + +
      + +
      object +
      + +
      + +

      P

      + + + +
      + +
      policy +
      + +
      + +
      port +
      + +
      + +

      Q

      + + +
      + +
      queue +
      + +
      + +

      R

      + + +
      + +
      resource +
      + +
      + +

      S

      + + + +
      + +
      security group +
      + + +
      security group rule +
      + + +
      server +
      + +
      + +
      snapshot +
      + + +
      stack +
      + + +
      subnet +
      + +
      + +

      T

      + + + +
      + +
      template +
      + + +
      tenant +
      + +
      + +
      token +
      + +
      + +

      U

      + + +
      + +
      user, [1] +
      + +
      + +

      V

      + + + +
      + +
      volume, [1] +
      + +
      + +
      volume type +
      + +
      + +

      W

      + + +
      + +
      webhook +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/getting-started-with-openstack.html b/doc/_build/html/getting-started-with-openstack.html new file mode 100644 index 000000000..f1d051180 --- /dev/null +++ b/doc/_build/html/getting-started-with-openstack.html @@ -0,0 +1,469 @@ + + + + + + + + + + Getting Started with OpenStack — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Getting Started with OpenStack

      +
      +

      Installing the SDK

      +

      You must install through Composer, because this library has a few +dependencies:

      +
      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):

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

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

      +
      $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. +
      3. Copy and run this code:
      4. +
      +
      $client->authenticate();
      +print_r($client->getCatalog()->getItems());
      +
      +
      +
        +
      1. 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.
      2. +
      +

      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:

      +
      $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:

      +
      $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:

      +
      $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:

      +
      $twoGbFlavor = $compute->flavor('4');
      +
      +
      +
      +
      +

      5. Thunderbirds are go!

      +

      Okay, you’re ready to spin up a server:

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

      +
      nova list
      +
      +
      +

      You can also execute a polling function immediately after the create +method that checks the build process:

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

      +
      $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:

      +
      $server = $compute->server('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx');
      +
      +
      +

      allowing you to update its properties:

      +
      $server->update(array(
      +   'name' => 'New server name'
      +));
      +
      +
      +

      or delete it entirely:

      +
      $server->delete();
      +
      +
      +
      +
      +

      Next steps

      +

      Read our docs for the Compute v2 service.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/getting-started-with-rackspace.html b/doc/_build/html/getting-started-with-rackspace.html new file mode 100644 index 000000000..9a5609fca --- /dev/null +++ b/doc/_build/html/getting-started-with-rackspace.html @@ -0,0 +1,435 @@ + + + + + + + + + + Getting Started with Rackspace — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Getting Started with Rackspace

      +
      +

      Installing the SDK

      +

      You must install through Composer, because this library has a few +dependencies:

      +
      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):

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

      +
      <?php
      +
      +require 'vendor/autoload.php';
      +
      +use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +    'username' => '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:

      +
      $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:

      +
      $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:

      +
      $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:

      +
      $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:

      +
      $twoGbFlavor = $compute->flavor('4');
      +
      +
      +
      +
      +

      5. Thunderbirds are go!

      +

      Okay, you’re ready to spin up a server:

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

      +
      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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/http-clients.html b/doc/_build/html/http-clients.html new file mode 100644 index 000000000..6c9e22c14 --- /dev/null +++ b/doc/_build/html/http-clients.html @@ -0,0 +1,332 @@ + + + + + + + + + + HTTP Clients — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      HTTP Clients

      +
      +

      Default HTTP headers

      +

      To set default HTTP headers:

      +
      $client->setDefaultOption('headers/X-Custom-Header', 'FooBar');
      +
      +
      +
      +
      +

      User agents

      +

      php-opencloud will send a default User-Agent header for every HTTP +request, unless a custom value is provided by the end-user. The default +header will be in this format:

      +
      +
      User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz
      +

      where xxx is the current version of the SDK, yyy is the current +version of cURL, and zzz is the current PHP version. To override +this default, you must run:

      +
      $client->setUserAgent('MyCustomUserAgent');
      +
      +
      +

      which will result in:

      +
      +
      User-Agent: MyCustomUserAgent
      +

      If you want to set a prefix for the user agent, but retain the default +User-Agent as a suffix, you must run:

      +
      $client->setUserAgent('MyPrefix', true);
      +
      +
      +

      which will result in:

      +
      +
      User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz
      +

      where $client is an instance of OpenCloud\OpenStack or +OpenCloud\Rackspace.

      +
      +
      +

      Other functionality

      +

      For a full list of functionality provided by Guzzle, please consult the +official documentation.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/index.html b/doc/_build/html/index.html new file mode 100644 index 000000000..aaca875a8 --- /dev/null +++ b/doc/_build/html/index.html @@ -0,0 +1,365 @@ + + + + + + + + + + Welcome to php-opencloud! — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Welcome to php-opencloud!

      +
      +

      Installation

      +

      You must install this library through Composer:

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

      +
      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 Getting Started with OpenStack or +Getting Started with Rackspace to help you get started with basic +Compute operations.

      +
      +

      Note

      +

      If you are running PHP 5.3, please see our Using the SDK with PHP v5.3 guide.

      +
      +
      + + +
      +

      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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/iterators.html b/doc/_build/html/iterators.html new file mode 100644 index 000000000..edf391c30 --- /dev/null +++ b/doc/_build/html/iterators.html @@ -0,0 +1,515 @@ + + + + + + + + + + Iterators — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $iterator = $computeService->flavorList();
      +
      +
      +

      There are two ways to traverse an iterator. The first is the longer, +more traditional way:

      +
      while ($iterator->valid()) {
      +    $flavor = $iterator->current();
      +
      +    // do stuff..
      +    echo $flavor->id;
      +
      +    $iterator->next();
      +}
      +
      +
      +

      There is also a shorter and more intuitive version:

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

      +
      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. +
      3. Group::getScalingGroup($data);
      4. +
      5. Group::resource('ScalingGroup', $data);
      6. +
      +

      where $data is the standard object. This list runs in order of +precedence.

      +
      +
      +
      +

      Setting up a PaginatedIterator

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

      + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionTypeRequiredDefault
      resourceClassThe resource class that is instantiated when the current element is retrieved. This is relative to the parent/service which called the iterator.stringYes
        +
      • +
      +
      baseUrlThe base URL that is used for making new calls to the API for new pagesGuzzle\Http\UrlYes
        +
      • +
      +
      limit.totalThe 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 listintNo10000
      limit.pageThe amount of resources each page containsintNo100
      key.linksOften, 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.stringNolinks
      key.collectionThe 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.stringNonull
      key.collectionElementRarely 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.stringNonull
      key.markerThe value used as the marker. It needs to represent a valid property in the JSON resource objects. Often it is id or name.stringNoname
      request.methodThe HTTP method used when making API calls for new pagesstringNoGET
      request.headersThe HTTP headers to send when making API calls for new pagesarrayNoarray()
      request.bodyThe HTTP entity body to send when making API calls for new pagesGuzzle\Http\EntityBodyNonull
      request.curlOptionsAdditional cURL options to use when making API calls for new pagesarrayNoarray()
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/logging.html b/doc/_build/html/logging.html new file mode 100644 index 000000000..8c8b9cddd --- /dev/null +++ b/doc/_build/html/logging.html @@ -0,0 +1,320 @@ + + + + + + + + + + Logging — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Logging

      +
      +

      Logger injection

      +

      As the Rackspace client extends the OpenStack client, they both support +passing $options as an array via the constructor’s third parameter. The +options are passed as a config to the Guzzle client, but also allow to inject +your own logger.

      +

      Your logger should implement the Psr\Log\LoggerInterface as defined in +PSR-3. +One example of a compatible logger is Monolog. +When the client does create a service, it will inject the logger if one is +available.

      +

      To inject a LoggerInterface compatible logger into a new client:

      +
      use Monolog\Logger;
      +use OpenCloud\OpenStack;
      +
      +// create a log channel
      +$logger = new Logger('name');
      +
      +$client = new OpenStack('http://identity.my-openstack.com/v2.0', array(
      +  'username' => 'foo',
      +  'password' => 'bar'
      +), array(
      +  'logger' => $logger,
      +));
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/objects.inv b/doc/_build/html/objects.inv new file mode 100644 index 000000000..ce930f072 Binary files /dev/null and b/doc/_build/html/objects.inv differ diff --git a/doc/_build/html/regions.html b/doc/_build/html/regions.html new file mode 100644 index 000000000..e4d0c94f3 --- /dev/null +++ b/doc/_build/html/regions.html @@ -0,0 +1,325 @@ + + + + + + + + + + Rackspace regions — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Rackspace regions

      +

      Below are the supported regions on the Rackspace network:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      codelocation
      IADVirginia
      ORDChicago
      DFWDallas
      LONLondon
      SYDSydney
      HKGHong Kong
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/search.html b/doc/_build/html/search.html new file mode 100644 index 000000000..332cba474 --- /dev/null +++ b/doc/_build/html/search.html @@ -0,0 +1,297 @@ + + + + + + + + + + Search — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      +
        +
      • Docs »
      • + +
      • +
      • + +
      • +
      +
      +
      +
      + + + + +
      + +
      + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/searchindex.js b/doc/_build/html/searchindex.js new file mode 100644 index 000000000..2dee3f4ab --- /dev/null +++ b/doc/_build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{getetag:63,four:[15,57],"catch":[71,17,39,34,91,92,63],prefix:[63,5,0],oldest:[85,41],whose:[],authorit:64,collation_serv:81,cloudloadbalanc:[],under:[],spec:[17,92],digit:[65,32],everi:[71,50,0,17,94,78,67,25,63,74],addsubdomain:60,"50mb":[],monitoring_zones_pol:52,tenni:85,getcontainercount:38,affect:60,"377341426ac5":5,macaddress:13,volumelist:19,planid:78,previou:[56,29,68,86,34,63],correct:[88,63],getchecktyp:52,nwww:[],bulkextract:63,ef08aa7a:[],settempurlsecret:6,repres:[56,34,58,7,60,18,63,67,5,32,70,15,27,37],terminolog:63,direct:[97,5,74],second:[85,75,17,93,68,96,86,52,34,22,41,14,92,63],even:[60,91],image_schedul:34,getendpoint:[3,77,88],check_id:30,errorpagecont:25,calcul:14,dataobject:[56,63],accountobjectcount:[],roleid:99,"new":[],net:[28,60],groupid:[8,45,23,33],metadata:[],abov:[28,29,50,71,17,93,96,9,80,25,90,24,22,63],domainlist:60,error:[],here:[26,71,37,63,90],snnrespons:[],"4xx":71,path:[28,15,63,6],interpret:99,anymor:[],datetim:[85,41,34],loop:29,permit:57,aka:29,jami:[11,75,63],unix:[2,14],securetrafficonli:26,printf:[29,57,17,60,92,98,76,33,77,4],total:[],"byte":[],unit:[2,28,30],sys_type_nam:3,describ:[],would:[29,56,36,37,69,26,41,15],snapshotlist:21,emailaddress:[60,11],recommend:56,type:[],until:[29,17,85,56,52,69,92,74],relat:[3,61,63,64],describedbi:15,notic:63,warn:[30,78],phone:63,exce:[65,85],regionless:[],localarchivefilenam:[],kskei:[],hold:[11,69],partsiz:63,"4b40":[],must:[0,94,67,78,2,24,25,26,27,4,28,85,75,57,58,6,7,60,61,55,63,80,30,5,8,83,33,74,40,84,97,69,35,9,65,36,13,98,90,14,92,16,76,56,43,17,93,45,18,96,19,20,52,46,21,59,41,77],join:28,restor:68,portrangemin:5,work:[],ntbbbb:78,conceptu:60,snapshotid:21,root:[],dns1:60,overrid:[57,63,0],"7a9ad27c0866":81,smtp:52,older_fil:63,secgroupid:12,getcriticalst:78,validatetempl:39,want:[],end:[80,29,56,57,0,60,63,67,25,26,16,74],opencloudrackspac:[],turn:[57,63],faulti:71,how:[71,52,24,26,85,57,3,77,61,39,35,65,38,15,63,10,17,18,99,41,48,60],theuserspassword:[],hop:48,rewind:[],verifi:65,logos_copi:[],config:[],connect_timeout:[81,58],updat:[],"41a6":[],setusernam:11,after:[29,75,17,96,85,34,24,63,40],befor:[],"49c5":[],alloweddomain:9,parallel:24,averag:[35,58],volumedeleteontermin:34,attempt:[56,78,11,69,4],third:[42,17,96,24,92,63,64],unclaim:41,opaqu:[85,32],"43cc":5,exclud:[67,85,50],hooladomain:60,receiv:[22,29,96,57,92],maintain:[],environ:[59,97],enter:[17,22],exclus:52,order:[24,25,55,27,4,85,75,76,58,60,78,80,30,16,8,33,98,9,56,90,14,15,63,94,43,93,45,96,20,34,41,77],oper:[],feedback:28,diagnos:78,offici:[28,0,68,20,86,52,34,3,15,63,4],filesystem:[],becaus:[56,58,17,77,92,86,90,91,41,14,15,63],jpeg:[],connectionlog:94,london:[79,92],zgggb4rmymif:[],flexibl:85,vari:[],publicurl:[],getev:66,objectmetadata:[],uuid:65,fit:[60,34],fix:57,cred:11,easier:[17,77,92],them:[57,7,60,35,78,52,34,3,63,74],thei:[85,42,57,6,60,78,56,63,32,90,91,14,15,27,74],isdis:30,fragment:63,"8gb":29,"break":[17,29,60,88,92],listkeypair:82,manifestfil:63,isen:[11,62],choic:81,exportcredenti:50,setdescript:99,ntaaaa:78,timeout:[58,52,17,26,24,92,4],each:[],debug:[],metahead:[],mean:[71,78,34],memoryinfo:3,capac:97,logo:[],collector:48,oldcontain:24,network:[],goe:78,foo_bar:[],newli:34,setemail:11,dsl:30,sprintf:[17,78,92],removerol:99,forth:18,jamie_dev:51,nodetyp:96,navig:[],uploaddirectori:57,situat:91,free:[24,28,31],standard:[57,68,78,56,52,63],silent:98,filter:[],renew:41,curlopt_progressfunct:[],onto:34,cpuinfo:3,rang:[14,9,67,5,34,48,63],independ:[29,57,78],"81c1":23,networkintinfo:3,restrict:74,hook:78,unlik:63,alreadi:[11,17,96,78,82,41,92],logplugin:71,getmemb:49,nptechnicalcontactsemail:78,primari:[2,60,11,96,95],attemptsbeforedeactiv:4,listev:66,top:[56,28,15],sometim:[2,52],eb60583c:[67,13],master:[39,40],too:[59,71],hadptrrecordsinterfac:90,similarli:63,scalingpolici:[56,23],john:[],listen:[26,29,20],iosstreamingurl:[],namespac:[17,28,92],tool:[75,78],incur:31,getimag:[91,49,51],technic:78,target:[],provid:[71,49,0,59,78,2,52,53,25,74,29,75,56,58,7,60,61,82,83,84,34,35,88,10,85,91,63,86,11,68,18,96,97,69,41,77],"26dc":[],my_amazing_contain:57,project:[65,28,32],"5399cd36":[],minut:[17,40,41,14,6],"51db6f78c508f17ddc924357":85,createaccesslist:9,provis:[97,34],createmessag:85,imageref:23,ram:[],mind:[11,57,63,6],getrequest:[17,71,92],raw:[70,39,40],aforement:[],manner:34,rax:34,recreat:40,latter:57,accountcontainercount:[],client:[],queuesservic:69,expens:83,remotefilenam:[],nsrecord:60,general1:40,usernam:[],object:[],what:[],regular:[83,27],specifi:[],letter:[65,60],getprivatekei:82,phase:37,hide:[56,49],min5:14,deviceown:13,tradit:56,blacklist:9,don:[17,71,92],doc:[],alarm:[],clock:[85,41],instancelist:81,doe:[71,42,57,60,88,63,26,13,34,24,91,27,46],wildcard:9,getprocessvers:3,routabl:[29,74],api:[],opposit:[48,64],random:6,advisori:52,messageid:85,getcheckid:30,enablecdnlog:75,involv:[86,56],servererrorresponseexcept:71,explain:[],apach:[94,63],busi:63,tar_gz:63,getpartialobject:63,"49bd":[],invalidtemplateerror:39,stop:[56,52,41],getcdn:[],bar:[11,42,76,50,17,45,92,65,91,60,15],notificationplan:78,baz:[17,76],method:[],new_queu:65,respond:[52,41,74],previewstack:40,result:[],"123abc":[],respons:[],fail:[17,98,96,52,34,24,41,92],themselv:[49,64],createent:37,flavorid:[86,29,34],best:[41,34],awar:[57,63,98],npaaaa:[],singleitem:78,ac6bb468c5bf:[],simplest:[68,63],awai:[55,63],irc:28,loadbalanc:[],createsymlinkfrom:[],cloudmonitoringservic:[],accord:[82,60,14,63],extend:[71,91,41,42],var_dump:[17,92],monitoringservic:[48,35],pnrr0lre:[],extens:[],protect:[15,97],accident:65,expos:57,howev:[56,29,35,78,86,52,21,34,24,22,48,27],against:[49,17,95,51,88,52,24,92,74],cloudqueu:[],logic:[7,30,71],countri:48,seri:[85,78,73],com:[28,11,42,17,60,78,52,75,98,26,90,48,92,39,40],computeservic:[17,59,19,56,90,92],can:[95,49,50,1,78,2,3,93,62,24,26,27,74,28,29,75,56,57,58,6,7,60,61,55,77,63,81,69,30,39,59,83,64,84,68,35,9,98,10,87,66,12,13,85,91,65,14,15,5,86,11,52,17,44,18,96,19,40,46,97,34,99,36,92,41,88,67,37],foobar:[3,27,0],a2cc:[],serverthre:96,guid:[],assum:[99,28,85,96],duplic:60,summer_vac:63,entitybodi:[56,63],getscalingpolici:[33,45],three:[53,96,91,63],been:[29,11,49,56,75,25,24,63],servertwonod:26,trigger:[52,35,78],debug_info:[52,78],basic:[],min240:14,a0a1:78,addrecord:60,new_email:11,deeper:64,xxx:0,worker:[41,69],search:[60,98],ani:[29,75,49,58,68,60,69,96,35,65,52,13,85,32,26,41,46],accesslist:9,lift:63,child:56,"86df":[],getaccount:[38,6],spin:[17,92],enablerootus:27,ident:[],adress:67,servic:[],properti:[],container_2:63,container_1:63,apikei:[47,74,97,50,7,18,35,61,2,72,69,89,32,83,59,92,70,64],dashboard:3,publicli:75,"7e4a":13,privatekei:20,spawn:[],"7704fb98ab1":[],cpumetr:3,securitygroupid:5,transferbuild:63,undelet:41,setid:[99,11],sever:[14,64],hong:[79,92],cntl4qsiba:[],perform:[],make:[71,85,49,17,77,95,78,56,32,24,41,14,74],demoauthor:[],weighted_least_connect:96,complex:56,backoffplugin:24,fefcaa640216:[],complet:[],testnewcheckparam:52,raid:97,disablecdn:75,fairli:15,rais:24,portal:60,refin:[86,68,63],deletetag:51,tune:[],kept:34,abandonstackdata:40,scenario:57,flavorref:23,inherit:[56,99],contact:[78,6],ubuntuimag:[],thi:[72,71,49,50,0,67,3,93,25,26,27,4,29,75,56,57,58,6,77,78,55,92,80,81,30,5,8,82,33,98,9,10,12,13,38,91,14,15,16,76,86,11,43,17,44,94,96,20,68,52,46,34,99,23,88,37],gzip:[],everyth:[71,63],left:[60,34,57,6],identifi:[56,85,35,65,53,13,70],just:[57,17,86,24,92,63],enableconnectionlog:94,bandwidth:[24,86,34],human:[67,12,13,46],yet:63,languag:30,previous:34,easi:[56,57,16,74],requestor:26,maximumtotalsizeofobjectsallowedincontain:[],els:[17,92,63],save:[68,95,82,50,34],explanatori:[],lbservic:29,applic:[28,34,10,97,69,15,63,74],preserv:40,openstack:[],shadow:20,claimmessag:41,daemon:35,orchestrationservic:[18,36,1,39,40],specif:[],arbitrari:[85,65,52,30,37,34],manual:[60,63,34],remind:49,badresponseexcept:[17,71,92],unnecessari:34,grouplist:23,www:60,right:[56,99,60,32],old:[24,63],deal:41,getbytesquota:57,percentag:68,intern:[24,56,92,31,34],stacktempl:40,ccccc:[],txt:63,file_get_cont:[82,50,39,40],getheaderlin:[],eleph:[],middlewar:57,getcontain:[24,57,63,6],condit:[],foo:[71,11,42,76,50,17,45,92,65,90,91,60,15],pvhvm:40,core:3,plu:41,"89b3":5,newtoken:3,post:[],plug:7,postgresql:52,hasconnectionlog:94,slightli:77,simul:[],coars:14,produc:[66,18,49,39,69],soa:60,getiosstreaminguri:75,nrespons:[17,92],encount:[52,71],encod:[70,57,63],end_mark:57,down:[60,13,46],wrap:[71,34],getagenthost:3,storag:[86,85,75,97,68,19,2,21,83],hallo:75,wai:[56,85,96,2,34,22,91,15,63],strtotim:60,support:[],nova:[],crecord:60,avail:[49,78,72,54,26,74,75,3,6,59,60,61,64,35,88,14,52,11,42,67,17,44,68,97,99,41],jane:[],call:[71,52,24,74,85,75,57,60,15,40,98,88,65,10,92,56,11,17,95,96,68,34,99,77],updatestatu:49,head:[],form:[56,71,90,13,15],sub1:[],forc:[88,74],getsecuritygroup:12,getwarningst:78,cidr:[7,5,67],icmp:5,"true":[65,85,57,63,0,68,78,60,16,67,20,86,52,13,34,26,48,94,27,46],freenod:28,filesystemmetr:3,getpassword:11,createus:11,maximum:[63,11,58,5,61],tell:[24,57,6],new_object_nam:63,"4bb8":[],fundament:[],entityid:[30,14,37,78],unrel:48,enablelog:57,"08z":34,featur:[24,25,54,3,74,75,76,58,6,78,80,30,16,4,9,86,14,63,43,93,94,96,20],volume_type_id:19,"abstract":48,mirror:57,backoff:24,glanc:15,metadatalist:76,check:[],us_identity_endpoint:[47,74,97,50,7,18,35,61,2,72,69,89,32,83,59,92,70,64],assembl:[18,39],arecord:60,listcontain:[75,57],"42fe":[17,92],connectionid:3,when:[71,78,52,25,24,26,74,29,75,57,7,60,61,63,81,30,16,82,40,35,88,56,36,85,14,92,39,11,42,17,18,96,20,34,99,41,77],guzzlephp:[],roll:[41,14],node:[],notif:[],subdivid:78,consid:[60,14],marconi:[],file_put_cont:[50,40],faster:24,furthermor:85,anywher:31,deleteallobject:57,ignor:[85,41],time:[58,73,57,50,6,68,60,69,78,52,75,63,97,32,24,83,74,14,16,40],push:[3,35],backward:56,concept:[],skip:41,consum:[11,49,32],focus:3,getcountrycod:48,getsubnet:67,hierarch:[],depend:[84,97,17,7,60,18,35,61,2,52,69,85,32,24,83,92,59,14,77,74],zone:[],getrecordedcheck:78,getconnect:3,intermedi:20,autoscaleservic:61,text:57,listresourc:87,compart:2,sourc:[80,48,15,34],string:[71,67,25,85,56,57,6,60,78,92,82,5,32,40,98,65,12,37,15,63,10,11,52,96,46,34,36,70,48,13],could:[90,25,78],logexcept:[],"8d5c":[67,13],fixedip:13,brows:15,bbbbb:[],cloudimag:[],hour:[],administr:[11,13,46],level:[56,15,27,64],iter:[],item:[],team:[35,78],cooki:80,x0r:[],round:96,shave:50,demo_db:[],slower:86,deviceid:13,cost:[],dnsservic:[90,64],port:[],getobjectcount:[57,38],getipaddress:37,c55c4705a286:[],repli:[],rollup:14,warning_st:78,containersizeinbyt:[],boost:92,urltyp:[84,7,18,35,61,2,69,97,59,83,63,74],deriv:85,process_vers:3,stmp:52,gatewayip:67,satisfi:52,address:[],clonedomain:60,along:[60,88],getprivateurl:77,"860d":[],wait:[],listnetwork:46,groupconfigur:23,ini_set:24,shift:22,images_link:56,objectcont:[],gettokenobject:50,persistentobject:56,queue:[],behav:32,commonli:[52,35],regardless:[56,57,40,49,6],extra:34,modul:[],prefer:17,getbodi:85,toarrai:65,rackspace_u:[],visibl:[15,20],marker:[86,68,85,56,57],instal:[],regex:37,httpd:63,file_exist:50,memori:[24,3,97,63],visit:61,hasqueu:65,"57ea":[67,13],"0d589460":23,criteria:[60,30],scope:[57,34],testexist:78,peopl:57,finit:32,supported_platform:52,unseri:50,easiest:34,subschema:15,b5e4:[],prepar:91,uniqu:[85,11,65,67,12,13,97,34,91,74,15,63,46],getlastmodifi:63,subet:7,whatev:34,"20902aec0e74":[],purpos:[95,64],heart:61,encapsul:88,predict:56,container_55:57,critic:[30,78],spl:[56,91],setuserag:0,resourceclass:56,occur:[71,91,15,78],gettyp:[3,52,77,78,88],alwai:[17,7,35,52,31,34,91],multipl:[],uptim:52,container_quota:57,write:[24,17,92],targettyp:60,my_secret:6,foreach:[49,52,53,62,73,26,29,75,56,57,3,60,78,55,81,30,63,82,33,40,98,85,9,86,87,66,36,13,90,91,14,92,5,76,65,11,58,67,17,44,95,96,19,68,46,21,93,99,12,23,88,77],fourth:64,"4bc5":81,parameter:[18,39],map:[80,48,32],product:[55,27],network_interfac:3,abstractschemaresourc:91,mac:[7,13],mai:[29,49,6,17,48,60,34,20,52,32,99,83,91,14,92,57],underscor:65,data:[],subsequ:[49,50],waitfor:[17,29,60,92],rather:[63,6],"switch":7,preced:[58,9,56,67,13,46],combin:[2,75,97,95],getlastconnect:3,filedata:[],setdefaultopt:0,getnotif:78,anticip:63,midnight:[],virtualip:[93,29],increas:[29,97],ttl:[],still:[22,52],pointer:[56,15,64],dynam:[67,91,97,15,63],entiti:[],sata:83,polici:[],platform:52,window:2,mail:[28,60,75,64],main:[7,78,6],bootablevolum:34,averagenumconnect:58,initi:[96,34],bound:37,therebi:34,half:26,nov:63,now:[56,34,74,7,18,35,61,2,69,97,32,83,23,59,70,64],discuss:59,name:[],revert:92,separ:[60,13,63],getitem:[17,77,88],januari:14,resourcetyp:[36,1],failov:[],getmetr:14,replac:[],continu:[29,60],opencloudopenstack:[],happen:[17,56,92,88],dispos:98,firstkei:45,subnet:[],shown:[39,29,46,44,96,1,67,81,66,12,25,87,36,40,5,13],passwordcredenti:[],space:[29,57,59,60,34,3,63],old_fil:63,monolog:42,urlencod:[57,63],catalogtyp:[],"25c16d7fa83d":[],factori:[56,77,63],curlopt:56,e41380a:[],userconst:11,tempurl:[],contain:[],remoteipprefix:5,setpassword:11,org:[],ord:[24,79,92],"5ac56230f841":[],adoptstack:40,frequenc:[52,14,35],synchron:57,catalog:[],thing:[78,60,11,77,34],place:[28,91,61,6],principl:3,think:[83,35],first:[72,49,47,61,2,55,93,25,26,59,27,4,85,75,57,58,7,60,51,92,80,30,63,32,8,83,33,74,64,69,35,9,98,86,67,89,14,15,16,76,56,70,43,17,78,45,18,96,20,68,97,34,22,41,48,94],origin:[2,52,85,41,63],ipvers:[67,29],directli:[34,48,32],subrang:67,carri:[],onc:[28,29,75,49,6,17,60,35,62,78,56,3,30,85,24,92,41,52,77,63],arrai:[72,50,26,70,47,88,78,2,24,25,3,59,27,4,89,29,56,57,6,7,60,61,55,92,63,80,81,69,30,39,85,32,8,82,33,74,64,97,68,35,9,98,10,67,12,13,83,90,91,65,14,15,5,76,86,11,42,52,17,45,18,96,19,20,40,46,21,34,23,41,48,37],yourself:[91,95],cachefil:50,"long":[85,41,49],createcontain:57,oppos:[],secureport:[26,20],happi:78,open:[49,27],mzdfw:14,country_cod:48,size:[],given:[],billableloadbalancerlist:58,convent:[24,60,91],getclaim:41,iad:[24,79,92],datastorelist:44,httpheader:63,userinfo:3,apikeycredenti:[],white:60,conveni:[24,56,63],webhookid:45,server_hostnam:40,somecontain:57,season:57,programat:[],copi:[],artifact:18,broadcast:7,github:28,than:[67,63,86,52,13,98,90,91,41,48,77,5,46],png:[],serv:[],wide:85,hostrout:67,isrooten:27,balanc:[],posit:[],mov:63,browser:63,alarmstatu:30,sai:96,san:97,argument:[6,17,93,60,68,86,52,24,92,63,40],nbodi:[],createscalingpolici:33,"20b":63,deliv:[2,94,78],maxconn:58,implod:[],engin:97,offer:[24,17,91,78,92],networkitem:9,router_interfac:13,ideal:69,checktypeid:52,take:[40,17,61,9,67,12,13,97,24,91,41,15,5,46],advis:24,fetchdatapoint:14,noth:[],channel:42,begin:[24,52,56,57,58],sure:50,normal:[24,41,96],track:80,compress:69,pair:[52,30,37,97,34,74],unalloc:48,c6dd8e837028:5,iptyp:93,later:[],drive:83,getresourcetyp:36,b5da:[],runtim:52,recipi:69,show:[60,11,14],concurr:63,label:[78,52,30,37,3,48],fifth:64,rotat:[96,74],onli:[72,49,52,54,26,74,29,75,6,60,61,80,81,31,83,40,69,35,86,37,85,91,63,65,11,67,68,64,96,20,46,34,41,13],explicitli:[11,35],ios_stream:[],transact:[71,58],maximumnumberofobjectsallowedincontain:[],activ:[29,58,17,96,61,68,92],createqueu:65,getobject:[71,63],analyz:[3,35,57],over:[],logfile_:63,variou:[26,52,15],importcredenti:50,getid:[85,11,99,77,78,62,56,52,30,3],secondari:96,cannot:[71,85,60,2,52,81,91,64],ssh:[82,34],"_must_":[],ssd:83,requir:[],ndescript:40,getemail:11,hasptrrecordsinterfac:90,error_log:63,privileg:99,where:[57,6,60,0,96,78,56,3,24,91,63,74],imageservic:70,deadlin:85,reserv:7,operationtyp:15,getmetadata:[87,30,37,63],character_set:55,new_dev:60,behind:15,between:[85,57,96,2,26,24,41,14,74],message_id:[],"4c4a":81,assumpt:[85,14],parent:[],nodeev:96,come:[24,26,57],tue:63,region:[],tutori:[],flavor_id:40,mani:[10,57,3,52,35,61,2,26,38,24,65,48,63,74],overview:[3,34],getpolici:[],period:[],colon:13,user2:[],launch_serv:23,user3:[],west:48,rebuild:[68,59],mark:85,asyncrespons:60,getdefaultregion:11,addfil:34,attachvolum:19,former:57,those:[86,59,68,57,9],"case":[17,19,56,68,27,34,92,63],virtualiplist:93,tostr:[],mount:19,plugin:[],new_autoscale_group:23,stackev:66,advantag:24,stdout:71,reportprogress:[],destin:[67,78,63,80],blah:45,ascii:65,addr:[26,96],develop:[70,74,7,18,35,61,2,69,97,32,83,59,64],author:[57,63,32],alphabet:[65,40],iscsi:97,same:[28,29,11,74,50,69,85,67,75,37,34,46,13],binari:[70,57],hkg:[79,92],html:[],array_merg:63,eventu:[],ptrrecordlist:90,exhaust:15,finish:[60,41],webserv:12,f177:23,nest:[56,57,6,2,15,64],assist:28,driver:85,someon:[],capabl:97,allocationpool:67,getrol:99,improv:[16,74],statuscod:[],serverid:[68,19,34],checkhistori:78,stockhead:63,appropri:[22,14],bind9data:60,listresourcetyp:36,without:[65,75,63,34],model:[],nodelist:96,webhead:23,rest:35,migratecontain:24,touch:26,flavor:[],speed:50,resetapikei:11,versu:20,display_nam:[21,19],servertwo:[26,96],getcdnstreaminguri:75,except:[],param:[49,77,51,19,78,86,52,53,21,55,90,91,63,57],objectstor:[75,57,63],blog:57,"3afe97b2":[],fb11:[],getgroup:[],real:[],newproperti:91,around:63,read:[28,57,17,69,24,92],virginia:[79,57,92],traffic:[7,94,96,9,20,26,31,93,24,92,5,74],mon:63,psr:42,saniti:57,interv:[14,58],whitespac:85,getcont:[],integ:[52,96,67,15,5,40],server:[],either:[11,57,80,17,93,96,78,92,63,68,90,25,34,83,14,15,5,74],d3f15879:[],ok_stat:78,output:[71,17,18,30,92,63],manag:[60,18,61,20,97,34],mail2:60,portrangemax:5,adequ:71,authent:[],constitut:85,poll:[17,52,29,92],confirm:75,getnotificationplan:78,definit:59,achiev:[29,34,33,64],protocol:[],evolv:78,keyston:[17,77],servicenet:[24,29,92,74],bundle_vers:3,clienterrorresponseexcept:[71,11,63,93],refer:[],processesinfo:3,filesysteminfo:3,domain_limit:10,starttim:58,fulli:[56,90],cloudmonitor:[3,52],isset:[17,92],comparison:[57,98],adoptstackdata:40,act:[52,35],industri:78,naction:60,getguid:3,effici:[85,95,56,3,34,24],getexponentialbackoff:24,zoneid:48,scalinggroup:56,minram:86,streamingurl:[],yyi:0,your:[],demo_us:[],her:49,area:[97,63],imagest:68,lon:[79,92],some_empty_contain:[],overwrit:[65,57],start:[],catalogitem:[77,88],interfac:[56,7,91,97,34],ipv4:[],lot:56,ipv6:[],"2yiukpwfoclimyrxesyxpd":[],hard:83,detachvolum:19,amongst:[26,74],categor:65,longer:[56,26,22,41,48,40],target_hostnam:52,cloudnetwork:[],"default":[],"173c":[],connect:[],creat:[],certain:[71,57,59,56,34,15,63],loadbalancerservic:[29,74],errorpag:25,ntarget:60,incorrect:[56,88],again:[17,60,92],extract:[],alaaaa:[],changedetail:60,field:[17,52,60,68,90],valid:[],collis:57,you:[],getdescript:[99,78,62],architectur:18,condens:14,sequenc:[55,57],latenc:34,guzzl:[71,11,42,49,0,17,77,51,92,56,24,15,63],pool:[7,13],reduc:[74,16,34],escal:78,directori:[2,97,57,63,6],descript:[],hello:75,week:60,potenti:49,cpu:[3,59,97],setdomainid:11,represent:[34,36,92,63,32],rax_priv:[],forbidden:91,mp4:63,mp3:[],abil:[7,63],follow:[1,78,2,52,26,74,28,75,58,6,7,60,61,5,83,40,84,69,35,65,12,13,14,39,66,67,17,93,18,96,46,97,59,87,36],disk:[29,50,68,59,86,34,3,83,70],groupconfig:[8,23],content:[],opencloud_token:50,wish:49,diskconfig:34,enabledhcp:67,bind_9:60,introduc:[],checkid:[30,14,78],fals:[94,65,57,71,17,60,68,16,86,67,13,34,91,92,27,46],util:[3,71],mechan:80,loadbalancerlist:26,failur:[63,58],veri:[],pathstobedelet:63,pagelimit:24,main_kei:[82,34],ordservic:24,webmast:60,httpmethodallow:[],adjust:[41,34],removenod:96,getnotificationhistoryitem:78,ten:52,sync:[],rate:24,design:[2,3,52],pass:[],further:[],unreceiv:78,deleg:[57,64],sub:60,"646ac7b0":78,section:[26,40,57,63,34],abl:[17,80,29,91],brief:3,rackspac:[],version:[],getagenttarget:3,"public":[],essenc:26,millisecond:14,full:[0,68,20,86,26,52,34,24,14,15,63,4],hash:[52,37,78,6],berkelei:60,"5gb":[],unmodifi:63,behaviour:[],listsubnet:67,inher:[91,74],parenthesi:60,valu:[50,0,26,59,2,52,25,55,74,85,75,56,57,58,6,7,60,61,80,81,30,63,82,40,84,69,35,10,12,37,83,91,15,5,76,65,67,68,18,96,19,46,97,34,41,13],a23f:[],volumeid:34,securitygrouprul:5,prior:[],amount:[56,29,75,59,86,24],pick:[],action:[60,41,57,78],narrow:3,via:[28,42,49,59,35,34,26,39,40],thirdkei:45,primit:35,transit:29,"0b3f":[],filenam:[82,63,34],vip:[],href:[85,41,15],establish:11,select:[],rackspacecloud:92,distinct:11,regist:[17,28,34,92,64],two:[],createnetwork:46,getnotificationtyp:78,taken:7,basi:71,minor:22,more:[],reachabl:61,flat:[60,34],desir:18,particular:[],known:[48,39],compani:35,"0b34":78,min1440:14,dictat:91,none:63,endpoint:[84,95,17,7,77,18,35,88,61,2,3,69,97,59,24,83,48,92,74],servicecatalog:77,valuabl:78,hous:63,outlin:[77,15,61],dev:[60,19],addvirtualip:[26,93,29],remain:[26,85,41,34],caveat:[],userguid:[],dec:63,connecterror:58,tahr:40,accept:[28,96,49],cation:[],minimum:[86,22,61,5,52],getcheck:[30,14,78,52],"20gb":[],getcredenti:77,timeoutmin:40,xxxx:17,secur:[],programmat:26,anoth:[56,15,92],snippet:63,display_descript:19,reject:[49,9],iso:34,simpl:[59,40,57,63,34],css:6,resourc:[],referenc:37,webhook:[],hoola:[],bdf7:[],okai:[17,71,92],aaaaa:[],datastor:[],mariadb:97,target_resolv:[52,48],newdomainnam:60,ethertyp:5,"short":56,launchconfig:[8,23],maximumtotalsizeofobjectsincontain:[],created_at:15,getbytesus:[57,38],hogarth:57,assign:[2,7,34,11,32],callback:[17,92],addsubscrib:[24,71],media:75,listsecuritygroup:12,help:[],soon:63,held:24,through:[],hierarchi:60,"9e9d":81,imagelist:[17,68,92],addtag:51,woolf:57,style:[94,6],overhead:86,getstatuscod:71,ip_address:[52,37],coarser:14,relev:[56,33],pend:49,might:[85,74,63,98,35,86,67,12,13,34,91,40,15,39,46],good:[17,15,92],"return":[],timestamp:[52,14],outgoingtransf:58,serveron:[26,96],detach:[],subdomain:[90,60,64],enact:24,userid:[99,11],instruct:[52,90],refresh:63,easili:[57,9],token:[],found:41,appendtometadata:[57,63],truncat:85,responsebodi:[],weight:96,blank:[60,92],procedur:[],heavi:63,gettempl:[36,40],createstack:40,cloudorchestr:[],publish:[57,69],research:56,etag:63,health:[],trusti:40,utf8:55,print:29,occurr:60,container_2001:57,upon:52,cdncontain:75,pub:82,alarmid:[30,78],reason:[56,91],base:[68,71,56,57,52,17,94,34,35,78,2,3,69,30,32,26,91,14,92,63,40],put:[24,60,6],setcountquota:57,testparam:78,resourceev:66,thrown:[71,25,93],"0d3ac30bnh6sw9jd9uzhycpsxsibechw":[],thread:50,omit:[84,11,7,18,35,61,2,69,97,59,83,63,74],agentid:3,iadservic:24,perman:[],lifetim:41,dfw:[79,92,88],sessionpersist:80,notifi:[41,49,78],httpsurl:[],prevent:69,feel:28,exchang:64,number:[],containerobjectcount:[],done:[41,57,63,78],construct:[56,77,63],loadbalancerid:[26,23],stabl:22,ystem:68,internalurl:[],differ:[10,75,56,57,17,77,95,35,88,78,2,52,98,34,99,91,14,92,63],script:[1,67,26,5,29,75,57,6,81,82,63,40,85,9,86,66,12,13,38,39,65,11,68,44,19,20,46,21,34,87,36,41],ipaddress:13,interact:[],minent:23,least:[93,41],http_cooki:80,statement:28,"11e4":13,scheme:34,"11e1":78,store:[],adher:60,option:[],relationship:85,getscalinggroup:56,memcmp:57,getten:62,absolutelimit:10,round_robin:26,part:[52,41,35,63],consult:[28,0,68,78,20,52,30,34,90,23,14,15,63,4],grace:[41,34],mode_email:11,kind:[24,37],prebuilt:59,whenev:[30,78],instanceid:[55,29,27],html_site:6,beforehand:[],packag:24,expir:[],nodeeventlist:96,dedic:69,"null":[59,2,67,74,29,7,61,80,83,40,84,35,56,12,13,91,92,5,18,96,46,97,69,70,37],b8b3:[17,92],getpublickei:82,entireti:65,built:[57,34],zero:87,self:[15,57],violat:27,also:[],build:[],getbundlevers:3,objectlist:[24,63],autoload:[17,28,92],portid:13,distribut:[2,26,96,74],unsur:17,choos:20,reach:[56,85],alloweddomainlist:9,most:[56,57,71,65,27,63],plai:85,getalarm:[30,78],plan:[],charg:[24,31],appear:[84,49,17,7,18,35,61,2,69,36,97,59,83,92,74],recordlist:98,my_api_kei:[],destruct:55,getter:[99,91,11],keystoneurl:[7,18,47,2,69,97,59,83,70,32],healthmonitor:4,newvalu:60,usual:[95,19,31,34,63,64],databaselist:55,cdn:[],alphanumer:[74,57,63,40],bulkdelet:63,"0ff89fa2fa26":78,fine:[14,9],find:[],coerc:63,payroll_2001:63,pretti:[],setnam:99,nexampl:[],templat:[],getexpir:77,yml:40,datastorevers:44,hit:78,express:58,nativ:[56,91],tcp:[52,58,5],banner:52,restart:[],getmonitoringzon:48,rfc:[15,63],connecttimeout:58,common:[],getdetail:[78,38],sslconfig:20,obscura:63,certif:[52,20],set:[],php_eol:[17,3,85,65,58],tokenid:[3,77],claimid:41,see:[68,28,11,56,52,17,77,38,88,92,86,26,34,3,15,63,40],sec:24,arg:[8,52,23],close:[26,63,58],analog:15,simultan:58,notification_plan_id:30,gethref:85,someth:[17,65,15,92],particip:61,enclosur:15,experi:[],altern:[17,52,78,63,92],signatur:[60,96],dalla:[79,21,19,92],numer:71,isol:[7,97,32],"4gb":[86,29],image_id:[],getdebugplugin:71,popul:[56,63,34],"6a4l6rr":[],both:[71,42,49,58,78,20,52,97,90,91],last:[],some_contain:[],defaultregion:11,imageid:[68,91,49,51,34],ssltermin:20,load:[],simpli:41,instanti:[],schedul:[14,35,34],header:[],shutdown:41,suppli:[28,58,60,19,55,90,70,63],getcriteria:30,backend:[46,74],devic:[75,35,67,90,13,34,3,83,74],"11be":13,empti:[29,57,67,17,60,55,82,13,26,92,63],destructor:63,lastmodifi:63,accessipv4:34,secret:6,accessipv6:34,setstaticerrorpag:6,monthli:57,nonexist:85,strategi:[],memory_limit:24,resizevolum:29,bzip:[],flight:68,flavorinterfac:86,fire:[],imag:[],stdclass:[56,87],append:[65,57,63],geten:11,understand:[],demand:[3,97],nameserv:67,repetit:50,limittyp:10,imap:[52,98],checktyp:52,look:[63,40],"5e3898d7":13,solid:83,straight:63,batch:[],oldvalu:60,durat:[40,30,32],cluster:37,"while":[56,41,97],old_contain:24,behavior:[61,97],checksum:[],piqspo8ndphw0010jemh9gygnnflyy3:[],anonym:15,robin:96,getttl:85,gettempurlsecret:6,readi:[17,60,96,92,34],systeminfo:3,revoketoken:77,dfw1:48,setttl:[],itself:[96,35,55,16,98,8,33,41,27,74],mxrecord:60,extra_spec:53,getbuildinfo:1,fedora:15,grant:[99,6],belong:64,shorter:56,decod:[],sessionpersistencetyp:80,higher:[17,92],syd:[79,92],optim:97,wherea:92,alert:[52,30,35,78,37],getsupportedplatform:52,chang:[],recent:[63,16,74],halfclos:26,travers:[17,56,60,92,98],task:69,older:22,entri:60,httpsredirect:26,npaaaaa:30,hasexpir:[77,50],getusernam:11,"2gb":[17,92],getentityid:73,algorithmlist:26,test_fil:34,explan:[20,39,4],datatimedout:58,volume_typ:19,cooldown:[23,33],mysql:[29,55,52,97,26,63],love:[17,92,34],createsecuritygrouprul:5,protocollist:26,expirationtimeinsecond:[],getview:95,sydnei:[79,92],getnetwork:46,"2076db17":5,pubkei:82,web01:40,min60:14,vendor:[17,28,92],password123:11,format:[],intuit:56,alertdev:[],"868a0966":[17,92],volumetypelist:53,semi:50,resolv:[52,64],elaps:14,manifest:63,collect:[],"boolean":[52,67,13,34,15,46],a2fc8d80c001:[],createport:13,tempnam:[],often:[56,52,78],objecttransf:[],some:[],back:[29,57,68,80,26,41,16,74],catalognam:[84,7,18,35,19,61,2,69,97,59,83,74],sampl:[],remotegroupid:5,containerlist:[],sizeof:56,containernam:[75,57,63],objectstoreservic:[2,24],weighted_round_robin:96,scale:[],per:[56,11,10,69,24,74],cast:71,substitut:[17,55,98,8,33,27],retri:24,slash:57,e836fc4:[],machin:[59,70,48,97],dnsnameserv:67,run:[28,56,0,17,48,18,35,10,81,97,24,41,14,92,40],zzz:0,"59e6":66,snake:[],nodeid:96,example2:60,impos:[10,57],paginatediter:[],prove:[7,18,47,2,69,97,59,83,70,32],b2f5eccd2b2:13,subnetid:[67,13],"1gb":[17,92],block:[71,29,68,7,35,52,21,34,83],forbiddenoperationexcept:91,primarili:[],"512m":24,within:[66,57,58,52,31,32,99,74,48,15,64],drain:96,ensur:[57,68,65,52,24,41,63,74],hemingwai:63,announc:28,identityservic:32,fledg:[],updatepassword:11,megabyt:86,live:[41,69],submit:[26,85],custom:[],doubt:92,includ:[74,99,58,60,95,65,67,3,90,41,77,64],resourcetypetempl:36,forward:[56,57,13,46],setstaticindexpag:6,getrespons:[17,71,92],blueprint:61,properli:[26,74],geturl:56,link:[],line:[22,60,28],getresourc:87,sdk:[],concaten:63,serverst:[17,92,34],consist:[60,74],nodecondit:96,sample_adopt_stack_data:40,oldimmutablefil:63,configid:81,similar:[2,24,35,19,93],constant:[85,11,57,17,68,34,41,92,63,49],f5b8c8a7c62b0150b68a50d6:[],user1:[],getfield:52,contentcach:16,addrol:99,containermetadata:[],"char":[52,37,78],queuenam:[85,41],guarante:34,curl:[56,63,0],metadatahead:[],jamie_keypair_1_rsa:[],invalid:39,librari:[17,28,92],gigabyt:[86,19],clouddatabas:[],retrievemetadata:[65,63],formatt:[],meaning:[],percona:97,getport:13,latin1_swedish_ci:81,rootus:27,stabletransit:60,source_ip:[80,48],evenli:26,depth:[59,15],listport:13,chaaaa:[30,78],deletemessag:85,endtim:58,secondkei:45,code:[],partial:63,memberstatu:49,fclose:63,image_fil:[],container_nam:[],privat:[29,93,96,88,46,34,26,15],nheader:[],listmessag:85,elsewher:28,friendli:[52,30,78],send:[],granular:[],itemuuid:78,diskinfo:3,exit:[17,92],"4b0f":23,"6lhbqdw5ayd44bd8jttdc":[],sent:[71,85,77,35,78,24,39],deactiv:4,xxxxxxxx:17,mindisk:86,enablecontentcach:16,containerobject:[],wipe:[55,57,63],newcontain:24,volumetyp:[53,19],id_rsa:82,geograph:[2,24,35],"try":[71,50,17,93,39,34,91,92,63],race:41,c1342a0a:66,pleas:[28,85,57,0,68,98,78,20,30,34,26,90,23,14,63,4],object_a:[],impli:7,getpublicurl:[77,88],readabl:[67,12,13,46],setcont:63,tempurlsecret:[],tar_bz:[],setclientid:65,hannaford:75,video:[75,63],download:63,object_z:[],claim_id:[],"85cc3048":5,compat:[56,42],index:[67,46,13,6],compar:[85,57],chicago:[79,92],"0800200c9a66":13,access:[],xxxxxxxxx:17,createsecuritygroup:12,some_other_contain:[],getcdnservic:75,san_diego_vac:[],backupstart:85,bodi:[85,77,15,56,34,60,63],firewal:34,let:[17,92],ubuntu:[17,92,40],becom:[56,29,34],sinc:[68,60,34,22,14,63],convert:75,setupobjecttransf:63,larger:[57,34],id_2:85,customhead:[],cert:20,id_1:85,implement:[85,42,57,77,56,90,91],chanc:41,mode_id:11,claim:[],appli:[26,41,97,5,20],foundat:[52,35],gatewai:67,expect:[56,70,77,86,41,63],egress:5,serverlist:[17,34],getus:[99,11],cloud:[],getothercredenti:11,collectionel:56,from:[],usb:83,commun:[26,35],accountsizeinbyt:[],next:[],websit:[],few:[11,17,7,77,18,47,2,69,97,32,26,83,59,92,70],camera:63,panel:11,remaind:41,sort:[65,57],localfilenam:[],new_contain:24,rare:56,account:[],scalabl:97,alic:[45,27],mycustomuserag:0,us2:[],control:[],sqlite:57,malform:[85,41],quickstart:32,tar:63,process:[58,17,96,61,65,3,30,69,24,41,92,63,64],high:[83,97],tag:[],tab:60,setexpir:[],serial:[83,50],launchconfigur:23,getwebooklist:45,a30b:[],listqueu:65,lamp:[39,40],port_range_min:5,versionlist:44,instead:[17,95,37,50],createcheck:52,delai:4,likewis:58,prikei:82,policyid:[33,45],abc3:5,getclientid:65,agentconnect:3,getstat:[65,23],physic:97,alloc:[7,29,13,67],essenti:60,backup:68,correspond:56,element:[68,61,56,67,13,46],issu:[99,28,78],allow:[],ingress:5,regionon:17,move:[26,56],securitygroup:[12,13],ord1:48,comma:75,getsourceip:48,usagerecord:58,ext4:3,ext3:34,curl_setopt:[],chosen:34,getokst:78,infrastructur:[3,52],heat_template_vers:40,myprefix:0,greater:[88,52,98,24,90,63],handl:[],auto:[],resourceiter:56,overal:[],dai:[85,60,78,73,41,14],auth:[],keepalivetimedout:58,getnotificationhistoryforcheck:78,jsonbodi:77,getclient:[],anyth:19,configurationid:29,mode:80,fiddli:56,ocj02rhipyyxypv9fhi:[],stock:[],subset:[57,63],bump:22,chunk:63,meta:[],"static":6,our:[71,28,17,77,26,34,3,92],special:[],out:[71,29,57,6,17,44,78,92,10,52,81,69,15,63,40],variabl:26,rel:[56,85,41,15],hardwar:[17,92,97],dhcp:[67,13],listsecuritygrouprul:5,defens:34,getstack:40,insid:[],liststack:40,setdefaultregion:11,nsrecord2:[],nsrecord1:[],organ:[2,32],dns2:60,getagentid:[3,37],fqdn:52,keep:[86,28,80,78,34],length:[65,90,85],cname:60,remotepath:[],retain:[65,63,0],getagentip:3,softwar:[87,52],listmemb:49,suffix:0,sshprivatekeyfilenam:[],scene:15,getnotificationplanid:30,echo:[71,52,3,85,57,58,6,60,78,30,88,65,10,14,92,63,56,11,17,95,19,34,48],exact:52,date:[],owner:[67,13,46],prioriti:[60,97],publickei:82,newus:11,system:[34,17,59,18,35,20,2,52,69,37,97,32,3,92,70,14,75,74],messag:[],tenantnam:17,attach:[],termin:[],"final":[26,29,63,27,78],udp:5,"51db7067821e727dc24df754":[],rsa:[],getapikei:11,accompani:77,arrayaccess:[56,91],exactli:[70,57],include_claim:[],"91de":5,githubusercont:[39,40],structur:[85,57,6,77,56,34,70,15,63],charact:[74,57,60,55,90,70,48,63,40],cloudserversopenstack:88,sens:71,bind:[60,30],exhibit:56,"function":[],"75906d20":13,beefi:15,generatetoken:77,have:[],snapshot_id:[],need:[71,49,47,61,2,24,26,59,27,74,28,29,75,57,7,60,51,92,82,32,83,64,69,35,98,56,89,91,14,15,63,70,72,17,93,18,19,68,97,34,22,23,40],billabl:58,buildinfo:1,inform:[],rout:67,rax_publ:[],flavorlist:[17,86,56,92],which:[],datacent:[11,35],singl:[],unless:[7,0],deploy:[18,61,39],who:[3,7,11,57,32],baseurl:56,callabl:[],persistencetyp:80,"9af5":66,segment:63,why:39,listimag:91,url:[],gather:[3,52,35],request:[],uri:85,getlaunchconfig:8,deni:9,snapshot:[],determin:[74,99,80,35,52,30,26,23,41,14,64],target_alia:52,constrain:5,fact:57,resourcemetadata:87,getregion:[77,88],verbos:[],getcountquota:57,anywai:63,metadataitem:76,setter:[99,91,11],redirect:26,disablelog:57,footbal:85,locat:[],should:[85,42,57,67,68,60,18,96,52,34,26,91,41,48,39,40],san_diego_vacation_video:[],local:[11,57,50,67,82,39,97,34,63,40],meant:[],recordid:98,insight:35,contribut:[],gettemporaryurl:6,mzaaaaa:[],bear:[11,57,63,6],autom:34,joint:[],jamie_keypair_1:82,jpg:71,gettimestamp:95,kong:[79,92],a80:[],httperror:24,enabl:[],loggerinterfac:42,possibl:[],glasgow:63,my_usernam:[],stuff:[56,37],pagerduti:78,partit:34,ascertain:24,agenttoken:3,view:[],getgroupconfig:8,seten:11,packet:[13,46],displai:71,volumeservic:[83,34],statu:[],correctli:[56,74],pattern:57,boundari:11,dlo:63,"1379cc8b":81,remotegroupprefix:5,progress:[17,68,92],email:[],agent_ip:3,kei:[],job:[56,69],entir:[17,35,9,68,81,37,34],agent_id:[3,37],"8ab8903ac7d8":23,swift:[],addit:[],getcontenttyp:63,admin:[67,57,11,13,46],equal:[90,5],etc:[15,63],instanc:[],grain:[14,9],disablecdnlog:75,comment:[90,60],connectfailur:58,guidelin:28,hyphen:[65,60],print_r:[17,65],chmod:[],respect:60,quit:56,yaml:[18,39,40],addition:[],httpurl:[],compos:[28,71,17,88,24,22,92],incomingtransf:58,compon:[71,18],json:[],getlabel:[3,48,30,37,78],xvhdd:19,twogbflavor:[17,92],immedi:[17,85,41],xlsx:63,adob:[],updated_at:15,togeth:[24,57],present:52,datastoreid:44,multi:[],databaseservic:97,countabl:56,vanilla:[],configurationlist:81,rate_limit:10,defin:[],"5cadc0e0b3c5":[17,92],retent:11,networkid:[67,13,46],layer:[3,7,71,20],domainid:[60,11,98],file:[],demo:[],non:[85,11,57,52,80,34,91,63],archiv:[],savemetadata:[65,57,63],incom:[26,74,5,32],maxent:23,batchlimit:24,refetch:75,cross:24,member:[],python:[],guzzlehttpexceptionbadresponseexcept:[],difficult:[],getagenttoken:3,http:[],hostnam:[52,29,98],cdnservic:75,effect:[17,97,92,50],"5xx":71,volume_id:[21,19],collat:[55,57],"__dir__":[50,39,40],off:[52,50,16,74],getchangelog:73,firstli:34,well:[17,60,61,16,74],phar:[],versionid:44,command:22,english:[57,63],audio:[],latest:[28,63],newest:41,less:[52,90,5,83],obtain:[],privateurl:[24,77],"_dynam":[],getcontentlength:63,web:[78,35,20,2,52,37,16,74],f0ac4394:13,typeid:78,domain_record_limit:10,getag:[3,85],fopen:63,utf8_general_ci:[55,81],keepalive_timeout:58,add:[],smart:[],deleteobject:57,match:[63,37,5],gmt:63,networkingservic:[7,67,12,13,5,46],piec:[52,35],mzlon:52,critical_st:78,know:[71,49,17,92,53,34,70,15],password:[],associ:[40,29,11,74,58,46,7,96,35,67,37,12,13,21,93,99,41,27,5,64],insert:[80,85,15],resid:[3,74,35,34],like:[24,25,26,4,28,29,75,57,58,6,59,60,78,62,80,40,9,56,52,15,16,76,43,68,93,94,96,20],success:[78,88],getcdnssluri:75,adminstateup:[13,46],necessari:[75,88,63],lose:41,resiz:[],page:[],createsubnet:67,exceed:58,captur:68,tenantid:[70,49,17,7,18,47,2,67,69,13,97,32,83,59,46],home:[57,63],transport:71,tmp:63,avoid:41,octet:13,createwebhook:45,leav:[27,5,92],delimet:75,setmetadata:63,getnam:[77,78,62,65,88,99,14,63],dcf:34,"enum":[93,96,15,49],usag:[],symlink:[],aaaab3nzac1yc2eaaaadaqabaaaagqdx8nkqv:[],host:[],getstream:[],although:[24,91,63],expiri:77,jsonstr:[],about:[],actual:[3,85,63,19],column:60,to_do_list:63,dbinstanc:[],constructor:42,getdomainid:11,disabl:[],own:[42,49,67,13,91,41,15,46],allhead:63,enablecdn:[75,6],ptrrecord:90,objectnam:[],nexthop:67,creatememb:49,automat:[11,69,19,65,82,13,97,34,88,63],due:57,jamie_macbook:[],getqueu:[65,85,41],getmessag:[85,39],merg:[65,63],"8fab2d22224c":[67,13],createsymlinkto:[],transfer:[24,94,63,58],addnod:[29,96],min20:14,much:[17,92],"var":[3,1,52,93,25,26,4,85,75,58,77,80,81,5,8,40,9,65,12,13,63,66,67,44,96,20,46,34,87,36,23,88],deliveri:[],brand:[8,37],subscrib:[24,71],getent:[30,95,14,37,78],serveronenod:26,getcatalog:[17,88],bug:28,count:[],made:[87,49,50,32],whether:[85,11,6,78,88,65,67,46,41,40],"483e":13,strpo:[17,92],getwebhook:45,troubl:60,"056d":[],record:[],below:[29,68,44,96,79,52,81,98,26],limit:[],uploadobject:[63,6],otherwis:34,problem:[28,71],quickli:41,formpost:57,"int":[56,63],dure:[29,41,37],additionalproperti:15,"41b9":[67,13],customhttphead:[],mountpoint:19,unpartit:34,ba8be283dbc3:13,probabl:[],"848a":[],mutual:52,a522:5,boot:[17,49],detail:[],virtual:[],"4c5e28f0":[],other:[],bool:[60,30,34],rememb:[60,96],varieti:[85,78],ntcccc:78,templateurl:[39,40],"07c9cae7d729":66,hascontentcach:16,stat:[],"class":[],accomplish:52,setbytesquota:57,"605e13f6":[],"24t17":34,rule:[],eol:22,portion:2,status:[78,73],eot:60},objtypes:{"0":"php:function"},objnames:{"0":["php","function","PHP function"]},filenames:["http-clients","services/orchestration/build-info","services/object-store/index","services/monitoring/agents","services/load-balancer/monitors","services/networking/security-group-rules","services/object-store/access","services/networking/index","services/autoscale/group-config","services/load-balancer/access","services/dns/limits","services/identity/users","services/networking/security-groups","services/networking/ports","services/monitoring/metrics","services/image/schemas","services/load-balancer/caching","getting-started-with-openstack","services/orchestration/index","services/volume/volumes","services/load-balancer/ssl","services/volume/snapshots","using-php-5.3","services/autoscale/groups","services/object-store/migrating-containers","services/load-balancer/errors","services/load-balancer/load-balancer","services/database/users","index","services/database/instances","services/monitoring/alarms","url-types","services/identity/index","services/autoscale/policies","services/compute/servers","services/monitoring/index","services/orchestration/resource-types","services/monitoring/entities","services/object-store/account","services/orchestration/templates","services/orchestration/stacks","services/queues/claims","logging","services/load-balancer/lb-setup.sample","services/database/datastores","services/autoscale/webhooks","services/networking/networks","services/common/clients.sample","services/monitoring/zones","services/image/sharing","caching-creds","services/image/tags","services/monitoring/checks","services/volume/volume-types","services/object-store/rs-only","services/database/databases","iterators","services/object-store/containers","services/load-balancer/stats","services/compute/index","services/dns/domains","services/autoscale/index","services/identity/tenants","services/object-store/objects","services/dns/index","services/queues/queues","services/orchestration/events","services/networking/subnets","services/compute/images","services/queues/index","services/image/index","debugging","services/common/rs-only.sample","services/monitoring/changelogs","services/load-balancer/index","services/object-store/cdn","services/load-balancer/metadata","services/identity/tokens","services/monitoring/notifications","regions","services/load-balancer/sessions","services/database/configurations","services/compute/keypairs","services/volume/index","services/common/service-args","services/queues/messages","services/compute/flavors","services/orchestration/resources","auth","services/common/rs-client","services/dns/reverse-dns","services/image/images","getting-started-with-rackspace","services/load-balancer/virtual-ips","services/load-balancer/logging","services/monitoring/views","services/load-balancer/nodes","services/database/index","services/dns/records","services/identity/roles"],titles:["HTTP Clients","Build info","Object Store v1","Agents","Health Monitors","Security Group Rules","Temporary URLs","Networking v2","Group configurations","Allowed Domains","Limits","Users","Security Groups","Ports"," Metrics","JSON schemas","Content Caching","Getting Started with OpenStack","Orchestration v1","Volumes","SSL Termination","Snapshots","Using the SDK with PHP v5.3","Groups","Migrating containers across regions","Error Pages","Load Balancer","Users","Welcome to php-opencloud!","Instances","Alarms","URL types","Identity v2","Scaling Policies","Servers","Monitoring v1","Resource types"," Entities","Account Details","Templates","Stacks","Claims","Logging","Setup","Datastores","Webhooks","Networks","Setup","Zones","Sharing images","Caching credentials","Image tags","Checks","Volume Types","<no title>","Databases","Iterators","Containers","Statistics and Usage Reports","Compute v2","Domains","Auto Scale v2","Tenants","Objects","DNS v1","Queues","Stack resource events","Subnets","Images","Queues v1","Images v1","Debugging","Setup","Changelogs","Load Balancer v1","CDN Containers","Metadata","Tokens","Notifications","Rackspace regions","Session Persistence","Configurations","Keypairs","Volumes v1","<no title>","Messages","Flavors","Stack resources","Authentication","<no title>","Reverse DNS","Images","Getting Started with Rackspace","Virtual IPs","Connection Logging","Views","Nodes","Databases v1","Records","Roles"],objects:{"":{cloneDomain:[60,0,1,""],addNodes:[96,0,1,""]}},titleterms:{all:[57,48,45,95,78,10,52,38,23,14,33],concept:[],queri:[10,41,98],global:99,code:[],ptr:90,hierarch:[],zone:48,send:[52,78],granular:14,under:63,webhook:45,volum:[83,29,53,19,34],veri:56,list:[49,52,53,93,62,26,75,57,3,60,78,55,65,80,81,30,63,82,40,98,9,86,87,66,36,13,90,91,14,5,76,10,11,67,68,44,95,96,19,46,21,34,99,12,23,48],upload:[82,63],iter:56,item:[78,9],small:[],sync:57,pass:[17,92],further:[70,74,7,18,35,61,2,69,97,32,83,59,64],port:13,what:[17,92],current:23,delet:[49,78,52,25,55,27,4,29,57,60,51,81,30,82,33,40,98,85,65,12,37,90,91,63,11,67,68,45,19,20,46,21,34,99,23,13],version:44,"new":[29,45,85,82,55,23,33,63],method:[99,11,62],metadata:[76,6,65,87,63,57],"5gb":63,gener:82,behaviour:56,glossari:[70,74,7,18,35,61,2,69,97,32,83,59,64],address:[11,34],modifi:[76,60,96,98,90,63],wait:29,checksum:63,step:[17,92],queue:[65,69],pick:[17,92],chang:60,revok:77,vip:93,api:[11,15],instal:[17,28,92,71],total:[57,38],select:[17,92],from:[19,9,98,15,39,40],describ:53,two:[],next:[17,92],websit:[],preview:40,type:[78,10,52,53,36,31,15,63],more:17,notif:78,about:[3,52,68,48],agent:[3,0],particular:78,cach:[50,16],account:38,retriev:[29,11,57,58,68,44,38,65,52,81,75,30,34,3,23,14,4],hour:14,setup:[72,49,59,61,2,24,93,25,3,27,4,85,75,76,58,7,51,55,80,30,63,32,8,83,33,74,64,69,35,9,98,38,14,92,16,70,43,17,78,45,18,96,20,97,47,41,94],work:[],histori:78,abandon:40,root:27,fetch:14,control:[],claim:41,stream:75,give:[],share:49,templat:[36,39,40],tag:51,want:[17,92],multipl:[67,13,63,46],secur:[12,5],anoth:[],purg:75,config:[],updat:[49,52,26,4,29,57,3,78,81,30,33,40,65,37,91,63,11,67,45,20,46,34,41,13],resourc:[56,87,66,36],dive:[17,92],befor:[],catalog:[77,88],date:63,datastor:44,data:14,orchestr:18,credenti:[17,11,92,50],inform:3,allow:9,help:28,over:63,through:[],ttl:[],paramet:[85,60,98,78,52,34,41],group:[8,23,12,5],monitor:[35,4],polici:33,requir:24,persist:80,"return":[],handl:71,auto:61,detach:19,introduct:[],name:[57,63,98],changelog:73,edit:8,revers:90,authent:[77,88],token:[3,77],each:63,debug:71,cloudfil:[],reset:11,domain:[60,9],replac:81,individu:[],keypair:[82,34],connect:[3,29,94],patch:[81,15],extract:63,event:[66,96],subnet:67,network:[7,46,9],content:[63,25,16],health:4,internet:[],clone:60,statist:58,insid:57,workflow:49,migrat:24,quick:[17,92],releas:41,"byte":[57,38],tenant:[77,62],launch:8,filter:[65,57,68,60,86,34],pagin:56,perman:[],oper:[70,74,7,18,35,61,2,69,97,32,83,59,75,64],number:14,bootabl:34,internalurl:31,size:63,given:[],interact:77,messag:[85,41],attach:19,termin:20,store:2,schema:[91,15],option:[24,52,56],"public":[],copi:63,specifi:14,loadbalanc:[],serv:[],target:3,remot:52,remov:[26,93,96,76,9],balanc:[26,29,74],deliveri:57,comput:59,ram:29,expir:14,have:78,tabl:[],destroi:77,mid:[],note:[65,56,91,49],also:[],client:[17,65,92,71,0],build:[17,29,1,92],indic:[],singl:[63,85,21,19],usernam:11,object:[11,57,62,2,75,38,99,63],quota:57,discov:78,plan:78,"class":[56,91],url:[75,6,31,34,39,40],doc:[],alarm:[30,78],adopt:40,thunderbird:[17,92],snapshot:21,cdn:[75,6],session:[80,77],find:[65,52,60,98],absolut:10,locat:63,explain:24,configur:[94,20,80,81,8,16],folder:[],info:1,contribut:28,get:[1,3,26,85,57,60,78,8,33,40,98,86,87,66,12,13,90,91,92,63,65,11,67,17,93,45,19,46,21,34,99,36,23,48],ssl:[75,20],report:58,restart:29,enabl:[80,94,75,27,16],across:24,common:56,contain:[24,75,57,63,38],view:[73,95,96,9,20,25,38],set:[56,85,25,6],result:[86,68],respons:15,statu:49,wire:71,kei:[11,6],databas:[55,97],state:23,"import":[56,60],publicurl:31,email:11,attribut:[52,37,34],parent:63,swift:71,addit:49,last:63,plugin:71,region:[24,79],tracerout:48,instanc:[17,29,81,92],load:[26,29,74],point:14,instanti:[],period:14,header:0,typic:49,guid:[],rackspac:[79,7,18,47,92,2,69,97,59,83,70,32],json:15,basic:[],strategi:71,imag:[49,17,51,68,34,91,70,92],resolut:14,bulk:[],ident:32,servic:[28,70,74,17,7,77,18,96,35,88,61,2,69,97,32,83,59,92,64],properti:[99,11,62],batch:[85,63],defin:[],error:25,fun:17,metric:[3,14],site:6,archiv:63,welcom:28,perform:48,member:49,html:6,document:[],complet:[],http:0,retriv:37,temporari:6,user:[99,77,11,27,0],php:[22,28],stack:[87,66,40],person:34,exampl:[71,15,50],thi:[],filesystem:50,entiti:37,model:[],protocol:26,execut:33,obtain:[],openstack:[70,17,7,18,47,2,69,97,32,83,59],flavor:[17,86,92],except:71,add:[71,76,93,96,51,9,98,99,90],valid:39,logger:42,which:78,format:[],password:11,specif:[10,85],server:[17,92,19,34],collect:[56,57],resiz:29,page:25,opencloud:28,creation:[],some:[17,3,92],sampl:[],scale:[23,33,61],larg:[57,63],inject:42,condit:63,refer:[],usag:[28,58],symlink:[],host:[3,6],prerequisit:[],post:85,paginatediter:56,disabl:[80,94,75,16],your:[17,71,92],log:[71,94,75,42,57],support:28,nova:[17,92],custom:25,start:[17,92],ipv4:93,ipv6:93,"function":0,cloud:[],link:[70,74,7,18,35,61,2,69,97,32,83,59,64],sdk:[17,22,92],count:[57,38],possibl:[52,78],"default":0,access:[57,9,34],record:[90,98],limit:10,"export":60,creat:[49,67,26,55,27,29,57,3,6,60,78,81,30,63,33,40,65,12,13,5,11,52,45,19,46,21,34,23,77,37],request:63,deep:[17,92],autoscal:[],intro:[],exist:[93,78,65,52,82,33,63],file:[40,63,39,34],check:[94,78,65,52,16,27],tip:28,detail:[65,52,68,19,86,26,21,38,3,91,48,4],virtual:93,other:0,role:99,test:[52,78],you:[17,92],node:96,stat:[65,58],meaning:71,algorithm:26,descript:[],pseudo:[],rule:5,fresh:[]}}) \ No newline at end of file diff --git a/doc/_build/html/services/autoscale/group-config.html b/doc/_build/html/services/autoscale/group-config.html new file mode 100644 index 000000000..a4b5ebbaf --- /dev/null +++ b/doc/_build/html/services/autoscale/group-config.html @@ -0,0 +1,343 @@ + + + + + + + + + + Group configurations — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $group = $service->group('{groupId}');
      +
      +
      +
      +
      +

      Get group configuration

      +
      /** @var  */
      +$groupConfig = $group->getGroupConfig();
      +
      +
      +
      +
      +

      Edit group configuration

      +
      $groupConfig->update(array(
      +    'name' => 'New name!'
      +));
      +
      +
      +
      +
      +

      Get launch configuration

      +
      /** @var */
      +$launchConfig = $group->getLaunchConfig();
      +
      +
      +
      +
      +

      Edit group/launch configuration

      +
      $launchConfig = $group->getLaunchConfig();
      +
      +$server = $launchConfig->args->server;
      +$server->name = "BRAND NEW SERVER NAME";
      +
      +$launchConfig->update(array
      +    'args' => array(
      +        'server' => $server,
      +        'loadBalancers' => $launchConfig->args->loadBalancers
      +    )
      +));
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/autoscale/groups.html b/doc/_build/html/services/autoscale/groups.html new file mode 100644 index 000000000..e1f771595 --- /dev/null +++ b/doc/_build/html/services/autoscale/groups.html @@ -0,0 +1,367 @@ + + + + + + + + + + Groups — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Groups

      +
      +

      List all groups

      +
      $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

      +
      $group = $service->group('{groupId}');
      +
      +
      +
      +
      +

      Create a new group

      +
      // 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

      +
      $group->delete();
      +
      +
      +
      +
      +

      Get the current state of the scaling group

      +
      $group->getState();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/autoscale/index.html b/doc/_build/html/services/autoscale/index.html new file mode 100644 index 000000000..86e99d2d9 --- /dev/null +++ b/doc/_build/html/services/autoscale/index.html @@ -0,0 +1,409 @@ + + + + + + + + + + Auto Scale v2 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Auto Scale v2

      +
      +

      Note

      +

      This service is only available for Rackspace users.

      +
      +
      +

      Setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +

      Auto Scale service

      +

      Now to instantiate the Auto Scale service:

      +
      $service = $client->autoscaleService();
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/autoscale/policies.html b/doc/_build/html/services/autoscale/policies.html new file mode 100644 index 000000000..ac077aeb3 --- /dev/null +++ b/doc/_build/html/services/autoscale/policies.html @@ -0,0 +1,361 @@ + + + + + + + + + + Scaling Policies — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $group = $service->group('{groupId}');
      +
      +
      +
      +
      +

      Get all policies

      +
      $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.

      +
      $policies = array(
      +  array(
      +    'name'     => 'NEW NAME',
      +    'change'   => 1,
      +    'cooldown' => 150,
      +    'type'     => 'webhook',
      +  )
      +);
      +
      +$group->createScalingPolicies($policies);
      +
      +
      +
      +
      +

      Get an existing scaling policy

      +
      $policy = $group->getScalingPolicy('{policyId}');
      +
      +
      +
      +
      +

      Update a scaling policy

      +
      $policy = $group->getScalingPolicy('{policyId}');
      +$policy->update(array(
      +    'name' => 'More relevant name'
      +));
      +
      +
      +
      +
      +

      Delete a scaling policy

      +
      $policy = $group->getScalingPolicy('{policyId}');
      +$policy->delete();
      +
      +
      +
      +
      +

      Execute a scaling policy

      +
      $policy = $group->getScalingPolicy('{policyId}');
      +$policy->execute();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/autoscale/service.sample.html b/doc/_build/html/services/autoscale/service.sample.html new file mode 100644 index 000000000..c8f23803f --- /dev/null +++ b/doc/_build/html/services/autoscale/service.sample.html @@ -0,0 +1,211 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +

      The first thing to do is pass in your credentials and instantiate a Rackspace +client:

      +
      <?php
      +
      +require 'vendor/autoload.php';
      +
      +use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +

      Now, set up the Auto Scale service:

      +
      $service = $client->autoscaleService();
      +
      +
      +

      {catalogName} is the name of the service, as it appears in the service +catalog. For Rackspace users, a default will be provided if you pass null +in for this argument. For OpenStack users, you cannot do this: you must instead +set your own value since it can depend on your environment setup.

      +

      {region} is the Compute 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 what endpoints your +catalog provides. For Rackspace, you may use either internalURL or +publicURL. The former will execute HTTP transactions over the internal +network configured for your service, possibly reducing latency and the overall +bandwidth cost - the caveat is that all of your resources must be in same region. +publicURL, however, which is the default, will operate over the public +Internet and is to be used for multi-region installations.

      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/autoscale/webhooks.html b/doc/_build/html/services/autoscale/webhooks.html new file mode 100644 index 000000000..dd7326134 --- /dev/null +++ b/doc/_build/html/services/autoscale/webhooks.html @@ -0,0 +1,345 @@ + + + + + + + + + + Webhooks — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Webhooks

      +
      +

      Setup

      +

      In order to interact with webhooks, you must first retrieve the +details of the group and scaling policy you want to execute:

      +
      $group = $service->group('{groupId}');
      +$policy = $group->getScalingPolicy('{policyId}');
      +
      +
      +
      +
      +

      Get all webhooks

      +
      $webhooks = $policy->getWebookList();
      +
      +
      +
      +
      +

      Create a new webhook

      +
      $policy->createWebhooks(array(
      +    array(
      +        'name' => 'Alice',
      +        'metadata' => array(
      +            'firstKey'  => 'foo',
      +            'secondKey' => 'bar'
      +        )
      +    )
      +));
      +
      +
      +
      +
      +

      Get webhook

      +
      $webhook = $policy->getWebhook('{webhookId}');
      +
      +
      +
      +
      +

      Update webhook

      +
      // Update the metadata
      +$metadata = $webhook->metadata;
      +$metadata->thirdKey = 'blah';
      +$webhook->update(array(
      +    'metadata' => $metadata
      +));
      +
      +
      +
      +
      +

      Delete webhook

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/common/clients.sample.html b/doc/_build/html/services/common/clients.sample.html new file mode 100644 index 000000000..115c25c90 --- /dev/null +++ b/doc/_build/html/services/common/clients.sample.html @@ -0,0 +1,307 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/common/os-client.sample.html b/doc/_build/html/services/common/os-client.sample.html new file mode 100644 index 000000000..cdc1a064c --- /dev/null +++ b/doc/_build/html/services/common/os-client.sample.html @@ -0,0 +1,237 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +

      or if you’re an OpenStack user:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/common/rs-client.html b/doc/_build/html/services/common/rs-client.html new file mode 100644 index 000000000..3d0e9414e --- /dev/null +++ b/doc/_build/html/services/common/rs-client.html @@ -0,0 +1,289 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/common/rs-client.sample.html b/doc/_build/html/services/common/rs-client.sample.html new file mode 100644 index 000000000..7441fc667 --- /dev/null +++ b/doc/_build/html/services/common/rs-client.sample.html @@ -0,0 +1,254 @@ + + + + + + + + + + Rackspace setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/common/rs-only.sample.html b/doc/_build/html/services/common/rs-only.sample.html new file mode 100644 index 000000000..2f30d54aa --- /dev/null +++ b/doc/_build/html/services/common/rs-only.sample.html @@ -0,0 +1,296 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Note

      +

      This service is only available for Rackspace users.

      +
      +
      +

      Setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/common/service-args.html b/doc/_build/html/services/common/service-args.html new file mode 100644 index 000000000..aebe9a3d7 --- /dev/null +++ b/doc/_build/html/services/common/service-args.html @@ -0,0 +1,289 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
        +
      • {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.
      • +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/Images.md.html b/doc/_build/html/services/compute/Images.md.html new file mode 100644 index 000000000..42f5c5717 --- /dev/null +++ b/doc/_build/html/services/compute/Images.md.html @@ -0,0 +1,253 @@ + + + + + + + + + + Compute Images — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Compute Images

      +
      +

      Intro

      +

      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.

      +

      In addition to creating images manually, you can also schedule images of +your server automatically. Please consult the official +docs +for more information about this extension, including enabling and +disabling scheduled images and showing scheduled images.

      +

      With standard servers, the entire disk (OS and data) is captured in the +image. With Performance servers, only the system 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.

      +
      +
      +

      Setup

      +

      You first need to setup a Compute service. For information, please +consult the Compute service documentation.

      +
      +
      +

      List images

      +
      $images = $service->imageList();
      +
      +foreach ($images as $image) {
      +
      +}
      +
      +
      +

      For more information about iterators, +please consult the official documentation.

      +
      +

      Query parameters

      +

      You can also refine the list of images returned by providing specific +URL parameters:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Field nameDescription
      serverFilters the list of images by server. Specify the server reference by ID or by full URL.
      nameFilters the list of images by image name.
      statusFilters 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-sinceFilters the list of images to those that have changed since the changes-since time. See the official docs for more information.
      markerThe ID of the last item in the previous list. See the official docs for more information.
      limitSets the page size. See the official docs for more information.
      typeFilters base Rackspace images or any custom server images that you have created. Can either be BASE or SNAPSHOT.
      +
      +
      +

      Example

      +

      You can return more information about each image by setting the +$details argument to true. The second argument can be an array +of query parameters:

      +
      use OpenCloud\Compute\Constants\ImageState;
      +
      +$list = $service->imageList(true, array(
      +    'server' => 'fooBar',
      +    'status' => ImageState::ACTIVE
      +));
      +
      +
      +
      +
      +
      +

      Get an image

      +
      $imageId = '3afe97b2-26dc-49c5-a2cc-a2fc8d80c001';
      +$image = $service->image($imageId);
      +
      +
      +
      +
      +

      Delete an image

      +
      $image->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/Keypair.md.html b/doc/_build/html/services/compute/Keypair.md.html new file mode 100644 index 000000000..4ccc67499 --- /dev/null +++ b/doc/_build/html/services/compute/Keypair.md.html @@ -0,0 +1,242 @@ + + + + + + + + + + Keypairs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Keypairs

      +
      +

      Generate new keypair

      +

      This operation creates a new keypair under a provided name; the public +key value is automatically generated for you.

      +
      $keypair = $service->keypair();
      +
      +$keypair->create(array(
      +   'name' => 'jamie_keypair_1'
      +));
      +
      +echo $keypair->getPublicKey();
      +
      +// Save private key to a file so you can use it to SSH into
      +// your server later.
      +$sshPrivateKeyFilename = 'jamie_keypair_1_rsa';
      +$privateKey = $keypair->getPrivateKey();
      +file_put_contents($sshPrivateKeyFilename, $privateKey);
      +chmod($sshPrivateKeyFilename, 0600);
      +
      +
      +
      +
      +

      Upload existing keypair

      +

      This operation creates a new keypair under a provided name using a +provided public key value. This public key will probably exist on your +local filesystem, and so provide easy access to your server when +uploaded.

      +
      $keypair = $service->keypair();
      +
      +$key = <<<EOT
      +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Example public key
      +EOT;
      +
      +$keypair->create(array(
      +   'name'      => 'jamie_macbook',
      +   'publicKey' => $key
      +));
      +
      +
      +
      +
      +

      List keypairs

      +

      To list all existing keypairs:

      +
      $keys = $service->listKeypairs();
      +
      +foreach ($keys as $key) {
      +   // ...
      +}
      +
      +
      +

      For more information about iterators, please see the +docs.

      +
      +
      +

      Delete keypairs

      +

      To delete a specific keypair:

      +
      $keypair->delete();
      +
      +
      +
      +
      +

      Creating a server with a keypair

      +

      In order to spawn 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:

      +
      use Guzzle\Http\Exception\BadResponseException;
      +use OpenCloud\Compute\Constants\Network;
      +
      +$server = $compute->server();
      +
      +try {
      +    $response = $server->create(array(
      +        'name'     => 'New server',
      +        'image'    => $ubuntuImage,
      +        'flavor'   => $twoGbFlavor,
      +        'networks' => array(
      +            $compute->network(Network::RAX_PUBLIC),
      +            $compute->network(Network::RAX_PRIVATE)
      +        ),
      +        'keypair' => 'jamie_macbook'
      +    ));
      +} catch (BadResponseException $e) {
      +   // error...
      +}
      +
      +
      +

      So, as you can see, you specify the name of an existing keypair that +you previously created on the API.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/Server.md.html b/doc/_build/html/services/compute/Server.md.html new file mode 100644 index 000000000..f6faa48b9 --- /dev/null +++ b/doc/_build/html/services/compute/Server.md.html @@ -0,0 +1,447 @@ + + + + + + + + + + Servers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Servers

      +
      +

      Intro

      +

      A server is a virtual machine instance in the Cloud Servers environment.

      +
      +
      +

      Setup

      +

      Server objects are instantiated from the Compute service. For more +details, see the Service docs.

      +
      +
      +

      Get server

      +

      The easiest way to retrieve a specific server is by its unique ID:

      +
      $serverId = 'ef08aa7a-b5e4-4bb8-86df-5ac56230f841';
      +$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.

      +
      // overview
      +$servers = $service->serverList();
      +
      +// detailed
      +$servers = $service->serverList(true);
      +
      +
      +
      +

      URL parameters for filtering servers

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionType
      imageThe image IDstring
      flavorThe flavor IDstring
      nameThe server namestring
      statusThe 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\ServerStatestring
      changes-sinceValue for checking for changes since a previous requestA valid ISO 8601 dateTime (2011-01-24T17:08Z)
      RAX-SI:image_scheduleIf 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

      +

      There are a few parameter requirements when creating a server using an +image:

      +
        +
      • name - needs to be a string;
      • +
      • flavor - a OpenCloud\Compute\Resource\Flavor object, that is +populated with the values of a real API flavor;
      • +
      • image - a OpenCloud\Compute\Resource\Image object, that is +populated with the values of a real API image;
      • +
      +

      Firstly we need to find our flavor and image using their UUIDs. For more +information about these concepts, including how to find flavor/image +UUIDs, please consult §§ 3-4 in the Getting Started +guide.

      +
      $ubuntuImage = $compute->image('868a0966-0553-42fe-b8b3-5cadc0e0b3c5');
      +$twoGbFlavor = $compute->flavor('4');
      +
      +
      +

      Now we’re ready to create our instance:

      +
      use OpenCloud\Compute\Constants\Network;
      +
      +$server = $compute->server();
      +
      +try {
      +    $response = $server->create(array(
      +        'name'     => 'My lovely server',
      +        'image'    => $ubuntuImage,
      +        'flavor'   => $twoGbFlavor
      +    ));
      +} catch (\Guzzle\Http\Exception\BadResponseException $e) {
      +
      +    // No! Something failed. Let's find out:
      +    $responseBody = (string) $e->getResponse()->getBody();
      +    $statusCode   = $e->getResponse()->getStatusCode();
      +    $headers      = $e->getResponse()->getHeaderLines();
      +
      +    echo sprintf('Status: %s\nBody: %s\nHeaders: %s', $statusCode, $responseBody, implode(', ', $headers);
      +}
      +
      +
      +

      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

      +

      There are a few parameter requirements when creating a server using a +bootable volume:

      +
        +
      • name - needs to be a string;
      • +
      • flavor - a OpenCloud\Compute\Resource\Flavor object, that is +populated with the values of a real API flavor;
      • +
      • volume - a OpenCloud\Volume\Resource\Volume object, that is +populated with the values of a real API volume;
      • +
      +

      Firstly we need to find our flavor and volume using their IDs.

      +
      $volumeService = $client->volumeService();
      +$bootableVolume = $volumeService->volume('<ID OF A BOOTABLE VOLUME>');
      +$flavor = $compute->flavor('<ID OF A FLAVOR>');
      +
      +
      +

      Now we’re ready to create our instance:

      +
      use OpenCloud\Compute\Constants\Network;
      +
      +$server = $compute->server();
      +
      +try {
      +    $response = $server->create(array(
      +        'name'     => 'My lovely server',
      +        'volume'   => $bootableVolume,
      +        'flavor'   => $flavor
      +    ));
      +} catch (\Guzzle\Http\Exception\BadResponseException $e) {
      +    // No! Something failed. Let's find out:
      +    echo $e->getRequest() . PHP_EOL . PHP_EOL;
      +    echo $e->getResponse();
      +}
      +
      +
      +

      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

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionTypeRequired
      nameThe 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.stringYes
      flavorA populated OpenCloud\Compute\Resource\Flavor object representing your chosen flavorobjectYes
      imageA populated OpenCloud\Compute\Resource\Image object representing your chosen imageobjectNo, if volume is specified
      volumeA populated OpenCloud\Volume\Resource\Volume object representing your chosen bootable volumeobjectNo, if image is specified
      volumeDeleteOnTerminationtrue if the bootable volume should be deleted when the server is terminated; false, otherwisebooleanNo; default = false
      OS-DCF:diskConfigThe 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.stringNo
      networksAn array of populated OpenCloud\Compute\Resource\Network objects that indicate which networks your instance resides in.arrayNo
      metadataAn array of arbitrary data (key-value pairs) that adds additional meaning to your server.arrayNo
      keypairYou can install a registered keypair onto your newly created instance, thereby providing scope for keypair-based authentication.arrayNo
      personalityFiles that you can upload to your newly created instance’s filesystem.arrayNo
      +
      +
      +

      Creating a server with keypairs

      +

      Please see the Keypair docs for more information.

      +
      +
      +

      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.

      +
      $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.

      +
      $server->update(array(
      +   'name' => 'NEW SERVER NAME'
      +));
      +
      +
      +
      +

      Updatable attributes

      + ++++ + + + + + + + + + + + + + + + + +
      namedescription
      nameThe 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.
      accessIPv4The IP version 4 address.
      accessIPv6The IP version 6 address.
      +
      +
      +
      +

      Delete server

      +
      $server->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/Service.md.html b/doc/_build/html/services/compute/Service.md.html new file mode 100644 index 000000000..99171c8e8 --- /dev/null +++ b/doc/_build/html/services/compute/Service.md.html @@ -0,0 +1,186 @@ + + + + + + + + + + Compute service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Compute service

      +
      +

      Setup

      +

      To instantiate a Compute service object, you first need to setup a +Rackspace/OpenStack client. To do this, or for more information, please +consult the Clients documentation.

      +
      $service = $client->computeService();
      +
      +
      +

      If no arguments are provided to the above method, certain values are set +to their default values:

      + ++++ + + + + + + + + + + + + + + + + +
      ParamDefault value
      $namecloudServersOpenStack
      $regionDFW
      $urltypepublicURL
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/flavors.html b/doc/_build/html/services/compute/flavors.html new file mode 100644 index 000000000..f2d579914 --- /dev/null +++ b/doc/_build/html/services/compute/flavors.html @@ -0,0 +1,358 @@ + + + + + + + + + + Flavors — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Flavors

      +
      +

      Get a flavor

      +
      $flavor = $service->flavor('{flavorId}');
      +
      +
      +
      +
      +

      List flavors

      +
      $flavors = $service->flavorList();
      +
      +foreach ($flavors as $flavor) {
      +    /** @param $flavor OpenCloud\Common\Resource\FlavorInterface */
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +

      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:

      +
      // Name and ID only
      +$compute->flavorList(false);
      +
      +
      +
      +
      +

      Filtering

      +

      You can also refine the list of images returned by providing specific filters:

      + ++++ + + + + + + + + + + + + + + + + + + + +
      Array keyDescription
      minDiskFilters the list of flavors to those with the specified minimum number of gigabytes of disk storage.
      minRamFilters the list of flavors to those with the specified minimum amount of RAM in megabytes.
      markerThe ID of the last item in the previous list. See the official docs for more information.
      limitSets 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:

      +
      $flavors = $service->flavorList(true, array('minRam' => 4));
      +
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/images.html b/doc/_build/html/services/compute/images.html new file mode 100644 index 000000000..cd8007d21 --- /dev/null +++ b/doc/_build/html/services/compute/images.html @@ -0,0 +1,380 @@ + + + + + + + + + + Images — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $images = $service->imageList();
      +
      +foreach ($images as $image) {
      +
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +

      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:

      +
      $images = $service->imageList(true);
      +
      +
      +
      +
      +

      Filtering

      +

      You can also refine the list of images returned by providing specific filters:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Array keyDescription
      serverFilters the list of images by server. Specify the server reference by ID or by full URL.
      nameFilters the list of images by image name.
      statusFilters 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-sinceFilters the list of images to those that have changed since the changes-since time. See the official docs for more information.
      markerThe ID of the last item in the previous list. See the official docs for more information.
      limitSets the page size. See the official docs for more information.
      typeFilters 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:

      +
      $images = $service->imageList(false, array('server' => '{serverId}'));
      +
      +
      +
      +
      +
      +

      Retrieve details about an image

      +
      $image = $service->image('{imageId}');
      +
      +
      +
      +
      +

      Delete an image

      +
      $image->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/index.html b/doc/_build/html/services/compute/index.html new file mode 100644 index 000000000..e508a4a4d --- /dev/null +++ b/doc/_build/html/services/compute/index.html @@ -0,0 +1,419 @@ + + + + + + + + + + Compute v2 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Compute v2

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Compute service

      +

      Now to instantiate the Compute service:

      +
      $service = $client->computeService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/keypair.html b/doc/_build/html/services/compute/keypair.html new file mode 100644 index 000000000..830311ef9 --- /dev/null +++ b/doc/_build/html/services/compute/keypair.html @@ -0,0 +1,246 @@ + + + + + + + + + + Keypairs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Keypairs

      +
      +

      Setup

      +

      The first thing to do is pass in your credentials and instantiate a Rackspace +client:

      +
      <?php
      +
      +require 'vendor/autoload.php';
      +
      +use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +

      Now, set up the Auto Scale service:

      +
      $service = $client->computeService('{catalogType}', '{region}', '{urlType}');
      +
      +
      +

      {catalogType} is the name of the service, as it appears in the service +catalog. For Rackspace users, this will default to cloudServersOpenStack; for +OpenStack users, you must set your own value since it can depend on your +environment setup.

      +

      {region} is the Compute 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 what endpoints your +catalog provides. For Rackspace, you may use either internalURL or publicURL. +The former will execute HTTP transactions over the internal Rackspace network, +reducing latency and the overall bandwidth cost - the caveat is that all of your +resources must be in same region. publicURL, however, which is the default, +will operate over the public Internet and is to be used for multi-region +installations.

      +
      +
      +

      Generate a new keypair

      +

      This operation creates a new keypair under a provided name; the public key +value is automatically generated for you.

      +
      // 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.

      +
      $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:

      +
      $keys = $service->listKeypairs();
      +
      +foreach ($keys as $key) {
      +
      +}
      +
      +
      +
      +
      +

      Delete keypairs

      +

      To delete a specific keypair:

      +
      $keypair->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/keypairs.html b/doc/_build/html/services/compute/keypairs.html new file mode 100644 index 000000000..c38987e1a --- /dev/null +++ b/doc/_build/html/services/compute/keypairs.html @@ -0,0 +1,351 @@ + + + + + + + + + + Keypairs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Keypairs

      +
      +

      Generate a new keypair

      +

      This operation creates a new keypair under a provided name; the public key +value is automatically generated for you.

      +
      // Instantiate empty object
      +$keypair = $service->keypair();
      +
      +// Send to API
      +$keypair->create(array(
      +   'name' => 'jamie_keypair_1'
      +));
      +
      +// Save these!
      +$pubKey = $keypair->getPublicKey();
      +$priKey = $keypair->getPrivateKey();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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.

      +
      $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
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      List keypairs

      +

      To list all existing keypairs:

      +
      $keys = $service->listKeypairs();
      +
      +foreach ($keys as $key) {
      +
      +}
      +
      +
      +
      +
      +

      Delete keypairs

      +

      To delete a specific keypair:

      +
      $keypair->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/server.html b/doc/_build/html/services/compute/server.html new file mode 100644 index 000000000..b77733469 --- /dev/null +++ b/doc/_build/html/services/compute/server.html @@ -0,0 +1,443 @@ + + + + + + + + + + Servers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Servers

      +
      +

      Setup

      +

      The first thing to do is pass in your credentials and instantiate a Rackspace +client:

      +
      <?php
      +
      +require 'vendor/autoload.php';
      +
      +use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +

      Now, set up the Auto Scale service:

      +
      $service = $client->computeService('{catalogType}', '{region}', '{urlType}');
      +
      +
      +

      {catalogType} is the name of the service, as it appears in the service +catalog. For Rackspace users, this will default to cloudServersOpenStack; for +OpenStack users, you must set your own value since it can depend on your +environment setup.

      +

      {region} is the Compute 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 what endpoints your +catalog provides. For Rackspace, you may use either internalURL or publicURL. +The former will execute HTTP transactions over the internal Rackspace network, +reducing latency and the overall bandwidth cost - the caveat is that all of your +resources must be in same region. publicURL, however, which is the default, +will operate over the public Internet and is to be used for multi-region +installations.

      +
      +
      +

      Get server

      +

      The easiest way to retrieve a specific server is by its unique ID:

      +
      $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.

      +
      // overview
      +$servers = $service->serverList();
      +
      +// detailed
      +$servers = $service->serverList(true);
      +
      +
      +
      +

      URL parameters for filtering servers

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionType
      imageThe image IDstring
      flavorThe flavor IDstring
      nameThe server namestring
      statusThe 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\ServerStatestring
      changes-sinceValue for checking for changes since a previous requestA valid ISO 8601 dateTime (2011-01-24T17:08Z)
      RAX-SI:image_scheduleIf 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:

      +
      $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.

      +
      $bootableVolume = $client->volumeService()->volume('{volumeId}');
      +
      +
      +

      Now we’re ready to create our instance:

      +
      $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

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionTypeRequired
      nameThe 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.stringYes
      flavorA populated OpenCloud\Compute\Resource\Flavor object representing your chosen flavorobjectYes
      imageA populated OpenCloud\Compute\Resource\Image object representing your chosen imageobjectNo, if volume is specified
      volumeA populated OpenCloud\Volume\Resource\Volume object representing your chosen bootable volumeobjectNo, if image is specified
      volumeDeleteOnTerminationtrue if the bootable volume should be deleted when the server is terminated; false, otherwisebooleanNo; default = false
      OS-DCF:diskConfigThe 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.stringNo
      networksAn array of populated OpenCloud\Compute\Resource\Network objects that indicate which networks your instance resides in.arrayNo
      metadataAn array of arbitrary data (key-value pairs) that adds additional meaning to your server.arrayNo
      keypairYou can install a registered keypair onto your newly created instance, thereby providing scope for keypair-based authentication.arrayNo
      personalityFiles that you can upload to your newly created instance’s filesystem.arrayNo
      +
      +
      +

      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:

      +
      $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.

      +
      $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.

      +
      $server->update(array(
      +   'name' => 'NEW SERVER NAME'
      +));
      +
      +
      +
      +

      Updatable attributes

      + ++++ + + + + + + + + + + + + + + + + +
      namedescription
      nameThe 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.
      accessIPv4The IP version 4 address.
      accessIPv6The IP version 6 address.
      +
      +
      +
      +

      Delete server

      +
      $server->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/servers.html b/doc/_build/html/services/compute/servers.html new file mode 100644 index 000000000..2f313f538 --- /dev/null +++ b/doc/_build/html/services/compute/servers.html @@ -0,0 +1,580 @@ + + + + + + + + + + Servers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Servers

      +
      +

      Get server

      +

      The easiest way to retrieve a specific server is by its unique ID:

      +
      $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.

      +
      // overview
      +$servers = $service->serverList();
      +
      +// detailed
      +$servers = $service->serverList(true);
      +
      +
      +
      +

      URL parameters for filtering servers

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionType
      imageThe image IDstring
      flavorThe flavor IDstring
      nameThe server namestring
      statusThe 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\ServerStatestring
      changes-sinceValue for checking for changes since a previous requestA valid ISO 8601 dateTime (2011-01-24T17:08Z)
      RAX-SI:image_scheduleIf 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
      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      Create server

      +
      +

      Using an image

      +

      Now we’re ready to create our instance:

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      Using a bootable volume

      +

      Firstly we need to find our volume using their IDs.

      +
      $bootableVolume = $client->volumeService()->volume('{volumeId}');
      +
      +
      +

      Now we’re ready to create our instance:

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      Create parameters

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionTypeRequired
      nameThe 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.stringYes
      flavorA populated OpenCloud\Compute\Resource\Flavor object representing your chosen flavorobjectYes
      imageA populated OpenCloud\Compute\Resource\Image object representing your chosen imageobjectNo, if volume is specified
      volumeA populated OpenCloud\Volume\Resource\Volume object representing your chosen bootable volumeobjectNo, if image is specified
      volumeDeleteOnTerminationtrue if the bootable volume should be deleted when the server is terminated; false, otherwisebooleanNo; default = false
      OS-DCF:diskConfigThe 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.stringNo
      networksAn array of populated OpenCloud\Compute\Resource\Network objects that indicate which networks your instance resides in.arrayNo
      metadataAn array of arbitrary data (key-value pairs) that adds additional meaning to your server.arrayNo
      keypairYou can install a registered keypair onto your newly created instance, thereby providing scope for keypair-based authentication.arrayNo
      personalityFiles that you can upload to your newly created instance’s filesystem.arrayNo
      +
      +
      +

      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:

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      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.

      +
      $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.

      +
      $server->update(array(
      +   'name' => 'NEW SERVER NAME'
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +

      Updatable attributes

      + ++++ + + + + + + + + + + + + + + + + +
      namedescription
      nameThe 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.
      accessIPv4The IP version 4 address.
      accessIPv6The IP version 6 address.
      +
      +
      +

      Updating the access IP address(es)

      +

      For example, you may have a private cloud with internal addresses in the +10.1.x range. However, you can access a server via a firewall device at +address 50.57.94.244. In this case, you can change the accessIPv4 +attribute to point to the firewall:

      +
      $server->update(array('accessIPv4' => '50.57.94.244'));
      +
      +
      +

      When a client application retrieves the server’s information, it will +know that it needs to use the accessIPv4 address to connect to the +server, and not the IP address assigned to one of the network +interfaces.

      +
      +
      +
      +

      Retrieving the server’s IP address

      +

      The Server::ip() method is used to retrieve the server’s IP address. +It has one optional parameter: the format (either IPv4 or IPv6) of the +address to return (by default, it returns the IPv4 address):

      +
      // IPv4
      +echo $server->ip();
      +echo $server->ip(4);
      +
      +// IPv6
      +echo $server->ip(6);
      +
      +
      +
      +
      +

      Delete server

      +
      $server->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/compute/service.sample.html b/doc/_build/html/services/compute/service.sample.html new file mode 100644 index 000000000..1eaec4bfc --- /dev/null +++ b/doc/_build/html/services/compute/service.sample.html @@ -0,0 +1,211 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +

      The first thing to do is pass in your credentials and instantiate a Rackspace +client:

      +
      <?php
      +
      +require 'vendor/autoload.php';
      +
      +use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +

      Now, set up the Auto Scale service:

      +
      $service = $client->computeService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +

      {catalogName} is the name of the service, as it appears in the service +catalog. For Rackspace users, a default will be provided if you pass null +in for this argument. For OpenStack users, you cannot do this: you must instead +set your own value since it can depend on your environment setup.

      +

      {region} is the Compute 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 what endpoints your +catalog provides. For Rackspace, you may use either internalURL or +publicURL. The former will execute HTTP transactions over the internal +network configured for your service, possibly reducing latency and the overall +bandwidth cost - the caveat is that all of your resources must be in same region. +publicURL, however, which is the default, will operate over the public +Internet and is to be used for multi-region installations.

      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/README.md.html b/doc/_build/html/services/database/README.md.html new file mode 100644 index 000000000..c08ebcfc7 --- /dev/null +++ b/doc/_build/html/services/database/README.md.html @@ -0,0 +1,274 @@ + + + + + + + + + + Databases — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Databases

      +

      A cloud database is a MySQL relational database service that allows +customers to programatically provision database instances of varying +virtual resource sizes without the need to maintain and/or update MySQL.

      +
      +

      Getting started

      +
      +

      1. Instantiate a Rackspace client.

      +
      use OpenCloud\Rackspace;
      +use OpenCloud\Common\Constants\State;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
      +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
      +));
      +
      +
      +
      +
      +

      2. Create a database server instance.

      +
      $databaseService = $client->databaseService('cloudDatabases', 'DFW');
      +
      +$twoGbFlavor = $databaseService->flavor(3);
      +
      +$dbInstance = $databaseService->instance();
      +$dbInstance->name = 'Demo database instance';
      +$dbInstance->volume = new stdClass();
      +$dbInstance->volume->size = 20; // GB
      +$dbInstance->flavor = $twoGbFlavor;
      +$dbInstance->create();
      +
      +$dbInstance->waitFor(State::ACTIVE, null, function ($dbInstance) {
      +
      +    printf("Database instance build status: %s\n", $dbInstance->status);
      +
      +});
      +
      +
      +

      The example above creates a database server instance with 20GB of disk +space and 2GB of memory, then waits for it to become ACTIVE.

      +
      +
      +

      3. Create a database on the database server instance.

      +
      $db = $dbInstance->database();
      +$db->name = 'demo_db';
      +
      +$db->create();
      +
      +
      +

      The example above creates a database named demo_db on the database +server instance created in the previous step.

      +
      +
      +

      4. Create database user and give it access to database.

      +
      $user = $dbInstance->user();
      +$user->name = 'demo_user';
      +$user->password = 'h@X0r!';
      +$user->databases = array('demo_db');
      +
      +$user->create();
      +
      +
      +

      The example above creates a database user named demo_user, sets its +password and gives it access to the demo_db database created in the +previous step.

      +
      +
      +

      5. Optional step: Create a load balancer to allow access to the database from the Internet.

      +

      The database 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.

      +
      $loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW');
      +
      +$loadBalancer = $loadBalancerService->loadBalancer();
      +
      +$loadBalancer->name = 'Load balancer - DB';
      +$loadBalancer->addNode($dbInstance->hostname, 3306);
      +$loadBalancer->port = 3306;
      +$loadBalancer->protocol = 'MYSQL';
      +$loadBalancer->addVirtualIp('PUBLIC');
      +
      +$loadBalancer->create();
      +
      +$loadBalancer->waitFor(State::ACTIVE, null, function ($lb) {
      +    printf("Load balancer build status: %s\n", $lb->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.

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/configurations.html b/doc/_build/html/services/database/configurations.html new file mode 100644 index 000000000..1771760cd --- /dev/null +++ b/doc/_build/html/services/database/configurations.html @@ -0,0 +1,381 @@ + + + + + + + + + + Configurations — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Configurations

      +
      +

      Creating a configuration

      +
      /** @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:

      +
      $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:

      +
      $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:

      + +

      some configuration parameters +* you can entirely replace a configuration to +replace all configuration parameters with new ones

      +
      +

      Patching a configuration

      +

      You can patch a configuration as shown below:

      +
      $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:

      +
      $configuration->update(array(
      +    'values' => array(
      +        'collation_server' => 'utf8_general_ci',
      +        'connect_timeout' => 60
      +    )
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      Deleting a configuration

      +
      $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:

      +
      $instances = $configuration->instanceList();
      +foreach ($instances as $instance) {
      +    /** @var $instance OpenCloud\Database\Resource\Instance **/
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/databases.html b/doc/_build/html/services/database/databases.html new file mode 100644 index 000000000..e9d9278bc --- /dev/null +++ b/doc/_build/html/services/database/databases.html @@ -0,0 +1,344 @@ + + + + + + + + + + Databases — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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:

      +
      // 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

      +
      $database->delete();
      +
      +
      +
      +

      Note

      +

      This is a destructive operation: all your data will be wiped away and will +not be retrievable.

      +
      +
      +
      +

      Listing databases

      +
      $databases = $service->databaseList();
      +
      +foreach ($databases as $database) {
      +    /** @param $database OpenCloud\Database\Resource\Database */
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/datastores.html b/doc/_build/html/services/database/datastores.html new file mode 100644 index 000000000..8a4033dfe --- /dev/null +++ b/doc/_build/html/services/database/datastores.html @@ -0,0 +1,338 @@ + + + + + + + + + + Datastores — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Datastores

      +
      +

      Listing datastores

      +

      You can list out all the datastores available as shown below:

      +
      $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:

      +
      /** @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:

      +
      $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:

      +
      $datastoreVersion = $datastore->version('{versionId}');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/index.html b/doc/_build/html/services/database/index.html new file mode 100644 index 000000000..4a34553a0 --- /dev/null +++ b/doc/_build/html/services/database/index.html @@ -0,0 +1,424 @@ + + + + + + + + + + Databases v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Databases v1

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Databases service

      +

      Now to instantiate the Databases service:

      +
      $service = $client->databaseService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/instances.html b/doc/_build/html/services/database/instances.html new file mode 100644 index 000000000..d4b28f840 --- /dev/null +++ b/doc/_build/html/services/database/instances.html @@ -0,0 +1,422 @@ + + + + + + + + + + Instances — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Instances

      +
      +

      Create a new instance

      +
      // 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:

      +
      $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.

      +
      $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

      +
      $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.

      +
      $instance->update(array(
      +    'configuration' => '{configurationId}'
      +));
      +
      +
      +
      +

      Note

      +

      If any parameters in the associated configuration require a restart, then you +will need to restart the instance after the update.

      +
      +
      +
      +

      Deleting an instance

      +
      $instance->delete();
      +
      +
      +
      +
      +

      Restarting an instance

      +
      $instance->restart();
      +
      +
      +
      +
      +

      Resizing an instance’s RAM

      +

      To change the amount of RAM allocated to the instance:

      +
      $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:

      +
      // Increase to 8GB disk
      +$instance->resizeVolume(8);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/service.sample.html b/doc/_build/html/services/database/service.sample.html new file mode 100644 index 000000000..578571553 --- /dev/null +++ b/doc/_build/html/services/database/service.sample.html @@ -0,0 +1,211 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +

      The first thing to do is pass in your credentials and instantiate a Rackspace +client:

      +
      <?php
      +
      +require 'vendor/autoload.php';
      +
      +use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +

      Now, set up the Database service:

      +
      $service = $client->databaseService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +

      {catalogName} is the name of the service, as it appears in the service +catalog. For Rackspace users, a default will be provided if you pass null +in for this argument. For OpenStack users, you cannot do this: you must instead +set your own value since it can depend on your environment setup.

      +

      {region} is the Compute 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 what endpoints your +catalog provides. For Rackspace, you may use either internalURL or +publicURL. The former will execute HTTP transactions over the internal +network configured for your service, possibly reducing latency and the overall +bandwidth cost - the caveat is that all of your resources must be in same region. +publicURL, however, which is the default, will operate over the public +Internet and is to be used for multi-region installations.

      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/database/users.html b/doc/_build/html/services/database/users.html new file mode 100644 index 000000000..c3bb667a6 --- /dev/null +++ b/doc/_build/html/services/database/users.html @@ -0,0 +1,347 @@ + + + + + + + + + + Users — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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.

      +
      // 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

      +
      $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:

      +
      $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

      +
      // true for yes, false for no
      +$instance->isRootEnabled();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/Domains.md.html b/doc/_build/html/services/dns/Domains.md.html new file mode 100644 index 000000000..25de5f93e --- /dev/null +++ b/doc/_build/html/services/dns/Domains.md.html @@ -0,0 +1,451 @@ + + + + + + + + + + Domains — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Domains

      +

      A domain is an entity/container of all DNS-related information +containing one or more records.

      +
      +

      Setup

      +

      Limit methods will be called on the DNS service, an instance of +OpenCloud\DNS\Service. Please see the DNS service +documentation for setup instructions.

      +
      +
      +

      Get domain

      +

      To retrieve a specific domain, you will need the domain’s id, not +its domain name.

      +
      $domain = $service->domain(12345);
      +
      +
      +

      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.

      +
      $domains = $service->domainList();
      +
      +# Return detailed information for each domain
      +$domains = $service->domainList(true);
      +
      +
      +

      Please consult the iterator +documentation for more information +about iterators.

      +
      +

      Filter parameters

      +

      You can filter the aforementioned search by using the name parameter +in a key/value array supplied as a method argument. For example, +providing array('name' => 'hoola.com') will return hoola.com and +similar names such as main.hoola.com and sub.hoola.com.

      +
      $hoolaDomains = $service->domainList(array(
      +    'name' => 'hoola.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

      +

      If you know a domain’s name, but not its unique identifier, you can do +this:

      +
      $domains = $service->domainList(array(
      +    'name' => 'foo.com'
      +));
      +
      +foreach ($domains as $domain) {
      +    $id = $domain->id;
      +}
      +
      +
      +
      +
      +
      +

      List domain changes

      +

      This call shows all changes to the specified domain since the specified +date/time. The since parameter is optional and defaults to midnight of +the current day.

      +
      $changes = $domain->changes();
      +
      +# Changes since last week
      +$since = date('c', strtotime('last week'));
      +$changes = $domain->changes($since);
      +
      +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);
      +    }
      +}
      +
      +
      +
      +
      +

      Export domain

      +

      This call provides the BIND (Berkeley Internet Name Domain) 9 formatted +contents of 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 (that is, no subdomain information is provided).

      +
      $asyncResponse = $domain->export();
      +$body = $asyncResponse->waitFor('COMPLETED');
      +echo $body['contents'];
      +
      +
      +
      +
      +

      Create domain

      +

      A domain is composed of DNS records (e.g. A, CNAME or MX +records) and an optional list of sub-domains. You will need to specify +these before creating the domain itself:

      +
      // 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);
      +
      +// add optional C record
      +$cRecord = $domain->record(array(
      +    'type' => 'CNAME',
      +    'name' => 'www.example.com',
      +    'data' => 'example.com',
      +    'ttl'  => 3600
      +));
      +$domain->addRecord($cRecord);
      +
      +// add optional MX record
      +$mxRecord = $domain->record(array(
      +    'type' => 'MX',
      +    'data' => 'mail.example.com',
      +    'name' => 'example.com',
      +    'ttl'  => 3600,
      +    'priority' => 5
      +));
      +$domain->addRecord($mxRecord);
      +
      +// add optional NS records
      +$nsRecord1 = $domain->record(array(
      +    'type' => 'NS',
      +    'data' => 'dns1.stabletransit.com',
      +    'name' => 'example.com',
      +    'ttl'  => 5400
      +));
      +$domain->addRecord($nsRecord1);
      +
      +$nsRecord2 = $domain->record(array(
      +    'type' => 'NS',
      +    'data' => 'dns2.stabletransit.com',
      +    'name' => 'example.com',
      +    'ttl'  => 5400
      +));
      +$domain->addRecord($nsRecord2);
      +
      +// add optional subdomains
      +$sub1 = $domain->subdomain(array(
      +    'emailAddress' => 'foo@example.com',
      +    'name'         => 'dev.example.com',
      +    'comment'      => 'Dev portal'
      +));
      +$domain->addSubdomain($sub1);
      +
      +// send to API
      +$domain->create(array(
      +    'emailAddress' => 'webmaster@example.com',
      +    'ttl'          => 3600,
      +    'name'         => 'example.com',
      +    'comment'      => 'Optional comment'
      +));
      +
      +
      +
      +
      +

      Clone domain

      +

      This call will duplicate a single existing domain configuration with a +new domain name for the specified Cloud account. By default, all records +and, optionally, subdomain(s) are duplicated as well.

      +

      The method signature you will need to use is:

      +
      cloneDomain ( string $newDomainName [, bool $subdomains [, bool $comments [, bool $email [, bool $records ]]]] )
      +
      +
      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameData typeDefaultDescription
      $newDomainNamestring
        +
      • +
      +
      The new name for your cloned domain
      $subdomainsbooltrueSet to TRUE to clone all the subdomains for this domain
      $commentsbooltrueSet to TRUE to replace occurrences of the reference domain name with the new domain name in comments on the cloned (new) domain.
      $emailbooltrueSet 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:

      +
      $asyncResponse = $domain->cloneDomain('new-name.com', true);
      +
      +
      +
      +
      +

      Import domain

      +

      This call provisions a new DNS domain under the account specified by the +BIND 9 formatted file configuration contents defined in the request +object.

      +

      You will need to ensure that the BIND 9 formatted file configuration +contents are valid by adhering 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:

      +
      $bind9Data = <<<EOT
      +\nexample.net. 3600 IN SOA dns1.stabletransit.com. sample@rackspace.com. 1308874739 3600 3600 3600 3600\nexample.net. 86400 IN A 110.11.12.16\nexample.net. 3600 IN MX 5 mail2.example.net.\nwww.example.net. 5400 IN CNAME example.net.\n
      +EOT;
      +
      +$asyncResponse = $service->import($bind9Data);
      +
      +
      +
      +
      +

      Modify domain

      +

      This call modifies DNS domain(s) attributes only. 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.

      +
      $domain->update(array(
      +    'ttl'          => ($domain->ttl + 100),
      +    'emailAddress' => 'new_dev@foo.com'
      +));
      +
      +
      +
      +
      +

      Remove domain

      +
      $domain->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/Limits.md.html b/doc/_build/html/services/dns/Limits.md.html new file mode 100644 index 000000000..e23fbe087 --- /dev/null +++ b/doc/_build/html/services/dns/Limits.md.html @@ -0,0 +1,221 @@ + + + + + + + + + + Limits — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Limits

      +
      +

      Setup

      +

      Limit methods will be called on the DNS service, an instance of +OpenCloud\DNS\Service. Please see the DNS service +documentation for setup instructions.

      +
      +
      +

      List all limits

      +

      This call provides a list of all applicable limits for the specified +account.

      +
      $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:

      +
      $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:

      +
      $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

      +
      $limit = $service->limits('DOMAIN_LIMIT');
      +
      +echo $limit->absolute->limits->value;
      +
      +>>> 500
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/Records.md.html b/doc/_build/html/services/dns/Records.md.html new file mode 100644 index 000000000..5f63aa7dd --- /dev/null +++ b/doc/_build/html/services/dns/Records.md.html @@ -0,0 +1,245 @@ + + + + + + + + + + Records — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Records

      +

      A DNS record belongs to a particular domain and is used to specify +information about the domain.

      +

      There are several types of DNS records. 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.

      +

      It is represented by the OpenCloud\DNS\Resource\Record class. +Records belong to a Domain.

      +
      +

      Get record

      +

      In order to retrieve details for a specific DNS record, you will need +its id:

      +
      $record = $domain->record('NS-1234567');
      +
      +
      +

      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.

      +
      $records = $domain->recordList();
      +
      +foreach ($records as $record) {
      +    printf("Record name: %s, ID: %s, TTL: %s\n", $record->name, $record->id, $record->ttl);
      +}
      +
      +
      +

      Please consult the iterator +documentation for more information +about iterators.

      +
      +

      Query parameters

      +

      You can pass in an array of query parameters for greater control over +your search:

      +
      +
      +

      Find a record ID from its name

      +

      For example:

      +
      $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:

      +
      $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

      +
      $record = $domain->record(123456);
      +$record->ttl -= 100;
      +$record->update();
      +
      +
      +
      +
      +

      Delete record

      +
      $record->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/Reverse-DNS.md.html b/doc/_build/html/services/dns/Reverse-DNS.md.html new file mode 100644 index 000000000..a2c3692d2 --- /dev/null +++ b/doc/_build/html/services/dns/Reverse-DNS.md.html @@ -0,0 +1,268 @@ + + + + + + + + + + Reverse DNS — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Reverse DNS

      +

      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.

      +
      +

      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:

      +
      /** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */
      +
      +$ptr = $service->ptrRecord(array(
      +    'parent' => $parent
      +));
      +
      +
      +

      So, in the above example, a $parent 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 and load +balancer documentation for more +detailed usage instructions.

      +
      +
      +

      List PTR records

      +
      /** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */
      +
      +$ptrRecords = $service->ptrRecordList($parent);
      +
      +foreach ($ptrRecords as $ptrRecord) {
      +
      +}
      +
      +
      +

      Please consult the iterator +documentation for more information +about iterators.

      +
      +
      +

      Add PTR record

      +
      $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:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired
      typeSpecifies the record type as “PTR”.Yes
      nameSpecifies the name for the domain or subdomain. Must be a valid domain name.Yes
      dataThe data field for PTR records must be a valid IPv4 or IPv6 IP address.Yes
      ttlIf specified, must be greater than 300. Defaults to 3600 if no TTL is specified.No
      commentIf included, its length must be less than or equal to 160 characters.No
      +
      +
      +

      Modify PTR record

      +
      $ptr->update(array(
      +    'ttl' => $ptr->ttl * 2
      +));
      +
      +
      +
      +
      +

      Delete PTR record

      +
      $ptr->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/Service.md.html b/doc/_build/html/services/dns/Service.md.html new file mode 100644 index 000000000..1bf9d94fe --- /dev/null +++ b/doc/_build/html/services/dns/Service.md.html @@ -0,0 +1,171 @@ + + + + + + + + + + DNS Service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      DNS Service

      +

      To instantiate a Compute service object, you first need to setup a +Rackspace/OpenStack client. To do this, or for more information, please +consult the Clients documentation.

      +

      You will then need to run:

      +
      $service = $client->dnsService();
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/domains.html b/doc/_build/html/services/dns/domains.html new file mode 100644 index 000000000..a79cf3908 --- /dev/null +++ b/doc/_build/html/services/dns/domains.html @@ -0,0 +1,545 @@ + + + + + + + + + + Domains — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Domains

      +
      +

      Get domain

      +

      To retrieve a specific domain, you will need the domain’s id, not +its domain name:

      +
      $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.

      +
      $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:

      +
      $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:

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

      +
      $changes = $domain->changes();
      +
      +
      +

      For more granular control, you can manually define the since parameter like +so:

      +
      $since = date('c', strtotime('last week'));
      +$changes = $domain->changes($since);
      +
      +
      +

      Once you have a set of changes, you can iterate over them like so:

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

      +
      // 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:

      +
      // 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:

      +
      $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:

      +
      $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:

      +
      +
      +cloneDomain($newDomainName[, $subdomains[, $comments[, $email[, $records]]]])
      +

      Clone a domain

      + +++ + + + +
      Parameters:
        +
      • $newDomainName (string) – The name of the new domain entry
      • +
      • $subdomains (bool) – Set to true to clone all the subdomains for this domain
      • +
      • $comments (bool) – Set to true to replace occurrences of the reference domain name with the new domain name in comments on the cloned (new) domain.
      • +
      • $email (bool) – 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.
      • +
      • $records (bool) – 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:

      +
      $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:

      +
      $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:

      +
      $bind9Data = <<<EOT
      +
      +example.net. 3600 IN SOA dns1.stabletransit.com. sample@rackspace.com. 1308874739 3600 3600 3600 3600
      +example.net. 86400 IN A 110.11.12.16
      +example.net. 3600 IN MX 5 mail2.example.net.
      +www.example.net. 5400 IN CNAME example.net.
      +
      +EOT;
      +
      +$asyncResponse = $service->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.

      +
      $domain->update(array(
      +    'ttl'          => ($domain->ttl + 100),
      +    'emailAddress' => 'new_dev@foo.com'
      +));
      +
      +
      +
      +
      +

      Delete domain

      +
      $domain->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/index.html b/doc/_build/html/services/dns/index.html new file mode 100644 index 000000000..ad5c65bba --- /dev/null +++ b/doc/_build/html/services/dns/index.html @@ -0,0 +1,404 @@ + + + + + + + + + + DNS v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      DNS v1

      +
      +

      Note

      +

      This service is only available for Rackspace users.

      +
      +
      +

      Setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +

      DNS service

      +

      Now to instantiate the DNS service:

      +
      $service = $client->dnsService();
      +
      +
      +
      +
      + +
      +

      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.
      +
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/limits.html b/doc/_build/html/services/dns/limits.html new file mode 100644 index 000000000..f04387da4 --- /dev/null +++ b/doc/_build/html/services/dns/limits.html @@ -0,0 +1,340 @@ + + + + + + + + + + Limits — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Limits

      +
      +

      List all limits

      +

      This call provides a list of all applicable limits for the specified account.

      +
      $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:

      +
      $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:

      +
      $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

      +
      $limit = $service->limits('DOMAIN_LIMIT');
      +echo $limit->absolute->limits->value;
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/records.html b/doc/_build/html/services/dns/records.html new file mode 100644 index 000000000..27861ae55 --- /dev/null +++ b/doc/_build/html/services/dns/records.html @@ -0,0 +1,402 @@ + + + + + + + + + + Records — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $domain = $service->domain('{domainId}');
      +
      +
      +
      +
      +

      Get record

      +

      In order to retrieve details for a specific DNS record, you will need +its id:

      +
      $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.

      +
      $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:

      + +++++ + + + + + + + + + + + + + + + + + + + + +
      NameData typeDescription
      typestringThe record type
      namestringThe record name
      datastringData for this record
      +
      +
      +

      Find a record ID from its name

      +

      For example:

      +
      $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:

      +
      $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

      +
      $record = $domain->record('{recordId}');
      +$record->ttl -= 100;
      +$record->update();
      +
      +
      +
      +
      +

      Delete record

      +
      $record->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/dns/reverse-dns.html b/doc/_build/html/services/dns/reverse-dns.html new file mode 100644 index 000000000..b5f81390d --- /dev/null +++ b/doc/_build/html/services/dns/reverse-dns.html @@ -0,0 +1,394 @@ + + + + + + + + + + Reverse DNS — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      /** @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 and load +balancer documentation for more +detailed usage instructions.

      +
      +
      +

      List PTR records

      +
      /** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */
      +
      +$ptrRecords = $service->ptrRecordList($parent);
      +
      +foreach ($ptrRecords as $ptrRecord) {
      +
      +}
      +
      +
      +
      +
      +

      Add PTR record

      +
      $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:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired
      typeSpecifies the record type as “PTR”.Yes
      nameSpecifies the name for the domain or subdomain. Must be a valid domain name.Yes
      dataThe data field for PTR records must be a valid IPv4 or IPv6 IP address.Yes
      ttlIf specified, must be greater than 300. Defaults to 3600 if no TTL is specified.No
      commentIf included, its length must be less than or equal to 160 characters.No
      +
      +
      +

      Modify PTR record

      +
      $ptr->update(array(
      +    'ttl' => $ptr->ttl * 2
      +));
      +
      +
      +
      +
      +

      Delete PTR record

      +
      $ptr->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/Roles.md.html b/doc/_build/html/services/identity/Roles.md.html new file mode 100644 index 000000000..66da33b10 --- /dev/null +++ b/doc/_build/html/services/identity/Roles.md.html @@ -0,0 +1,273 @@ + + + + + + + + + + Roles — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Roles

      +
      +

      Intro

      +

      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.

      +
      +
      +

      Setup

      +

      Role objects are instantiated from the Identity service. For more +details, see the Service docs.

      +
      +
      +

      Useful object properties/methods

      + +++++ + + + + + + + + + + + + + + + + + + + + +
      PropertyGetterSetter
      idgetId()setId()
      namegetName()setName()
      descriptiongetDescription()setDescription()
      +
      +
      +

      List roles

      +

      This call lists the global roles available within a specified service.

      +
      $roles = $service->getRoles();
      +
      +foreach ($roles as $role) {
      +   // ...
      +}
      +
      +
      +

      For more information about how to use iterators, see the +documentation.

      +
      +
      +

      Get role

      +

      This call lists detailed information (id, name, description) for a +specified role.

      +
      $roleId = '123abc';
      +$role = $service->getRole($roleId);
      +
      +
      +
      +
      +

      Add/delete user roles

      +

      To add/remove user roles, you must first instantiate a +user object:

      +
      $roleId = '123abc';
      +
      +// 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:

      +
      $roles = $user->getRoles();
      +
      +foreach ($roles as $role) {
      +   // ...
      +}
      +
      +
      +

      For more information about how to use iterators, see the +documentation.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/Service.md.html b/doc/_build/html/services/identity/Service.md.html new file mode 100644 index 000000000..81c2d8a3b --- /dev/null +++ b/doc/_build/html/services/identity/Service.md.html @@ -0,0 +1,194 @@ + + + + + + + + + + Identity service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Identity service

      +
      +

      Intro

      +

      The Identity service is regionless, so you do not need to specify a +region when instantiating the service object. Although this was +primarily based on Rackspace’s implementation of Cloud Identity, it +should also work for OpenStack Keystone.

      +
      +
      +

      A note on object creation

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/Tenants.md.html b/doc/_build/html/services/identity/Tenants.md.html new file mode 100644 index 000000000..5bf81f980 --- /dev/null +++ b/doc/_build/html/services/identity/Tenants.md.html @@ -0,0 +1,201 @@ + + + + + + + + + + Tenants — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Tenants

      +
      +

      Intro

      +

      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.

      +
      +
      +

      Setup

      +

      Tenant objects are instantiated from the Identity service. For more +details, see the Service docs.

      +
      +
      +

      List tenants

      +
      $tenants = $service->getTenants();
      +
      +foreach ($tenants as $tenant) {
      +   // ...
      +}
      +
      +
      +

      For more information about how to use iterators, see the +documentation.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/Tokens.md.html b/doc/_build/html/services/identity/Tokens.md.html new file mode 100644 index 000000000..40d57c972 --- /dev/null +++ b/doc/_build/html/services/identity/Tokens.md.html @@ -0,0 +1,287 @@ + + + + + + + + + + Tokens — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Tokens

      +
      +

      Intro

      +

      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.

      +
      +
      +

      Setup

      +

      Token objects are instantiated from the Identity service. For more +details, see the Service docs.

      +
      +
      +

      Useful object properties/methods

      + ++++++ + + + + + + + + + + + + + + + + + + + +
      PropertyDescriptionGetterSetter
      idThe unique ID of the tokengetId()setId()
      expiresTimestamp of when the token will expiregetExpires() or hasExpired()setExpires()
      +
      +
      +

      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.

      +

      Request body for Rackspace’s generate token operation:

      +
      {
      +    "auth": {
      +        "RAX-KSKEY:apiKeyCredentials": {
      +            "username": "foo",
      +            "apiKey": "aaaaa-bbbbb-ccccc-12345678"
      +        },
      +        "tenantId": "1100111"
      +    }
      +}
      +
      +
      +

      Request body for Keystone’s generate token operation:

      +
      {
      +    "auth": {
      +        "passwordCredentials":{
      +            "username":"demoauthor",
      +            "password":"theUsersPassword"
      +        },
      +        "tenantId": "12345678"
      +    }
      +}
      +
      +
      +

      The only real differences you’ll notice is the name of the object key +(RAX-KSKEY:apiKeyCredentials/passwordCredentials) and the secret +(apiKey/password). The tenantId property in both templates +are optional. You can also add tenantName too.

      +
      use OpenCloud\Common\Http\Message\Formatter;
      +
      +$template = sprintf(
      +   '{"auth": {"RAX-KSKEY:apiKeyCredentials":{"username": "%s", "apiKey": "%s"}}}',
      +   'my_username',
      +   'my_api_key'
      +);
      +
      +$response = $service->generateToken($template);
      +
      +$body = Formatter::decode($response);
      +
      +// service catalog
      +$catalog = $body->access->serviceCatalog;
      +
      +// token
      +$token = $body->access->token;
      +
      +// user
      +$user = $body->access->user;
      +
      +
      +

      As you will notice, these variables will be stdClass objects - for fully +fledged functionality, let the client authenticate by itself because it +ends up stocking the necessary models for you.

      +

      To see the response body structure, consult the official +docs.

      +
      +
      +

      Revoke token (destroy session)

      +
      $tokenId = '1234567';
      +$service->revokeToken($tokenId);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/Users.md.html b/doc/_build/html/services/identity/Users.md.html new file mode 100644 index 000000000..e7b735280 --- /dev/null +++ b/doc/_build/html/services/identity/Users.md.html @@ -0,0 +1,358 @@ + + + + + + + + + + Users — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Users

      +
      +

      Intro

      +

      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.

      +
      +
      +

      Setup

      +

      User objects are instantiated from the Identity service. For more +details, see the Service docs.

      +
      +
      +

      Useful object properties/methods

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PropertyDescriptionGetterSetter
      idThe unique ID for this usergetId()setId()
      usernameUsername for this usergetUsername()setUsername()
      emailUser’s email addressgetEmail()setEmail()
      enabledWhether or not this user can consume API functionalitygetEnabled() or isEnabled()setEnabled()
      passwordEither a user-defined string, or an automatically generated one, that provides security when authenticating.getPassword() only valid on creationsetPassword() to set local property only. To set password on API (retention), use updatePassword().
      defaultRegionDefault 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()
      domainIdDomain 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

      +
      $users = $service->getUsers();
      +
      +foreach ($users as $user) {
      +   // ...
      +}
      +
      +
      +

      For more information about how to use iterators, see the +documentation.

      +
      +
      +

      Get user

      +

      There are various ways to get a specific user: by name, ID and email +address.

      +
      use OpenCloud\Identity\Constants\User as UserConst;
      +
      +// Get user by name
      +$user1 = $service->getUser('jamie');
      +
      +// Get user by ID
      +$user2 = $service->getUser(123456, UserConst::MODE_ID);
      +
      +// Get user by email
      +$user3 = $service->getUser('jamie.hannaford@rackspace.com', UserConst::MODE_EMAIL);
      +
      +
      +
      +
      +

      Create user

      +

      There are a few things to remember 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.
      • +
      • Within an account, a maximum of 100 account users can be added.
      • +
      • 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.

      +
      use Guzzle\Http\Exception\ClientErrorResponseException;
      +
      +try {
      +   // execute operation
      +   $user = $service->createUser(array(
      +      'username' => 'newUser',
      +      'email'    => 'foo@bar.com'
      +   ));
      +} catch (ClientErrorResponseException $e) {
      +   // catch 4xx HTTP errors
      +   echo $e->getResponse()->toString();
      +}
      +
      +// show generated password
      +echo $user->getPassword();
      +
      +
      +
      +
      +

      Update user

      +

      When updating a user, specify which attribute/property you want to +update:

      +
      $user->update(array(
      +   'email' => 'new_email@bar.com'
      +));
      +
      +
      +
      +

      Updating a user password

      +

      Updating a user password requires calling a distinct method:

      +
      $user->updatePassword('password123');
      +
      +
      +
      +
      +
      +

      Delete user

      +
      $user->delete();
      +
      +
      +
      +
      +

      List credentials

      +

      This operation allows you to see your non-password credential types for +all authentication methods available.

      +
      $creds = $user->getOtherCredentials();
      +
      +
      +
      +
      +

      Get user API key

      +
      echo $user->getApiKey();
      +
      +
      +
      +
      +

      Reset user API key

      +

      When resetting an API key, a new one will be automatically generated for +you:

      +
      $user->resetApiKey();
      +echo $user->getApiKey();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/index.html b/doc/_build/html/services/identity/index.html new file mode 100644 index 000000000..c5bb6ce92 --- /dev/null +++ b/doc/_build/html/services/identity/index.html @@ -0,0 +1,395 @@ + + + + + + + + + + Identity v2 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Identity v2

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Identity service

      +

      Now to instantiate the Identity service:

      +
      $service = $client->identityService();
      +
      +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/roles.html b/doc/_build/html/services/identity/roles.html new file mode 100644 index 000000000..69bf9b7ed --- /dev/null +++ b/doc/_build/html/services/identity/roles.html @@ -0,0 +1,364 @@ + + + + + + + + + + Roles — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      + +++++ + + + + + + + + + + + + + + + + + + + + +
      PropertyGetterSetter
      idgetId()setId()
      namegetName()setName()
      descriptiongetDescription()setDescription()
      +
      +
      +

      List roles

      +

      This call lists the global roles available within a specified service.

      +
      $roles = $service->getRoles();
      +
      +foreach ($roles as $role) {
      +   // ...
      +}
      +
      +
      +
      +
      +

      Get role

      +

      This call lists detailed information (id, name, description) for a +specified role.

      +
      $role = $service->getRole('{roleId}');
      +
      +
      +
      +
      +

      Add/delete user roles

      +
      $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:

      +
      $roles = $user->getRoles();
      +
      +foreach ($roles as $role) {
      +   // ...
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/tenants.html b/doc/_build/html/services/identity/tenants.html new file mode 100644 index 000000000..8277813ca --- /dev/null +++ b/doc/_build/html/services/identity/tenants.html @@ -0,0 +1,317 @@ + + + + + + + + + + Tenants — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Tenants

      +
      +

      List tenants

      +
      $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:

      +
      $tenant->getId();
      +$tenant->getName();
      +$tenant->getDescription();
      +$tenant->isEnabled();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/tokens.html b/doc/_build/html/services/identity/tokens.html new file mode 100644 index 000000000..f6c0a210c --- /dev/null +++ b/doc/_build/html/services/identity/tokens.html @@ -0,0 +1,379 @@ + + + + + + + + + + Tokens — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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:

      +
      $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

      +
      $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

      +
      $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 user documentation +which accompanies this guide.

      +
      +
      +

      Interacting with tenants

      +
      $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 user documentation +which accompanies this guide.

      +
      +
      +
      +

      Revoke token (destroy session)

      +
      $service->revokeToken('{tokenId}');
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/identity/users.html b/doc/_build/html/services/identity/users.html new file mode 100644 index 000000000..d46d9b80d --- /dev/null +++ b/doc/_build/html/services/identity/users.html @@ -0,0 +1,464 @@ + + + + + + + + + + Users — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Users

      +
      +

      Object properties/methods

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PropertyDescriptionGetterSetter
      idThe unique ID for this usergetId()setId()
      usernameUsername for this usergetUsername()setUsername()
      emailUser’s email addressgetEmail()setEmail()
      enabledWhether or not this user can consume API functionalitygetEnabled() or isEnabled()setEnabled()
      passwordEither a user-defined string, or an automatically generated one, that provides security when authenticating.getPassword() only valid on creationsetPassword() to set local property only. To set password on API (retention), use updatePassword().
      defaultRegionDefault 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()
      domainIdDomain 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

      +
      $users = $service->getUsers();
      +
      +foreach ($users as $user) {
      +   // ...
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Retrieve a user by username

      +
      $user = $service->getUser('jamie');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Retrieve a user by user ID

      +
      use OpenCloud\Identity\Constants\User as UserConst;
      +
      +$user = $service->getUser('{userId}', UserConst::MODE_ID);
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Retrieve a user by email address

      +
      use OpenCloud\Identity\Constants\User as UserConst;
      +
      +$user = $service->getUser('{emailAddress}', UserConst::MODE_EMAIL);
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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.

      +
      use Guzzle\Http\Exception\ClientErrorResponseException;
      +
      + $user = $service->createUser(array(
      +    'username' => 'newUser',
      +    'email'    => 'foo@bar.com'
      + ));
      +
      +// show generated password
      +echo $user->getPassword();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Update user

      +

      When updating a user, specify which attribute/property you want to +update:

      +
      $user->update(array(
      +   'email' => 'new_email@bar.com'
      +));
      +
      +
      +
      +
      +

      Updating a user password

      +

      Updating a user password requires calling a distinct method:

      +
      $user->updatePassword('password123');
      +
      +
      +
      +
      +

      Delete user

      +
      $user->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      List credentials

      +

      This operation allows you to see your non-password credential types for +all authentication methods available.

      +
      $creds = $user->getOtherCredentials();
      +
      +
      +
      +
      +

      Get user API key

      +
      echo $user->getApiKey();
      +
      +
      +
      +
      +

      Reset user API key

      +

      When resetting an API key, a new one will be automatically generated for +you:

      +
      $user->resetApiKey();
      +echo $user->getApiKey();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/Images.md.html b/doc/_build/html/services/image/Images.md.html new file mode 100644 index 000000000..b9de74c58 --- /dev/null +++ b/doc/_build/html/services/image/Images.md.html @@ -0,0 +1,273 @@ + + + + + + + + + + Images — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Images

      +

      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).

      +

      An Image is represented by the OpenCloud\Image\Resource\Image class.

      +
      +

      Setup

      +

      You instantiate an Image object from its OpenCloud\Image\Service +class, which is available from the OpenStack/Rackspace client:

      +
      $service = $client->imageService('cloudImages', 'IAD');
      +
      +
      +

      View the guides for more information about clients +or services.

      +
      +
      +

      List images

      +
      $images = $service->listImages();
      +
      +foreach ($images as $image) {
      +   /** @param $image OpenCloud\Image\Resource\Image */
      +}
      +
      +
      +

      For more information about working with iterators, please see the +iterators documentation.

      +
      +
      +

      Get image details

      +
      /** @param $image OpenCloud\Image\Resource\Image */
      +$image = $service->getImage('<image_id>');
      +
      +
      +
      +

      A note on schema classes

      +

      Both OpenCloud\Image\Resource\Image and +OpenCloud\Image\Resource\Member extend the +AbstractSchemaResource abstract 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 way +different than conventional getter/setter methods, and even class +properties. For this reason, they implement SPL’s native +`ArrayAccess <http://www.php.net/manual/en/class.arrayaccess.php>`__ +interface which allows you to access their state as a conventional +array:

      +
      $image = $service->getImage('<image_id>');
      +
      +$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:

      +
      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

      +
      $image->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/Schemas.md.html b/doc/_build/html/services/image/Schemas.md.html new file mode 100644 index 000000000..e3e7d1427 --- /dev/null +++ b/doc/_build/html/services/image/Schemas.md.html @@ -0,0 +1,331 @@ + + + + + + + + + + JSON schemas — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      JSON schemas

      +

      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.

      +

      A JSON Schema is represented by the +OpenCloud\Image\Resource\Schema\Schema class.

      +
      +

      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:

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

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

      +
      {
      +    "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.

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

      +
      [
      +    {"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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/Sharing.md.html b/doc/_build/html/services/image/Sharing.md.html new file mode 100644 index 000000000..743793072 --- /dev/null +++ b/doc/_build/html/services/image/Sharing.md.html @@ -0,0 +1,311 @@ + + + + + + + + + + Sharing images — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Sharing images

      +

      Images can be created and deleted by image producers, updated by image +consumers, and listed by both image producers and image consumers:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      OperationProducer can?Consumer can?
      CreatedYesNo
      DeletedYesNo
      UpdatedNoYes
      ListedYesYes
      +

      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. +
      3. A potential consumer provides the producer with his/her tenant ID and +email address.
      4. +
      5. The producer `creates a new Image Member <>`__ with the consumer’s +details
      6. +
      7. The producer notifies the consumer via email that the image has been +shared and provides the image’s ID.
      8. +
      9. If the consumer wishes the image to appear in his/her image list, the +consumer `updates their own Member status <>`__ to ACCEPTED.
      10. +
      +
      +

      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 this up first.

      +
      +
      +

      List image members

      +

      This operation is available for both producers and consumers.

      +
      $members = $image->listMembers();
      +
      +foreach ($members as $member) {
      +    /** @param $member OpenCloud\Image\Resource\Member */
      +}
      +
      +
      +

      For more information about working with iterators, please see the +iterators documentation.

      +
      +
      +

      Create image member

      +

      This operation is only available for producers.

      +
      $tenantId = 12345;
      +
      +/** @param $response Guzzle\Http\Message\Response */
      +$response = $image->createMember($tenantId);
      +
      +
      +
      +
      +

      Delete image member

      +

      This operation is only available for producers.

      +
      $tenantId = 12345;
      +
      +/** @param $member OpenCloud\Image\Resource\Member */
      +$member = $image->getMember($tenantId);
      +
      +$member->delete();
      +
      +
      +
      +
      +

      Update image member status

      +

      This operation is only available for consumers.

      +
      use OpenCloud\Images\Enum\MemberStatus;
      +
      +$tenantId = 12345;
      +
      +/** @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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/Tags.md.html b/doc/_build/html/services/image/Tags.md.html new file mode 100644 index 000000000..85836ec8e --- /dev/null +++ b/doc/_build/html/services/image/Tags.md.html @@ -0,0 +1,205 @@ + + + + + + + + + + Image tags — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Image tags

      +

      An image tag is a string of characters used to identify a specific image +or images.

      +
      +

      Setup

      +

      All member operations are executed against an Image, so +you will need to set this up first.

      +
      +
      +

      Add image tag

      +
      /** @param $response Guzzle\Http\Message\Response */
      +$response = $image->addTag('jamie_dev');
      +
      +
      +
      +
      +

      Delete image tag

      +
      /** @param $response Guzzle\Http\Message\Response */
      +$response = $image->deleteTag('jamie_dev');
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/images.html b/doc/_build/html/services/image/images.html new file mode 100644 index 000000000..9fe53b19c --- /dev/null +++ b/doc/_build/html/services/image/images.html @@ -0,0 +1,366 @@ + + + + + + + + + + Images — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Images

      +
      +

      List images

      +
      $images = $service->listImages();
      +
      +foreach ($images as $image) {
      +   /** @param $image OpenCloud\Image\Resource\Image */
      +}
      +
      +
      +
      +
      +

      Get image details

      +
      /** @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:

      +
      $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:

      +
      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

      +
      $image->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/index.html b/doc/_build/html/services/image/index.html new file mode 100644 index 000000000..1ac5b3af7 --- /dev/null +++ b/doc/_build/html/services/image/index.html @@ -0,0 +1,397 @@ + + + + + + + + + + Images v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Images v1

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Images service

      +

      Now to instantiate the Images service:

      +
      $service = $client->imageService(null, '{region}');
      +
      +
      +
      +
      + +
      +

      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.
      +
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/schemas.html b/doc/_build/html/services/image/schemas.html new file mode 100644 index 000000000..b73adabc1 --- /dev/null +++ b/doc/_build/html/services/image/schemas.html @@ -0,0 +1,440 @@ + + + + + + + + + + JSON schemas — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

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

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

      +
      {
      +    "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.

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

      +
      [
      +    {"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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/sharing.html b/doc/_build/html/services/image/sharing.html new file mode 100644 index 000000000..01e693f02 --- /dev/null +++ b/doc/_build/html/services/image/sharing.html @@ -0,0 +1,417 @@ + + + + + + + + + + Sharing images — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Sharing images

      +

      Images can be created and deleted by image producers, updated by image +consumers, and listed by both image producers and image consumers:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      OperationProducer can?Consumer can?
      CreatedYesNo
      DeletedYesNo
      UpdatedNoYes
      ListedYesYes
      +

      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. +
      3. A potential consumer provides the producer with his/her tenant ID and +email address.
      4. +
      5. The producer `creates a new Image Member <>`__ with the consumer’s +details
      6. +
      7. The producer notifies the consumer via email that the image has been +shared and provides the image’s ID.
      8. +
      9. If the consumer wishes the image to appear in his/her image list, the +consumer `updates their own Member status <>`__ to ACCEPTED.
      10. +
      +
      +

      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:

      +
      $image = $service->getImage('{imageId}');
      +
      +
      +
      +
      +

      List image members

      +

      This operation is available for both producers and consumers.

      +
      $members = $image->listMembers();
      +
      +foreach ($members as $member) {
      +    /** @param $member OpenCloud\Image\Resource\Member */
      +}
      +
      +
      +
      +
      +

      Create image member

      +

      This operation is only available for producers.

      +
      /** @param $response Guzzle\Http\Message\Response */
      +$response = $image->createMember('{tenantId}');
      +
      +
      +
      +
      +

      Delete image member

      +

      This operation is only available for producers.

      +
      /** @param $member OpenCloud\Image\Resource\Member */
      +$member = $image->getMember('{tenantId}');
      +$member->delete();
      +
      +
      +
      +
      +

      Update image member status

      +

      This operation is only available for consumers.

      +
      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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/image/tags.html b/doc/_build/html/services/image/tags.html new file mode 100644 index 000000000..a4c59e644 --- /dev/null +++ b/doc/_build/html/services/image/tags.html @@ -0,0 +1,318 @@ + + + + + + + + + + Image tags — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Image tags

      +
      +

      Setup

      +

      All member operations are executed against an Image, so you will +need to set one up first:

      +
      $image = $service->getImage('{imageId}');
      +
      +
      +
      +
      +

      Add image tag

      +
      /** @param $response Guzzle\Http\Message\Response */
      +$response = $image->addTag('jamie_dev');
      +
      +
      +
      +
      +

      Delete image tag

      +
      /** @param $response Guzzle\Http\Message\Response */
      +$response = $image->deleteTag('jamie_dev');
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/index.html b/doc/_build/html/services/index.html new file mode 100644 index 000000000..e56bd9a40 --- /dev/null +++ b/doc/_build/html/services/index.html @@ -0,0 +1,177 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      + + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/README.md.html b/doc/_build/html/services/load-balancer/README.md.html new file mode 100644 index 000000000..cba6ca120 --- /dev/null +++ b/doc/_build/html/services/load-balancer/README.md.html @@ -0,0 +1,262 @@ + + + + + + + + + + Load Balancers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Load Balancers

      +

      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.

      +
      +

      Getting started

      +
      +

      1. Instantiate a Rackspace client.

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
      +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
      +));
      +
      +
      +
      +
      +

      2. Retrieve the server instances you want to add as nodes of the load balancer.

      +
      $computeService = $client->computeService('cloudServersOpenStack', 'DFW');
      +
      +$serverOne = $computeService->server('e836fc4e-056d-4447-a80e-fefcaa640216');
      +$serverTwo = $computeService->server('5399cd36-a23f-41a6-bdf7-20902aec0e74');
      +
      +
      +

      The example above uses two server instances that have already been +created. It retrieves the server instances using their IDs. See also: +`creating server instances <>`__.

      +
      +
      +

      3. Obtain a Load Balancer service object from the client.

      +

      This object will be used to first define the load balancer nodes and +later create the load balancer itself.

      +
      $loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW');
      +
      +
      +
      +
      +

      4. Define a load balancer node for each server.

      +
      $loadBalancer = $loadBalancerService->loadBalancer();
      +
      +$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';
      +
      +
      +

      In the example above, each node runs a service that listens on port +8080. Further, each node will start out as ENABLED, which means it +will be ready to receive network traffic from the load balancer as soon +as it is created.

      +
      +
      +

      5. Create the load balancer with the two nodes.

      +
      $loadBalancer->addVirtualIp('PUBLIC');
      +$loadBalancer->create(array(
      +    'name' => 'My smart load balancer',
      +    'port' => 80,
      +    'protocol' => 'HTTP',
      +    'nodes' => array($serverOneNode, $serverTwoNode)
      +));
      +
      +
      +

      In the example above, the load balancer will have a virtual IP address +accessible from the public Internet. Also notice that the port the load +balancer listens on (80) does not need to match the ports of its nodes +(8080).

      +
      +
      +
      +

      Next steps

      +

      Once you have created a load balancer, there is a lot you can do with +it. See the complete user guide for load balancers.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/USERGUIDE.md.html b/doc/_build/html/services/load-balancer/USERGUIDE.md.html new file mode 100644 index 000000000..99c1c5ed7 --- /dev/null +++ b/doc/_build/html/services/load-balancer/USERGUIDE.md.html @@ -0,0 +1,959 @@ + + + + + + + + + + The Complete User Guide to Load Balancers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      The Complete User Guide to Load Balancers

      +
      +

      Prerequisites

      +
      +

      Client

      +

      To use the load balancers service, you must first instantiate a +Rackspace client object.

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
      +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
      +));
      +
      +
      +
      +
      +

      Load Balancer Service

      +

      All operations on load balancers are done via a load balancer service +object.

      +
      $loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW');
      +
      +
      +
      +
      +

      Cloud Servers

      +

      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.

      +
      +
      +
      +

      Load Balancers

      +

      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.

      +
      +

      Create Load Balancer

      +
      $loadBalancer = $loadBalancerService->loadBalancer();
      +
      +$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';
      +
      +$loadBalancer->addVirtualIp('PUBLIC');
      +$loadBalancer->create(array(
      +    'name'     => 'My smart load balancer',
      +    'port'     => 80,
      +    'protocol' => 'HTTP',
      +    'nodes'    => array($serverOneNode, $serverTwoNode)
      +));
      +
      +
      +
      +
      +

      List Load Balancer Details

      +

      You can retrieve a single load balancer’s details by using its ID.

      +
      $loadBalancer = $loadBalancerService->loadBalancer('254889');
      +
      +/** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/
      +
      +
      +
      +
      +

      List Load Balancers

      +

      You can retrieve a list of all your load balancers. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $loadBalancers = $loadBalancerService->loadBalancerList();
      +foreach ($loadBalancers as $loadBalancer) {
      +    /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/
      +}
      +
      +
      +
      +
      +

      Update Load Balancer Attributes

      +

      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.
      • +
      • protocol: The network protocol used by traffic coming in to the +load balancer. See also: 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.
      • +
      +
      +

      Updating a single attribute of a load balancer

      +
      $loadBalancer->update(array(
      +    'name' => 'New name'
      +));
      +
      +
      +
      +
      +

      Updating multiple attributes of a load balancer

      +
      $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.

      +
      $loadBalancer->delete();
      +
      +
      +
      +
      +
      +

      Nodes

      +

      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.

      +
      +

      List Nodes

      +

      You can list the nodes attached to a load balancer. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $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.

      +
      $address = $serverThree->addresses->private[0]->addr;
      +$loadBalancer->addNode($address, 8080);
      +$loadBalancer->addNodes();
      +
      +
      +

      The addNode method accepts three more optional parameters, in +addition to the two shown above:

      +
      +
      Position | Description | Data type | Required? | Default value |
      +
      ———– | ————— | ————–| ————– |
      +
      +

      —————– | +|  1 | IP address of node | String | Yes | - | +|  2 | Port used by node’s service | Integer | Yes | - | +|  3 | Starting condition of node: +|  4 | Type of node to add: +|  5 | 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. | Integer | +No | 1 |

      +
      +
      +

      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.
      • +
      +
      +

      Modifying a single attribute of a node

      +
      use OpenCloud\LoadBalancer\Enum\NodeCondition;
      +
      +$node->update(array(
      +    'condition' => NodeCondition::DISABLED
      +));
      +
      +
      +
      +
      +

      Modifying multiple attributes of a node

      +
      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.

      +
      +

      Given an OpenCloud\LoadBalancer\Resource\Node instance

      +
      $node->delete();
      +
      +
      +
      +
      +

      Given an OpenCloud\LoadBalancer\Resource\LoadBalancer instance and a node ID

      +
      $loadBalancer->removeNode(490639);
      +
      +
      +

      The removeNode method, as shown above, accepts the following +arguments:

      + +++++++ + + + + + + + + + + + + + + + + +
      PositionDescriptionData typeRequired?Default value
      1ID of nodeIntegerYes
        +
      • +
      +
      +
      +
      +
      +

      View Node Service Events

      +

      You can view events associated with the activity between a node and a +load balancer. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $nodeEvents = $loadBalancer->nodeEventList();
      +foreach ($nodeEvents as $nodeEvent) {
      +    /** @var $nodeEvent OpenCloud\LoadBalancer\Resource\NodeEvent **/
      +}
      +
      +
      +
      +
      +
      +

      Virtual IPs

      +

      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.

      +
      +

      List Virtual IPs

      +

      You can list the VIPs associated with a load balancer. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $vips = $loadBalancer->virtualIpList();
      +foreach ($vips as $vip) {
      +    /** @var $vip of OpenCloud\LoadBalancer\Resource\VirtualIp **/
      +}
      +
      +
      +
      +
      +

      Add Virtual IPv6

      +

      You can add additional IPv6 VIPs to a load balancer.

      +
      use OpenCloud\LoadBalancer\Enum\IpType;
      +
      +$loadBalancer->addVirtualIp(IpType::PUBLIC, 6);
      +
      +
      +

      The addVirtualIp method, as shown above, accepts the following +arguments:

      +
      +
      Position | Description | Data type | Required? | Default value |
      +
      ———– | ————— | ————– |————– |
      +
      +

      —————– | +|  1 | Type of VIP: +|  2 | IP version: Must be 6 | Integer | Yes | - |

      +
      +
      +

      Remove Virtual IPs

      +

      You can remove a VIP from a load balancer.

      +
      $vip->remove();
      +
      +
      +

      Please note that 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.

      +
      +
      +
      +

      Algorithms

      +

      Load balancers use an algorithm to determine how incoming traffic is +distributed amongst the back-end nodes.

      +
      +

      List Load Balancing Algorithms

      +

      You can list all supported load balancing algorithms using a load +balancer service object. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $algorithms = $loadBalancerService->algorithmList();
      +foreach ($algorithms as $algorithm) {
      +    /** @var $algorithm OpenCloud\LoadBalancer\Resource\Algorithm **/
      +}
      +
      +
      +
      +
      +
      +

      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.

      +
      +

      List Load Balancing Protocols

      +

      You can list all supported network protocols using a load balancer +service object. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $protocols = $loadBalancerService->protocolList();
      +foreach ($protocols as $protocol) {
      +    /** @var $protocol OpenCloud\LoadBalancer\Resource\Protocol **/
      +}
      +
      +
      +
      +
      +
      +

      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.

      +

      There are two types (or modes) of session persistence:

      + ++++ + + + + + + + + + + + + + +
      NameDescription
      HTTP_COOKIEA 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_IPA 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.
      +
      +

      List Session Persistence Configuration

      +
      $sessionPersistence = $loadBalancer->sessionPersistence();
      +$sessionPersistenceType = $sessionPersistence->persistenceType;
      +
      +/** @var $sessionPersistenceType null | 'HTTP_COOKIE' | 'SOURCE_IP' **/
      +
      +
      +

      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

      +
      $sessionPersistence = $loadBalancer->sessionPersistence();
      +$sessionPersistence->update(array(
      +    'persistenceType' => 'HTTP_COOKIE'
      +));
      +
      +
      +
      +
      +

      Disable Session Persistence

      +
      $sessionPersistence = $loadBalancer->sessionPersistence();
      +$sessionPersistence->delete();
      +
      +
      +
      +
      +
      +

      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.

      +
      +

      Check Logging Configuration

      +
      /** @var $connectionLogging bool **/
      +
      +$connectionLogging = $loadBalancer->hasConnectionLogging();
      +
      +
      +

      In the example above:

      +
        +
      • If connection logging is enabled, the value of $connectionLogging +is true.
      • +
      • If connection logging is disabled, the value of +$connectionLogging is false.
      • +
      +
      +
      +

      Enable Connection Logging

      +
      $loadBalancer->enableConnectionLogging(true);
      +
      +
      +
      +
      +

      Disable Connection Logging

      +
      $loadBalancer->enableConnectionLogging(false);
      +
      +
      +
      +
      +
      +

      Error Page

      +

      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

      +
      $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

      +
      $errorPage = $loadBalancer->errorPage();
      +$errorPage->update(array(
      +    'content' => '<HTML content of custom error page>'
      +));
      +
      +
      +
      +
      +

      Delete Custom Error Page

      +
      $errorPage = $loadBalancer->errorPage();
      +$errorPage->delete();
      +
      +
      +
      +
      +
      +

      Allowed Domains

      +

      Allowed domains are a restricted set of domain names that are +allowed to add load balancer nodes.

      +
      +

      List Allowed Domains

      +

      You can list all allowed domains using a load balancer service object. +An instance of OpenCloud\Common\Collection\PaginatedIterator is +returned.

      +
      $allowedDomains = $loadBalancerService->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.

      +
      +

      View Access List

      +

      You can view a load balancer’s access list. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $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:

      +
      $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.

      +
      $networkItem->delete();
      +
      +
      +
      +
      +
      +

      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.

      +
      +

      Check Content Caching Configuration

      +
      /** @var $contentCaching bool **/
      +
      +$contentCaching = $loadBalancer->hasContentCaching();
      +
      +
      +

      In the example above:

      +
        +
      • If content caching is enabled, the value of $contentCaching is +true.
      • +
      • If content caching is disabled, the value of $contentCaching is +false.
      • +
      +
      +
      +

      Enable Content Caching

      +
      $loadBalancer->enableContentCaching(true);
      +
      +
      +
      +
      +

      Disable Content Caching

      +
      $loadBalancer->enableContentCaching(false);
      +
      +
      +
      +
      +
      +

      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.

      +
      +

      View current SSL termination config

      +
      /** @var $sslConfig OpenCloud\LoadBalancer\Resource\SSLTermination **/
      +
      +$sslConfig = $loadBalancer->SSLTermination();
      +
      +
      +
      +
      +

      Update SSL termination config

      +
      $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 SSL termination config

      +
      $sslConfig->delete();
      +
      +
      +
      +
      +
      +

      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.

      +
      +

      List metadata

      +
      $metadataList = $loadBalancer->metadataList();
      +
      +foreach ($metadataList as $metadataItem) {
      +    printf("Key: %s, Value: %s", $metadataItem->key, $metadataItem->value);
      +}
      +
      +
      +

      Please consult the iterator +documentation for more information +about iterators.

      +
      +
      +

      Add metadata

      +
      $metadataItem = $loadBalancer->metadata();
      +$metadataItem->create(array(
      +    'key'   => 'foo',
      +    'value' => 'bar'
      +));
      +
      +
      +
      +
      +

      Modify metadata

      +
      $metadataItem = $loadBalancer->metadata('foo');
      +$metadataItem->update(array(
      +    'value' => 'baz'
      +));
      +
      +
      +
      +
      +

      Remove metadata

      +
      $metadataItem->delete();
      +
      +
      +
      +
      +
      +

      Monitors

      +

      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.

      +
      /** @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 or delete

      +
      // Update
      +$healthMonitor->update(array(
      +    'delay'   => 120,
      +    'timeout' => 60,
      +    'type'    => 'CONNECT'
      +    'attemptsBeforeDeactivation' => 3
      +));
      +
      +// Delete
      +$healthMonitor->delete();
      +
      +
      +
      +
      +
      +

      Statistics

      +

      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.
      • +
      +
      /** @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.

      +
      # 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;
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/access.html b/doc/_build/html/services/load-balancer/access.html new file mode 100644 index 000000000..9a07d5eda --- /dev/null +++ b/doc/_build/html/services/load-balancer/access.html @@ -0,0 +1,368 @@ + + + + + + + + + + Allowed Domains — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      $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.

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      View Access List

      +

      You can view a load balancer’s access list:

      +
      $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:

      +
      $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.

      +

      Get the executable PHP scripts for this example:

      + +
      +
      +

      Remove Network Item From Access List

      +

      You an remove a network item from a load balancer’s access list:

      +
      $networkItem->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/caching.html b/doc/_build/html/services/load-balancer/caching.html new file mode 100644 index 000000000..5f62a9f07 --- /dev/null +++ b/doc/_build/html/services/load-balancer/caching.html @@ -0,0 +1,327 @@ + + + + + + + + + + Content Caching — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      Check Configuration

      +
      // TRUE if enabled, FALSE if not
      +$contentCaching = $loadBalancer->hasContentCaching();
      +
      +
      +
      +
      +

      Enable Content Caching

      +
      $loadBalancer->enableContentCaching(true);
      +
      +
      +
      +
      +

      Disable Content Caching

      +
      $loadBalancer->enableContentCaching(false);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/errors.html b/doc/_build/html/services/load-balancer/errors.html new file mode 100644 index 000000000..03d119805 --- /dev/null +++ b/doc/_build/html/services/load-balancer/errors.html @@ -0,0 +1,336 @@ + + + + + + + + + + Error Pages — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Error Pages

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +

      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

      +
      $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

      +
      $errorPage = $loadBalancer->errorPage();
      +$errorPage->update(array(
      +    'content' => '<HTML content of custom error page>'
      +));
      +
      +
      +
      +
      +

      Delete Custom Error Page

      +
      $errorPage = $loadBalancer->errorPage();
      +$errorPage->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/index.html b/doc/_build/html/services/load-balancer/index.html new file mode 100644 index 000000000..96de80255 --- /dev/null +++ b/doc/_build/html/services/load-balancer/index.html @@ -0,0 +1,493 @@ + + + + + + + + + + Load Balancer v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Load Balancer v1

      +
      +

      Note

      +

      This service is only available for Rackspace users.

      +
      +
      +

      Setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +

      Load Balancer service

      +

      Now to instantiate the Load Balancer service:

      +
      $service = $client->loadBalancerService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/lb-setup.sample.html b/doc/_build/html/services/load-balancer/lb-setup.sample.html new file mode 100644 index 000000000..56eadb9cf --- /dev/null +++ b/doc/_build/html/services/load-balancer/lb-setup.sample.html @@ -0,0 +1,287 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/load-balancer.html b/doc/_build/html/services/load-balancer/load-balancer.html new file mode 100644 index 000000000..5134ad239 --- /dev/null +++ b/doc/_build/html/services/load-balancer/load-balancer.html @@ -0,0 +1,433 @@ + + + + + + + + + + Load Balancer — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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:

      +
      $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:

      +
      $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 and algorithms +please see the sections below.

      +

      Get the executable PHP script for this example

      +
      +
      +

      Get Load Balancer Details

      +

      You can retrieve a single load balancer’s details by using its ID:

      +
      /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/
      +$loadBalancer = $service->loadBalancer('{loadBalancerId}');
      +
      +
      +
      +
      +

      List Load Balancers

      +

      You can retrieve a list of all your load balancers:

      +
      $loadBalancers = $service->loadBalancerList();
      +
      +foreach ($loadBalancers as $loadBalancer) {
      +    /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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.
      • +
      • protocol: The network protocol used by traffic coming in to the +load balancer. See also: 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.
      • +
      +
      $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:

      +
      $loadBalancer->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      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:

      +
      $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:

      +
      $algorithms = $service->algorithmList();
      +
      +foreach ($algorithms as $algorithm) {
      +    /** @var $algorithm OpenCloud\LoadBalancer\Resource\Algorithm **/
      +}
      +
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/logging.html b/doc/_build/html/services/load-balancer/logging.html new file mode 100644 index 000000000..a987dcef0 --- /dev/null +++ b/doc/_build/html/services/load-balancer/logging.html @@ -0,0 +1,326 @@ + + + + + + + + + + Connection Logging — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      Check Configuration

      +
      // TRUE if enabled, FALSE if not
      +$connectionLogging = $loadBalancer->hasConnectionLogging();
      +
      +
      +
      +
      +

      Enable Connection Logging

      +
      $loadBalancer->enableConnectionLogging(true);
      +
      +
      +
      +
      +

      Disable Connection Logging

      +
      $loadBalancer->enableConnectionLogging(false);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/metadata.html b/doc/_build/html/services/load-balancer/metadata.html new file mode 100644 index 000000000..70866abda --- /dev/null +++ b/doc/_build/html/services/load-balancer/metadata.html @@ -0,0 +1,339 @@ + + + + + + + + + + Metadata — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Metadata

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      List metadata

      +
      $metadataList = $loadBalancer->metadataList();
      +
      +foreach ($metadataList as $metadataItem) {
      +    printf("Key: %s, Value: %s", $metadataItem->key, $metadataItem->value);
      +}
      +
      +
      +
      +
      +

      Add metadata

      +
      $metadataItem = $loadBalancer->metadata();
      +$metadataItem->create(array(
      +    'key'   => 'foo',
      +    'value' => 'bar'
      +));
      +
      +
      +
      +
      +

      Modify metadata

      +
      $metadataItem = $loadBalancer->metadata('foo');
      +$metadataItem->update(array(
      +    'value' => 'baz'
      +));
      +
      +
      +
      +
      +

      Remove metadata

      +
      $metadataItem->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/monitors.html b/doc/_build/html/services/load-balancer/monitors.html new file mode 100644 index 000000000..cec0452a4 --- /dev/null +++ b/doc/_build/html/services/load-balancer/monitors.html @@ -0,0 +1,337 @@ + + + + + + + + + + Health Monitors — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Health Monitors

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      Retrieve monitor details

      +
      /** @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

      +
      $healthMonitor->update(array(
      +    'delay'   => 120,
      +    'timeout' => 60,
      +    'type'    => 'CONNECT'
      +    'attemptsBeforeDeactivation' => 3
      +));
      +
      +
      +
      +
      +

      Delete monitor

      +
      $healthMonitor->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/nodes.html b/doc/_build/html/services/load-balancer/nodes.html new file mode 100644 index 000000000..d0df9139d --- /dev/null +++ b/doc/_build/html/services/load-balancer/nodes.html @@ -0,0 +1,415 @@ + + + + + + + + + + Nodes — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Nodes

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      List Nodes

      +

      You can list the nodes attached to a load balancer:

      +
      $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.

      +
      $address = $serverThree->addresses->private[0]->addr;
      +$loadBalancer->addNode($address, 8080);
      +$loadBalancer->addNodes();
      +
      +
      +

      The signature for addNodes is as follows:

      +
      +
      +addNodes($address, $port[, $condition = 'ENABLED'[, $type = null[, $weight = null]]])
      +

      Add a node to a load balancer

      + +++ + + + +
      Parameters:
        +
      • $address (string) – the IP address of the node
      • +
      • $port (integer) – the port number of the node
      • +
      • $condition (string) – the initial condition of the code. Defaults to ENABLED
      • +
      • $type (string) – either PRIMARY or SECONDARY
      • +
      • $weight (integer) – 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.
      • +
      +
      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:

      +
      $node->delete();
      +
      +
      +

      The second is with an OpenCloud\LoadBalancer\Resource\LoadBalancer +instance and the node’s ID, like so:

      +
      $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:

      +
      $nodeEvents = $loadBalancer->nodeEventList();
      +
      +foreach ($nodeEvents as $nodeEvent) {
      +    /** @var $nodeEvent OpenCloud\LoadBalancer\Resource\NodeEvent **/
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/sessions.html b/doc/_build/html/services/load-balancer/sessions.html new file mode 100644 index 000000000..ff25f8f22 --- /dev/null +++ b/doc/_build/html/services/load-balancer/sessions.html @@ -0,0 +1,357 @@ + + + + + + + + + + Session Persistence — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Session Persistence

      +

      There are two types (or modes) of session persistence:

      + ++++ + + + + + + + + + + + + + +
      NameDescription
      HTTP_COOKIEA 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_IPA 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.
      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      List Session Persistence Configuration

      +
      $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

      +
      $sessionPersistence = $loadBalancer->sessionPersistence();
      +$sessionPersistence->update(array(
      +    'persistenceType' => 'HTTP_COOKIE'
      +));
      +
      +
      +
      +
      +

      Disable Session Persistence

      +
      $sessionPersistence = $loadBalancer->sessionPersistence();
      +$sessionPersistence->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/ssl.html b/doc/_build/html/services/load-balancer/ssl.html new file mode 100644 index 000000000..3eb6a88ca --- /dev/null +++ b/doc/_build/html/services/load-balancer/ssl.html @@ -0,0 +1,344 @@ + + + + + + + + + + SSL Termination — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      View configuration

      +
      /** @var $sslConfig OpenCloud\LoadBalancer\Resource\SSLTermination **/
      +$sslConfig = $loadBalancer->SSLTermination();
      +
      +
      +
      +
      +

      Update configuration

      +
      $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

      +

      Get the executable PHP script for this example

      +
      +
      +

      Delete configuration

      +
      $sslConfig->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/stats.html b/doc/_build/html/services/load-balancer/stats.html new file mode 100644 index 000000000..552a3254d --- /dev/null +++ b/doc/_build/html/services/load-balancer/stats.html @@ -0,0 +1,354 @@ + + + + + + + + + + Statistics and Usage Reports — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Statistics and Usage Reports

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      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.
      • +
      +
      /** @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.

      +
      # 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;
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/load-balancer/virtual-ips.html b/doc/_build/html/services/load-balancer/virtual-ips.html new file mode 100644 index 000000000..3d662e669 --- /dev/null +++ b/doc/_build/html/services/load-balancer/virtual-ips.html @@ -0,0 +1,354 @@ + + + + + + + + + + Virtual IPs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Virtual IPs

      +
      +

      Setup

      +

      In order to interact with this feature you must first retrieve a particular +load balancer, like so:

      +
      $loadBalancer = $service->loadBalancer('{id}');
      +
      +
      +
      +
      +

      List Virtual IPs

      +

      You can list the VIPs associated with a load balancer like so:

      +
      $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:

      +
      +
      +

      Add Virtual IPv6

      +

      You can add additional IPv6 VIPs to a load balancer using the following method:

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

      +
      use OpenCloud\LoadBalancer\Enum\IpType;
      +
      +$loadBalancer->addVirtualIp(IpType::PUBLIC, 4);
      +
      +
      +
      +
      +

      Remove Virtual IP

      +

      You can remove a VIP from a load balancer.

      +
      $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.

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Agents.md.html b/doc/_build/html/services/monitoring/Agents.md.html new file mode 100644 index 000000000..72a31097e --- /dev/null +++ b/doc/_build/html/services/monitoring/Agents.md.html @@ -0,0 +1,439 @@ + + + + + + + + + + Agents — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Agents

      +
      +

      Intro

      +

      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.

      +
      +
      +

      Setup

      +
      $agentId = '00-agent.example.com';
      +$agent   = $service->getAgent($agentId);
      +
      +
      +

      You can view the service page for more information +about setting up the Cloud Monitoring service.

      +
      +
      +

      List agents

      +
      $agents = $service->getAgents();
      +
      +foreach ($agents as $agent) {
      +   echo $agent->getLastConnected();
      +}
      +
      +
      +

      Please consult the iterator doc for +more information about iterators.

      +
      +
      +

      List connections

      +
      $connections = $agent->getConnections();
      +
      +
      +

      Please consult the iterator doc for +more information about iterators.

      +
      +
      +

      Get connection

      +
      /** @var \OpenCloud\CloudMonitoring\Resource\AgentConnection */
      +$connection = $agent->getConnection('cntl4qsIbA');
      +
      +
      +
      +

      Agent Connection properties

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionTypeMethod
      id
        +
      • +
      +
        +
      • +
      +
      getId()
      guid
        +
      • +
      +
        +
      • +
      +
      getGuid()
      agent_id
        +
      • +
      +
        +
      • +
      +
      getAgentId()
      endpoint
        +
      • +
      +
        +
      • +
      +
      getEndpoint()
      process_version
        +
      • +
      +
        +
      • +
      +
      getProcessVersion()
      bundle_version
        +
      • +
      +
        +
      • +
      +
      getBundleVersion()
      agent_ip
        +
      • +
      +
        +
      • +
      +
      getAgentIp()
      +
      +
      +
      +
      +

      Agent tokens

      +
      +

      Intro

      +

      Agent tokens are used to authenticate Monitoring agents to the +Monitoring Service. Multiple agents can share a single token.

      +
      +
      +

      Setup

      +
      $tokenId = '4c5e28f0-0b3f-11e1-860d-c55c4705a286:1234';
      +$agentToken = $service->getAgentToken($tokenId);
      +
      +
      +
      +
      +

      Create agent token

      +
      $newToken = $service->getAgentToken();
      +$newToken->create(array('label' => 'Foobar'));
      +
      +
      +
      +
      +

      List agent tokens

      +
      $agentTokens = $service->getAgentTokens();
      +
      +foreach ($agentTokens as $token) {
      +    echo $token->getLabel();
      +}
      +
      +
      +

      Please consult the iterator doc for +more information about iterators.

      +
      +
      +

      Update and delete Agent Token

      +
      // Update
      +$token->update(array(
      +    'label' => 'New label'
      +));
      +
      +// Delete
      +$token->delete();
      +
      +
      +
      +
      +
      +

      Agent Host Information

      +
      +

      Info

      +

      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

      +
      $host = $monitoringService->getAgentHost();
      +
      +
      +
      +
      +

      Get some metrics

      +
      $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

      +
      +

      Info

      +

      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

      +
      $targets = $service->getAgentTargets();
      +
      +foreach ($targets as $target) {
      +    echo $target->getType();
      +}
      +
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Alarms.md.html b/doc/_build/html/services/monitoring/Alarms.md.html new file mode 100644 index 000000000..b84555dd9 --- /dev/null +++ b/doc/_build/html/services/monitoring/Alarms.md.html @@ -0,0 +1,286 @@ + + + + + + + + + + Alarms — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Alarms

      +
      +

      Info

      +

      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

      +

      Alarms are sub-resources of Entities:

      +
      $alarmId = 'alAAAA';
      +$alarm = $check->getAlarm();
      +
      +
      +

      For more information about working with Checks, please see the +appropriate documentation.

      +
      +
      +

      Attributes

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Method
      check_idThe ID of the check to alert on.RequiredgetCheckId()
      notification_plan_idThe ID of the notification plan to execute when the state changes.OptionalgetNotificationPlanId()
      criteriaThe alarm DSL for describing alerting conditions and their output states.OptionalgetCriteria()
      disabledDisable processing and alerts on this alarmOptionalisDisabled() <bool>
      labelA friendly label for an alarm.OptionalgetLabel()
      metadataArbitrary key/value pairs.OptionalgetMetadata()
      +
      +
      +

      Create Alarm

      +
      $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

      +
      $alarms = $entity->getAlarms();
      +
      +foreach ($alarms as $alarm) {
      +    echo $alarm->getId();
      +}
      +
      +
      +
      +
      +

      Update and delete Alarm

      +
      // Update
      +$alarm->update(array(
      +    'criteria' => 'if (metric["duration"] >= 5) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);'
      +));
      +
      +// Delete
      +$alarm->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Changelogs.md.html b/doc/_build/html/services/monitoring/Changelogs.md.html new file mode 100644 index 000000000..27d72515a --- /dev/null +++ b/doc/_build/html/services/monitoring/Changelogs.md.html @@ -0,0 +1,200 @@ + + + + + + + + + + Changelogs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Changelogs

      +
      +

      Info

      +

      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.

      +
      +
      +

      Working with Changelogs

      +
      $changelog = $service->getChangelog();
      +
      +foreach ($changelog as $item) {
      +   $entity = $item->getEntityId();
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Checks.md.html b/doc/_build/html/services/monitoring/Checks.md.html new file mode 100644 index 000000000..643149bf5 --- /dev/null +++ b/doc/_build/html/services/monitoring/Checks.md.html @@ -0,0 +1,456 @@ + + + + + + + + + + Checks — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Checks

      +
      +

      Info

      +

      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).

      +
      +
      +

      Setup

      +

      Checks are sub-resources of Entities:

      +
      $checkId = 'chAAAA';
      +$check = $entity->getCheck($checkId);
      +
      +
      +
      +
      +

      Attributes

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data type
      typeThe type of check.RequiredValid check type. String (1..25 chars)
      detailsDetails specific to the check type.OptionalArray
      disabledDisables the check.OptionalBoolean
      labelA friendly label for a check.OptionalString (1..255 chars)
      metadataArbitrary key/value pairs.OptionalArray
      periodThe period in seconds for a check. The value must be greater than the minimum period set on your account.OptionalInteger (30..1800)
      timeoutThe timeout in seconds for a check. This has to be less than the period.OptionalInteger (2..1800)
      +
      +

      Attributes used for remote Checks

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data type
      monitoring_zones_pollList of monitoring zones to poll from. Note: This argument is only required for remote (non-agent) checksOptionalArray
      target_aliasA 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.OptionalString (1..64 chars)
      target_hostnameThe hostname this check should target. This parameter is mutually exclusive with target_alias.OptionalValid FQDN, IPv4 or IPv6 address. String (1..256 chars).
      target_resolverDetermines how to resolve the check target.OptionalIPv4 or IPv6
      +
      +
      +
      +

      Test parameters (before create)

      +
      $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'
      +);
      +
      +// You can do a test to see what would happen
      +// if a Check is launched with these params
      +$response = $entity->testNewCheckParams($params);
      +
      +echo $response->timestamp; // When was it executed?
      +echo $response->available; // Was it available?
      +echo $response->status;    // Status code
      +
      +
      +
      +
      +

      Create a Check

      +
      $entity->createCheck($params);
      +
      +
      +
      +
      +

      Test existing Check

      +
      // Set arg to TRUE for debug information
      +$response = $check->test(true);
      +
      +echo $response->debug_info;
      +
      +
      +
      +
      +

      List Checks

      +
      $checks = $entity->getChecks();
      +
      +foreach ($checks as $check) {
      +    echo $check->getId();
      +}
      +
      +
      +
      +

      Update and delete Check

      +
      // Update
      +$check->update(array('period' => 500));
      +
      +// Delete
      +$check->delete();
      +
      +
      +
      +
      +
      +
      +

      Check types

      +
      +

      Info

      +

      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.

      +
      +
      +

      Setup

      +

      If you want to see the type for an existing Check:

      +
      /** @var \OpenCloud\CloudMonitoring\Resource\CheckType */
      +$checkType = $check->getCheckType();
      +
      +
      +

      Alternatively, you can retrieve a specific type based on its ID:

      +
      $checkTypeId = 'remote.dns';
      +$checkType = $service->getCheckType($checkTypeId);
      +
      +
      +
      +
      +

      Attributes

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      typeThe name of the supported check type.StringgetType()
      fieldsCheck type fields.ArraygetFields()
      supported_platformsPlatforms 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 runtimeArraygetSupportedPlatforms()
      +
      +
      +

      List all possible check types

      +
      $checkTypes = $service->getCheckTypes();
      +
      +foreach ($checkTypes as $checkType) {
      +   echo $checkType->getId();
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Entities.md.html b/doc/_build/html/services/monitoring/Entities.md.html new file mode 100644 index 000000000..ed19e1acc --- /dev/null +++ b/doc/_build/html/services/monitoring/Entities.md.html @@ -0,0 +1,283 @@ + + + + + + + + + +  Entities — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

       Entities

      +
      +

      Info

      +

      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.

      +
      +
      +

      Setup

      +
      $entity = $service->getEntity();
      +
      +
      +

      For more information about setting up the $service object, please +see the userguide tutorial for services.

      +
      +
      +

      Attributes

      + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data typeMethod
      labelDefines a name for the entity.RequiredString (1..255 chars)getLabel()
      agent_idAgent to which this entity is bound to.OptionalString matching the regex: /^[-\.\w]{1,255}$/getAgentId()
      ip_addressesHash of IP addresses that can be referenced by checks on this entity.OptionalArraygetIpAddresses()
      metadataArbitrary key/value pairs that are passed during the alerting phase.OptionalOpenCloud\Common\MetadatagetMetadata()
      +
      +
      +

      Create Entity

      +
      $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'
      +    )
      +));
      +
      +
      +
      +
      +

      Update and delete Entity

      +
      // Update
      +$entity->update(array(
      +    'label' => 'New label for my entity'
      +));
      +
      +// Delete
      +$entity->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Metrics.md.html b/doc/_build/html/services/monitoring/Metrics.md.html new file mode 100644 index 000000000..365595ffd --- /dev/null +++ b/doc/_build/html/services/monitoring/Metrics.md.html @@ -0,0 +1,347 @@ + + + + + + + + + +  Metrics — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

       Metrics

      +
      +

      Info

      +

      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...
      FULL5760
      MIN5576
      MIN20144
      MIN6048
      MIN24012
      MIN14402
      +
      +
      +

      Specifying number of points to retrieve data in 48 hour period

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      You specify points in the range...API calculates resolution
      3168-∞FULL
      360-3167MIN5
      96-359MIN20
      30-95MIN60
      7-29MIN240
      0-6MIN1440
      +
      +
      +

      Data Point Expiration

      +

      Cloud Monitoring expires data points according to the following +schedule:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      ResolutionExpiration
      FULL2 days
      MIN57 days
      MIN2015 days
      MIN6030 days
      MIN24060 days
      MIN1440365 days
      +
      +
      +
      +

       Setup

      +

      Metrics are sub-resources of Checks. For more information about working +with Checks, please see the relevant documentation.

      +
      +
      +

      List all metrics

      +
      $metrics = $check->getMetrics();
      +
      +foreach ($metrics as $metric) {
      +    echo $metric->getName();
      +}
      +
      +
      +
      +
      +

      Fetch data points

      +
      $data = $check->fetchDataPoints('mzdfw.available', array(
      +    'resolution' => 'FULL',
      +    'from'       => 1369756378450,
      +    'to'         => 1369760279018
      +));
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Notifications.md.html b/doc/_build/html/services/monitoring/Notifications.md.html new file mode 100644 index 000000000..59a52dcb4 --- /dev/null +++ b/doc/_build/html/services/monitoring/Notifications.md.html @@ -0,0 +1,513 @@ + + + + + + + + + + Notifications — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Notifications

      +
      +

      Info

      +

      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).

      +
      +
      +

      Setup

      +
      $id = 'ntAAAA';
      +$notification = $service->getNotification($id);
      +
      +
      +
      +
      +

      Attributes

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      detailsA hash of notification specific details based on the notification type.ArraygetDetails()
      labelFriendly name for the notification.String (1..255 chars)getLabel()
      typeThe notification type to send.String. Either webhook, email, or pagerdutygetType()
      +
      +
      +

      Test parameters

      +
      $params = array(
      +    'label' => 'My webhook #1',
      +    'type'  => 'webhook',
      +    'details' => array(
      +        'url' => 'http://example.com'
      +    )
      +);
      +
      +// Test it
      +$response = $notification->testParams($params);
      +
      +if ($response->status == 'Success') {
      +    echo $response->message;
      +}
      +
      +
      +
      +
      +

      Create Notification

      +
      $notification->create($params);
      +
      +
      +
      +
      +

      Test existing notification

      +
      $response = $notification->testExisting(true);
      +echo $response->debug_info;
      +
      +
      +
      +
      +

      List Notifications

      +
      $notifications = $service->getNotifications();
      +
      +foreach ($notifications as $notification) {
      +    echo $notification->getId();
      +}
      +
      +
      +
      +
      +

      Update and delete Notifications

      +
      // Update
      +$notification->update(array(
      +    'label' => 'New notification label'
      +));
      +
      +// Delete
      +$notification->delete();
      +
      +
      +
      +
      +
      +

      Notification types

      +
      +

      Info

      +

      Pretty self-explanatory. 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:

      + +++++ + + + + + + + + + + + + +
      NameDescriptionData type
      addressEmail address to send notifications toValid email
      +
      +
      +

      Email

      +

      Email alerts where the message is delivered to a specified address. It +has these attributes:

      + +++++ + + + + + + + + + + + + +
      NameDescriptionData type
      urlAn HTTP or HTTPS URL to POST toValid 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:

      +
      $type = $notification->getNotificationType();
      +
      +
      +

      Alternatively, you can retrieve an independent resource using the ID:

      +
      $typeId = 'pagerduty';
      +$type = $service->getNotificationType($typeId);
      +
      +
      +
      +
      +

      List all possible notification types

      +
      $types = $service->getNotificationTypes();
      +
      +foreach ($types as $type) {
      +    echo sprintf('%s %s', $type->getName(), $type->getDescription());
      +}
      +
      +
      +
      +
      +
      +

      Notification plans

      +
      +

      Info

      +

      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.

      +
      +
      +

      Setup

      +
      $planId = 'npAAAA';
      +$plan = $service->getNotificationPlan();
      +
      +
      +
      +
      +

      Attributes

      + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data typeMethod
      labelFriendly name for the notification plan.RequiredString (1..255 chars)getLabel()
      critical_stateThe notification list to send to when the state is CRITICAL.OptionalArraygetCriticalState()
      ok_stateThe notification list to send to when the state is OK.OptionalArraygetOkState()
      warning_stateThe notification list to send to when the state is WARNING.OptionalArraygetWarningState()
      +
      +
      +

      Create Notification Plan

      +
      $plan->create(array(
      +    'label'          => 'New Notification Plan',
      +    'critical_state' => array('ntAAAA'),
      +    'ok_state'       => array('ntBBBB'),
      +    'warning_state'  => array('ntCCCC')
      +));
      +
      +
      +
      +
      +

      Update and delete Notification Plan

      +
      // Update
      +$plan->update(array(
      +    'label' => 'New label for my plan'
      +));
      +
      +// Delete
      +$plan->delete();
      +
      +
      +
      +
      +
      +

      Alarm Notification History

      +
      +

      Info

      +

      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

      +

      Notification History is a sub-resource of an Alarm. For more information +about working with Alarms, please consult the relevant +documentation.

      +
      +
      +

      Discover which Checks have a Notification History

      +

      This operation list checks for which alarm notification history is +available:

      +
      $checks = $alarm->getRecordedChecks();
      +
      +
      +
      +
      +

      List Alarm Notification History for a particular Check

      +
      $checkHistory = $alarm->getNotificationHistoryForCheck('chAAAA');
      +
      +
      +
      +
      +

      Get a particular Notification History item

      +
      $checkId  = 'chAAAA';
      +$itemUuid = '646ac7b0-0b34-11e1-a0a1-0ff89fa2fa26';
      +
      +$singleItem = $history->getNotificationHistoryItem($checkId, $itemUuid);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Service.md.html b/doc/_build/html/services/monitoring/Service.md.html new file mode 100644 index 000000000..930f44111 --- /dev/null +++ b/doc/_build/html/services/monitoring/Service.md.html @@ -0,0 +1,203 @@ + + + + + + + + + + Cloud Monitoring Service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Cloud Monitoring Service

      +

      Initializing the Cloud Monitoring is easy - and can be done in a similar +way to all other Rackspace services:

      +
        +
      1. Create client and pass in auth details. For more information about +creating clients, please consult the Client +documentation.
      2. +
      3. Use the factory method, specifying additional parameters where +necessary:
      4. +
      +
      $service = $client->cloudMonitoringService('cloudMonitoring', 'ORD', 'publicURL');
      +
      +
      +

      All three parameters are optional - if not specified, it will revert to +the service’s default values which are:

      +
        +
      • Name = cloudMonitoring
      • +
      • Region = DFW
      • +
      • URL type = publicURL
      • +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Views.md.html b/doc/_build/html/services/monitoring/Views.md.html new file mode 100644 index 000000000..bb2ebdfca --- /dev/null +++ b/doc/_build/html/services/monitoring/Views.md.html @@ -0,0 +1,203 @@ + + + + + + + + + + Views — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Views

      +
      +

      Info

      +

      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

      +

      ```php $views = $service->getViews();

      +

      foreach ($views as $view) { $entity = $view->getEntity();

      +
      echo $view->getTimestamp();
      +
      +
      +

      } ```

      +

      Please consult the iterator doc for +more information about iterators.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/Zones.md.html b/doc/_build/html/services/monitoring/Zones.md.html new file mode 100644 index 000000000..d6808c0d4 --- /dev/null +++ b/doc/_build/html/services/monitoring/Zones.md.html @@ -0,0 +1,263 @@ + + + + + + + + + + Zones — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Zones

      +
      +

      Info

      +

      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.

      +
      +
      +

       Setup

      +
      $zoneId = 'mzAAAAA';
      +$zone = $monitoringService->getMonitoringZone($zoneId);
      +
      +
      +
      +
      +

      Attributes

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      country_codeCountry CodeString longer than 2 charactersgetCountryCode()
      labelLabelStringgetLabel()
      source_ipsSource IP listArraygetSourceIps()
      +
      +
      +

       List all zones

      +
      $zones = $service->getMonitoringZones();
      +
      +
      +

      Please consult the iterator doc for +more information about iterators.

      +
      +
      +

      Perform a traceroute

      +
      $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;
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/agents.html b/doc/_build/html/services/monitoring/agents.html new file mode 100644 index 000000000..20c723912 --- /dev/null +++ b/doc/_build/html/services/monitoring/agents.html @@ -0,0 +1,470 @@ + + + + + + + + + + Agents — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $agent = $service->getAgent('{agentId}');
      +
      +
      +
      +
      +

      List agents

      +
      $agents = $service->getAgents();
      +
      +foreach ($agents as $agent) {
      +   echo $agent->getLastConnected();
      +}
      +
      +
      +
      +
      +

      List connections

      +
      $connections = $agent->getConnections();
      +
      +
      +
      +
      +

      Get connection

      +
      /** @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:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameMethod
      idgetId()
      guidgetGuid()
      agent_idgetAgentId()
      endpointgetEndpoint()
      process_versiongetProcessVersion()
      bundle_versiongetBundleVersion()
      agent_ipgetAgentIp()
      +
      +
      +
      +

      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

      +
      $agentToken = $service->getAgentToken('{tokenId}');
      +
      +
      +
      +
      +

      Create agent token

      +
      $newToken = $service->getAgentToken();
      +$newToken->create(array('label' => 'Foobar'));
      +
      +
      +
      +
      +

      List agent tokens

      +
      $agentTokens = $service->getAgentTokens();
      +
      +foreach ($agentTokens as $token) {
      +    echo $token->getLabel();
      +}
      +
      +
      +
      +
      +

      Update agent token

      +
      $token->update(array(
      +    'label' => 'New label'
      +));
      +
      +
      +
      +
      +

      Update agent token

      +
      $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

      +
      $host = $service->getAgentHost();
      +
      +
      +
      +
      +

      Get some metrics

      +
      $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

      +
      $targets = $service->getAgentTargets();
      +
      +foreach ($targets as $target) {
      +    echo $target->getType();
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/alarms.html b/doc/_build/html/services/monitoring/alarms.html new file mode 100644 index 000000000..2d77a16a8 --- /dev/null +++ b/doc/_build/html/services/monitoring/alarms.html @@ -0,0 +1,407 @@ + + + + + + + + + + Alarms — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $entity = $service->getEntity('{entityId}');
      +
      +
      +

      and then a particular check, about which you can configure alarms:

      +
      $check = $entity->getCheck('{checkId}');
      +
      +
      +

      For more information about these resource types, please consult the documentation +about entities and checks.

      +
      +
      +

      Retrieve alarm

      +
      $alarm = $check->getAlarm('{alarmId}');
      +
      +
      +

      Once you have access to a OpenCloud\Monitoring\Resource\Alarm object, these +are the attributes you can access:

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Method
      check_idThe ID of the check to alert on.RequiredgetCheckId()
      notification_plan_idThe ID of the notification plan to execute when the state changes.OptionalgetNotificationPlanId()
      criteriaThe alarm DSL for describing alerting conditions and their output states.OptionalgetCriteria()
      disabledDisable processing and alerts on this alarmOptionalisDisabled() <bool>
      labelA friendly label for an alarm.OptionalgetLabel()
      metadataArbitrary key/value pairs.OptionalgetMetadata()
      +
      +
      +

      Create Alarm

      +
      $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

      +
      $alarms = $entity->getAlarms();
      +
      +foreach ($alarms as $alarm) {
      +    echo $alarm->getId();
      +}
      +
      +
      +
      +
      +

      Update Alarm

      +
      $alarm->update(array(
      +    'criteria' => 'if (metric["duration"] >= 5) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);'
      +));
      +
      +
      +
      +
      +

      Delete alarm

      +
      $alarm->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/changelogs.html b/doc/_build/html/services/monitoring/changelogs.html new file mode 100644 index 000000000..524d11376 --- /dev/null +++ b/doc/_build/html/services/monitoring/changelogs.html @@ -0,0 +1,309 @@ + + + + + + + + + + Changelogs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $changelog = $service->getChangelog();
      +
      +foreach ($changelog as $item) {
      +   $entity = $item->getEntityId();
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/checks.html b/doc/_build/html/services/monitoring/checks.html new file mode 100644 index 000000000..097026d98 --- /dev/null +++ b/doc/_build/html/services/monitoring/checks.html @@ -0,0 +1,570 @@ + + + + + + + + + + Checks — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data type
      typeThe type of check.RequiredValid check type. String (1..25 chars)
      detailsDetails specific to the check type.OptionalArray
      disabledDisables the check.OptionalBoolean
      labelA friendly label for a check.OptionalString (1..255 chars)
      metadataArbitrary key/value pairs.OptionalArray
      periodThe period in seconds for a check. The value must be greater than the minimum period set on your account.OptionalInteger (30..1800)
      timeoutThe timeout in seconds for a check. This has to be less than the period.OptionalInteger (2..1800)
      +
      +
      +

      Optional attributes to be used with remote checks

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data type
      monitoring_zones_pollList of monitoring zones to poll from. Note: This argument is only required for remote (non-agent) checksOptionalArray
      target_aliasA 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.OptionalString (1..64 chars)
      target_hostnameThe hostname this check should target. This parameter is mutually exclusive with target_alias.OptionalValid FQDN, IPv4 or IPv6 address. String (1..256 chars).
      target_resolverDetermines how to resolve the check target.OptionalIPv4 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:

      +
      $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:

      +
      $entity->createCheck($params);
      +
      +
      +
      +
      +
      +

      Test existing Check

      +
      // Set arg to TRUE for debug information
      +$response = $check->test(true);
      +
      +echo $response->debug_info;
      +
      +
      +
      +
      +

      List Checks

      +
      $checks = $entity->getChecks();
      +
      +foreach ($checks as $check) {
      +    echo $check->getId();
      +}
      +
      +
      +
      +
      +

      Update Check

      +
      $check->update(array('period' => 500));
      +
      +
      +
      +
      +

      Delete check

      +
      $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:

      +
      /** @var \OpenCloud\CloudMonitoring\Resource\CheckType */
      +$checkType = $check->getCheckType();
      +
      +
      +
      +
      +

      List all possible check types

      +
      $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:

      +
      $checkTypeId = 'remote.dns';
      +$checkType = $service->getCheckType($checkTypeId);
      +
      +
      +
      +
      +

      Attributes

      +

      Once you have access to a OpenCloud\CloudMonitoring\Resource\CheckType object, +you can query these attributes:

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      typeThe name of the supported check type.StringgetType()
      fieldsCheck type fields.ArraygetFields()
      supported_platformsPlatforms 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 runtimeArraygetSupportedPlatforms()
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/entities.html b/doc/_build/html/services/monitoring/entities.html new file mode 100644 index 000000000..6b26160af --- /dev/null +++ b/doc/_build/html/services/monitoring/entities.html @@ -0,0 +1,386 @@ + + + + + + + + + +  Entities — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

       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

      +
      $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

      +
      $entity = $service->getEntity('{entityId}');
      +
      +
      +
      +

      Attributes

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      labelDefines a name for the entity.String (1..255 chars)getLabel()
      agent_idAgent to which this entity is bound to.String matching the regex: /^[-\.\w]{1,255}$/getAgentId()
      ip_addressesHash of IP addresses that can be referenced by checks on this entity.ArraygetIpAddresses()
      metadataArbitrary key/value pairs that are passed during the alerting phase.OpenCloud\Common\MetadatagetMetadata()
      +
      +
      +
      +

      Update an entity

      +
      $entity->update(array(
      +    'label' => 'New label for my entity'
      +));
      +
      +
      +
      +
      +

      Delete entity

      +
      $entity->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/index.html b/doc/_build/html/services/monitoring/index.html new file mode 100644 index 000000000..1eec07d17 --- /dev/null +++ b/doc/_build/html/services/monitoring/index.html @@ -0,0 +1,517 @@ + + + + + + + + + + Monitoring v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Monitoring v1

      +
      +

      Note

      +

      This service is only available for Rackspace users.

      +
      +
      +

      Setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +

      Monitoring service

      +

      Now to instantiate the Monitoring service:

      +
      $service = $client->monitoringService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      +
      +

      Operations

      +
      + +
      +
      +
      +

      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:
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/metrics.html b/doc/_build/html/services/monitoring/metrics.html new file mode 100644 index 000000000..1b0bfd6f2 --- /dev/null +++ b/doc/_build/html/services/monitoring/metrics.html @@ -0,0 +1,465 @@ + + + + + + + + + +  Metrics — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

       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...
      FULL5760
      MIN5576
      MIN20144
      MIN6048
      MIN24012
      MIN14402
      +
      +
      +

      Specifying number of points to retrieve data in 48 hour period

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      You specify points in the range...API calculates resolution
      3168-∞FULL
      360-3167MIN5
      96-359MIN20
      30-95MIN60
      7-29MIN240
      0-6MIN1440
      +
      +
      +

      Data Point Expiration

      +

      Cloud Monitoring expires data points according to the following +schedule:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      ResolutionExpiration
      FULL2 days
      MIN57 days
      MIN2015 days
      MIN6030 days
      MIN24060 days
      MIN1440365 days
      +
      +
      +
      +

      Setup

      +

      In order to interact with this feature, you must first retrieve an entity by +its ID:

      +
      $entity = $service->getEntity('{entityId}');
      +
      +
      +

      and then a particular check, about which you can configure alarms:

      +
      $check = $entity->getCheck('{checkId}');
      +
      +
      +

      For more information about these resource types, please consult the documentation +about entities and checks.

      +
      +
      +

      List all metrics

      +
      $metrics = $check->getMetrics();
      +
      +foreach ($metrics as $metric) {
      +    echo $metric->getName();
      +}
      +
      +
      +
      +
      +

      Fetch data points

      +
      $data = $check->fetchDataPoints('mzdfw.available', array(
      +    'resolution' => 'FULL',
      +    'from'       => 1369756378450,
      +    'to'         => 1369760279018
      +));
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/notifications.html b/doc/_build/html/services/monitoring/notifications.html new file mode 100644 index 000000000..4f1bd357f --- /dev/null +++ b/doc/_build/html/services/monitoring/notifications.html @@ -0,0 +1,628 @@ + + + + + + + + + + Notifications — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $notification = $service->getNotification('{id}');
      +
      +
      +

      Once you have access to a OpenCloud\Monitoring\Resource\Notification object, +these are the attributes available for use:

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      detailsA hash of notification specific details based on the notification type.ArraygetDetails()
      labelFriendly name for the notification.String (1..255 chars)getLabel()
      typeThe notification type to send.String. Either webhook, email, or pagerdutygetType()
      +
      +
      +

      Creating notifications

      +

      The first thing to do when creating a new notification is configure the +parameters which will define the behaviour of your resource:

      +
      $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:

      +
      // 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:

      +
      $notification->create($params);
      +
      +
      +
      +
      +
      +

      Test existing notification

      +
      $response = $notification->testExisting(true);
      +echo $response->debug_info;
      +
      +
      +
      +
      +

      List Notifications

      +
      $notifications = $service->getNotifications();
      +
      +foreach ($notifications as $notification) {
      +    echo $notification->getId();
      +}
      +
      +
      +
      +
      +

      Update a Notification

      +
      $notification->update(array(
      +    'label' => 'New notification label'
      +));
      +
      +
      +
      +
      +

      Delete a Notification

      +
      $notification->delete();
      +
      +
      +
      +
      +
      +

      Notification types

      +

      Rackspace Cloud Monitoring currently supports the following notification types:

      +

      Industry-standard web hooks, where JSON is posted to a configurable URL. +It has these attributes:

      + +++++ + + + + + + + + + + + + +
      NameDescriptionData type
      addressEmail address to send notifications toValid email
      +

      Email alerts where the message is delivered to a specified address. It +has these attributes:

      + +++++ + + + + + + + + + + + + +
      NameDescriptionData type
      urlAn HTTP or HTTPS URL to POST toValid 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:

      +
      $type = $notification->getNotificationType();
      +
      +
      +

      Alternatively, you can retrieve an independent resource using the ID:

      +
      $typeId = 'pagerduty';
      +$type = $service->getNotificationType($typeId);
      +
      +
      +
      +
      +

      List all possible notification types

      +
      $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

      +
      $plan = $service->getNotificationPlan('{planId}');
      +
      +
      +

      Once you have access to a OpenCloud\\Monitoring\\Resource\\NotificationPlan +object, you can access these resources:

      + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionRequired?Data typeMethod
      labelFriendly name for the notification plan.RequiredString (1..255 chars)getLabel()
      critical_stateThe notification list to send to when the state is CRITICAL.OptionalArraygetCriticalState()
      ok_stateThe notification list to send to when the state is OK.OptionalArraygetOkState()
      warning_stateThe notification list to send to when the state is WARNING.OptionalArraygetWarningState()
      +
      +
      +

      Create Notification Plan

      +
      $plan->create(array(
      +    'label'          => 'New Notification Plan',
      +    'critical_state' => array('ntAAAA'),
      +    'ok_state'       => array('ntBBBB'),
      +    'warning_state'  => array('ntCCCC')
      +));
      +
      +
      +
      +
      +

      Update notification plan

      +
      $plan->update(array(
      +    'label' => 'New label for my plan'
      +));
      +
      +
      +
      +
      +

      Delete notification plan

      +
      $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:

      +
      $entity = $service->getEntity('{entityId}');
      +
      +
      +

      and then a particular check, about which you can configure alarms:

      +
      $check = $entity->getCheck('{checkId}');
      +
      +
      +

      and finally, retrieve the alarm:

      +
      $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:

      +
      $checks = $alarm->getRecordedChecks();
      +
      +
      +
      +
      +

      List Alarm Notification History for a particular Check

      +
      $checkHistory = $alarm->getNotificationHistoryForCheck('chAAAA');
      +
      +
      +
      +
      +

      Get a particular Notification History item

      +
      $checkId  = 'chAAAA';
      +$itemUuid = '646ac7b0-0b34-11e1-a0a1-0ff89fa2fa26';
      +
      +$singleItem = $history->getNotificationHistoryItem($checkId, $itemUuid);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/views.html b/doc/_build/html/services/monitoring/views.html new file mode 100644 index 000000000..7c018f6c5 --- /dev/null +++ b/doc/_build/html/services/monitoring/views.html @@ -0,0 +1,312 @@ + + + + + + + + + + Views — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $views = $service->getViews();
      +
      +foreach ($views as $view) {
      +    $entity = $view->getEntity();
      +    echo $view->getTimestamp();
      +}
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/monitoring/zones.html b/doc/_build/html/services/monitoring/zones.html new file mode 100644 index 000000000..0a3f60040 --- /dev/null +++ b/doc/_build/html/services/monitoring/zones.html @@ -0,0 +1,366 @@ + + + + + + + + + + Zones — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $zone = $monitoringService->getMonitoringZone('{zoneId}');
      +
      +
      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeMethod
      country_codeCountry CodeString longer than 2 charactersgetCountryCode()
      labelLabelStringgetLabel()
      source_ipsSource IP listArraygetSourceIps()
      +
      +
      +

       List all zones

      +
      $zones = $service->getMonitoringZones();
      +
      +
      +
      +
      +

      Perform a traceroute

      +
      $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;
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/README.md.html b/doc/_build/html/services/networking/README.md.html new file mode 100644 index 000000000..7840bde62 --- /dev/null +++ b/doc/_build/html/services/networking/README.md.html @@ -0,0 +1,310 @@ + + + + + + + + + + Networking — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Networking

      +

      Networking is a service that you can use to create virtual networks +and attach cloud devices such as servers to these networks.

      +
      +

      Concepts

      +
      +
      +

      Concepts

      +

      To use the Networking service effectively, you should understand the +following key concepts:

      +
        +
      • 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.
      • +
      +
      +
      +

      Getting started

      +
      +

      1. Instantiate an OpenStack or Rackspace client.

      +

      To use the Networking service, you must first instantiate a +OpenStack or Rackspace client object.

      +
        +
      • If you are working with an OpenStack cloud, instantiate an +OpenCloud\OpenStack client as follows:

        +
        use OpenCloud\OpenStack;
        +
        +$client = new OpenStack('<OPENSTACK CLOUD IDENTITY ENDPOINT URL>', array(
        +    'username' => '<YOUR OPENSTACK CLOUD ACCOUNT USERNAME>',
        +    'password' => '<YOUR OPENSTACK CLOUD ACCOUNT PASSWORD>'
        +));
        +
        +
        +
      • +
      • If you are working with the Rackspace cloud, instantiate a +OpenCloud\Rackspace client as follows:

        +
        use OpenCloud\Rackspace;
        +
        +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        + ));
        +
        +
        +
      • +
      +
      +
      +

      2. Obtain an Networking service object from the client.

      +

      All Networking operations are done via an networking service object. +To instantiate this object, call the networkingService method on the +$client object. This method takes two arguments:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      PositionDescriptionData typeRequired?Default valueExample value
      1Name of the service, as it appears in the service catalogStringNonull; automatically determined when possiblecloudNetworks
      2Cloud regionStringYes
        +
      • +
      +
      DFW
      +
      $region = '<CLOUD REGION NAME>';
      +$networkingService = $client->networkingService(null, $region);
      +
      +
      +

      Any networks, subnets, and ports created with this +$networkingService instance will be stored in the cloud region +specified by $region.

      +
      +
      +

      3. Create a network.

      +
      $network = $networkingService->createNetwork(array(
      +    'name' => 'My private backend network'
      +));
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Next steps

      +

      Once you have created a network, there is more you can do with it. See +complete user guide for networking.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/USERGUIDE.md.html b/doc/_build/html/services/networking/USERGUIDE.md.html new file mode 100644 index 000000000..0c1c57f60 --- /dev/null +++ b/doc/_build/html/services/networking/USERGUIDE.md.html @@ -0,0 +1,1021 @@ + + + + + + + + + + Complete User Guide for the Networking Service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Complete User Guide for the Networking Service

      +

      Networking is a service that you can use to create virtual networks and +attach cloud devices such as servers to these networks.

      +

      This user guide introduces you the entities in the Networking service — +networks, subnets, and ports — and shows you how to create and manage +these entities.

      + +
      +

      Concepts

      +

      To use the Networking service effectively, you should understand the +following key concepts:

      +
        +
      • Network: An isolated virtual layer-2 broadcast domain that is +typically reserved for the tenant who created it unless it is +configured to be shared. The network is the main entity in the +Networking service. Ports and subnets are always associated with a +network.
      • +
      • Subnet: 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 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 or addresses to be assigned to the interfaces +plugged into them. When IP addresses are associated with a port, this +also implies the port is associated with a subnet because the IP +address is taken from the allocation pool for a specific subnet.
      • +
      +
      +
      +

      Prerequisites

      +
      +

      Client

      +

      To use the Networking service, you must first instantiate a +OpenStack or Rackspace client object.

      +
        +
      • If you are working with an OpenStack cloud, instantiate an +OpenCloud\OpenStack client as follows:

        +
        use OpenCloud\OpenStack;
        +
        +$client = new OpenStack('<OPENSTACK CLOUD IDENTITY ENDPOINT URL>', array(
        +    'username' => '<YOUR OPENSTACK CLOUD ACCOUNT USERNAME>',
        +    'password' => '<YOUR OPENSTACK CLOUD ACCOUNT PASSWORD>'
        +));
        +
        +
        +
      • +
      • If you are working with the Rackspace cloud, instantiate an +OpenCloud\Rackspace client as follows:

        +
        use OpenCloud\Rackspace;
        +
        +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        +));
        +
        +
        +
      • +
      +
      +
      +

      Networking service

      +

      All Networking operations are done via a networking service object. To +instantiate this object, call the networkingService method on the +$client object. This method takes the following arguments:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      PositionDescriptionData typeRequired?Default valueExample value
      1Name of the service, as it appears in the service catalogStringNonull; automatically determined when possiblecloudNetworks
      2Cloud regionStringYes
        +
      • +
      +
      DFW
      +
      $region = '<CLOUD REGION NAME>';
      +$networkingService = $client->networkingService(null, $region);
      +
      +
      +

      Any networks, subnets, and ports created with this +$networkingService instance are stored in the cloud region specified +by $region.

      +
      +
      +
      +

      Networks

      +

      A network is an isolated virtual layer-2 broadcast domain that is +typically reserved for the tenant who created it unless it is configured +to be shared. The network is the main entity in the Networking service. +Ports and subnets are always associated with a network.

      +
      +

      Create a network

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the network. This name might not be unique.StringNonullMy private backend network
      adminStateUpThe administrative state of network. If false (down), the network does not forward packets.BooleanNotruetrue
      sharedSpecifies whether the network resource can be accessed by any tenant.BooleanNofalsefalse
      tenantIdOwner of network. Only admin users can specify a tenant ID other than their own.StringNoSame as tenant creating the network123456
      +

      You can create a network as shown in the following example:

      +
      $network = $networkingService->createNetwork(array(
      +    'name' => 'My private backend network'
      +));
      +/** @var $network OpenCloud\Networking\Resource\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.

      +

      You can create multiple networks as shown in the following example:

      +
      $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:

      +
      $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:

      +
      $network = $networkingService->getNetwork('eb60583c-57ea-41b9-8d5c-8fab2d22224c');
      +/** @var $network OpenCloud\Networking\Resource\Network **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Update a network

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the network. This name might not be unique.StringNonullMy updated private backend network
      adminStateUpThe administrative state of network. If false (down), the network does not forward packets.BooleanNotruetrue
      sharedSpecifies whether the network resource can be accessed by any tenant.BooleanNofalsefalse
      +

      You can update a network as shown in the following example:

      +
      $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:

      +
      $network->delete();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Subnets

      +

      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.

      +
      +

      Create a subnet

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      networkIdNetwork this subnet is associated withStringYes
        +
      • +
      +
      eb60583c-57ea-41b9-8d5c-8fab2d22224c
      ipVersionIP versionInteger (4 or 6)Yes
        +
      • +
      +
      4
      cidrCIDR representing the IP address range for this subnetString (CIDR)Yes
        +
      • +
      +
      192.168.199.0/25
      nameA human-readable name for the subnet. This name might not be unique.StringNonullMy subnet
      gatewayIpIP address of the default gateway used by devices on this subnetString (IP address)NoFirst IP address in CIDR192.168.199.128
      dnsNameserversDNS nameservers used by hosts in this subnetIndexed array of stringsNoEmpty arrayarray('4.4.4.4', '8.8.8.8')
      allocationPoolsSubranges of the CIDR available for dynamic allocation to portsIndexed array of associative arraysNoEvery IP address in CIDR, excluding gateway IP address if configuredarray(array('start' => '192.168.199.2', 'end' => '192.168.199.127'))
      hostRoutesRoutes that should be used by devices with IP addresses from this subnet (not including the local subnet route)Indexed array of associative arraysNoEmpty arrayarray(array('destination' => '1.1.1.0/24', 'nexthop' => '192.168.19.20'))
      enableDhcpSpecifies whether DHCP is enabled for this subnetBooleanNotruefalse
      tenantIdOwner of the subnet. Only admin users can specify a tenant ID other than their own.StringNoSame as tenant creating the subnet123456
      +

      You can create a subnet as shown in the following example:

      +
      $subnet = $networkingService->createSubnet(array(
      +    'name' => 'My subnet',
      +    'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c',
      +    'ipVersion' => 4,
      +    'cidr' => '192.168.199.0/25'
      +));
      +/** @var $subnet OpenCloud\Networking\Resource\Subnet **/
      +
      +
      +

      [ 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.

      +

      You can create multiple subnets as shown in the following example:

      +
      $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:

      +
      $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:

      +
      $subnet = $networkingService->getSubnet('d3f15879-fb11-49bd-a30b-7704fb98ab1e');
      +/** @var $subnet OpenCloud\Networking\Resource\Subnet **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Update a subnet

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the subnet. This name might not be unique.StringNonullMy updated subnet
      gatewayIpIP address of the default gateway used by devices on this subnetString (IP address)NoFirst IP address in CIDR192.168.62.155
      dnsNameserversDNS nameservers used by hosts in this subnetIndexed array of stringsNoEmpty arrayarray('4.4.4.4', '8.8.8.8')
      hostRoutesRoutes that should be used by devices with IP adresses from this subnet (not including the local subnet route)Indexed array of associative arraysNoEmpty arrayarray(array('destination' => '1.1.1.0/24', 'nexthop' => '192.168.17.19'))
      enableDhcpSpecifies whether DHCP is enabled for this subnetBooleanNotruefalse
      +

      You can update a subnet as shown in the following example:

      +
      $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:

      +
      $subnet->delete();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Ports

      +

      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 or addresses to be assigned to the interfaces +plugged into them. When IP addresses are associated with a port, this +also implies the port is associated with a subnet because the IP address +is taken from the allocation pool for a specific subnet.

      +
      +

      Create a port

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      networkIdNetwork this port is associated withStringYes
        +
      • +
      +
      eb60583c-57ea-41b9-8d5c-8fab2d22224c
      nameA human-readable name for the port. This name might not be unique.StringNonullMy port
      adminStateUpThe administrative state of port. If false (down), the port does not forward packets.BooleanNotruetrue
      macAddressMAC address to use on this portString (MAC address in 6-octet form separated by colons)NoGenerated0F:5A:6F:70:E9:5C
      fixedIpsIP addresses for this portIndexed array of associative arraysNoAutomatically allocated from the poolarray(array('subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', 'ipAddress' => '192.168.199.17'))
      deviceIdIdentifies the device (for example, virtual server) using this portStringNonull5e3898d7-11be-483e-9732-b2f5eccd2b2e
      deviceOwnerIdentifies the entity (for example, DHCP agent) using this portStringNonullnetwork:router_interface
      securityGroupsSpecifies the IDs of any security groups associated with this portIndexed array of stringsNoEmpty arrayarray('f0ac4394-7e4a-4409-9701-ba8be283dbc3')
      tenantIdOwner of the port. Only admin users can specify a tenant ID other than their own.StringNoSame as the tenant creating the port123456
      +

      You can create a port as shown in the following example:

      +
      $port = $networkingService->createPort(array(
      +    'name' => 'My port',
      +    'networkId' => 'eb60583c-57ea-41b9-8d5c-8fab2d22224c'
      +));
      +/** @var $port OpenCloud\Networking\Resource\Port **/
      +
      +
      +

      [ 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.

      +

      You can create multiple ports as shown in the following example:

      +
      $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:

      +
      $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:

      +
      $port = $networkingService->getPort('75906d20-6625-11e4-9803-0800200c9a66');
      +/** @var $port OpenCloud\Networking\Resource\Port **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Update a port

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the port. This name might not be unique.StringNonullMy port
      adminStateUpThe administrative state of port. If false (down), the port does not forward packets.BooleanNotruetrue
      fixedIpsIP addresses for this portIndexed array of associative arraysNoAutomatically allocated from the poolarray(array('subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', 'ipAddress' => '192.168.199.59'))
      deviceIdIdentifies the device (for example, virtual server) using this portStringNonull5e3898d7-11be-483e-9732-b2f5eccd2b2e
      deviceOwnerIdentifies the entity (for example, DHCP agent) using this portStringNonullnetwork:router_interface
      securityGroupsSpecifies the IDs of any security groups associated with this portIndexed array of stringsNoEmpty arrayarray('f0ac4394-7e4a-4409-9701-ba8be283dbc3')
      +

      You can update a port as shown in the following example:

      +
      $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:

      +
      $port->delete();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/index.html b/doc/_build/html/services/networking/index.html new file mode 100644 index 000000000..2f6c08518 --- /dev/null +++ b/doc/_build/html/services/networking/index.html @@ -0,0 +1,422 @@ + + + + + + + + + + Networking v2 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Networking v2

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Networking service

      +

      Now to instantiate the Networking service:

      +
      $service = $client->networkingService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/networks.html b/doc/_build/html/services/networking/networks.html new file mode 100644 index 000000000..cd173a910 --- /dev/null +++ b/doc/_build/html/services/networking/networks.html @@ -0,0 +1,465 @@ + + + + + + + + + + Networks — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Networks

      +
      +

      Create a network

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the network. This name might not be unique.StringNonullMy private backend network
      adminStateUpThe administrative state of network. If false (down), the network does not forward packets.BooleanNotruetrue
      sharedSpecifies whether the network resource can be accessed by any tenant.BooleanNofalsefalse
      tenantIdOwner of network. Only admin users can specify a tenant ID other than their own.StringNoSame as tenant creating the network123456
      +

      You can create a network as shown in the following example:

      +
      /** @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.

      +

      You can create multiple networks as shown in the following example:

      +
      $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:

      +
      $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:

      +
      /** @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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the network. This name might not be unique.StringNonullMy updated private backend network
      adminStateUpThe administrative state of network. If false (down), the network does not forward packets.BooleanNotruetrue
      sharedSpecifies whether the network resource can be accessed by any tenant.BooleanNofalsefalse
      +

      You can update a network as shown in the following example:

      +
      $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:

      +
      $network->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/ports.html b/doc/_build/html/services/networking/ports.html new file mode 100644 index 000000000..f80f748a5 --- /dev/null +++ b/doc/_build/html/services/networking/ports.html @@ -0,0 +1,529 @@ + + + + + + + + + + Ports — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Ports

      +
      +

      Create a port

      +

      This operation takes one parameter, an associative array, with the following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      networkIdNetwork this port is associated withStringYes
        +
      • +
      +
      eb60583c-57ea-41b9-8d5c-8fab2d22224c
      nameA human-readable name for the port. This name might not be unique.StringNonullMy port
      adminStateUpThe administrative state of port. If false (down), the port does not forward packets.BooleanNotruetrue
      macAddressMAC address to use on this portString (MAC address in 6-octet form separated by colons)NoGenerated0F:5A:6F:70:E9:5C
      fixedIpsIP addresses for this portIndexed array of associative arraysNoAutomatically allocated from the poolarray(array('subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', 'ipAddress' => '192.168.199.17'))
      deviceIdIdentifies the device (for example, virtual server) using this portStringNonull5e3898d7-11be-483e-9732-b2f5eccd2b2e
      deviceOwnerIdentifies the entity (for example, DHCP agent) using this portStringNonullnetwork:router_interface
      securityGroupsSpecifies the IDs of any security groups associated with this portIndexed array of stringsNoEmpty arrayarray('f0ac4394-7e4a-4409-9701-ba8be283dbc3')
      tenantIdOwner of the port. Only admin users can specify a tenant ID other than their own.StringNoSame as the tenant creating the port123456
      +

      You can create a port as shown in the following example:

      +
      /** @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.

      +

      You can create multiple ports as shown in the following example:

      +
      $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:

      +
      $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:

      +
      /** @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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the port. This name might not be unique.StringNonullMy port
      adminStateUpThe administrative state of port. If false (down), the port does not forward packets.BooleanNotruetrue
      fixedIpsIP addresses for this portIndexed array of associative arraysNoAutomatically allocated from the poolarray(array('subnetId' => '75906d20-6625-11e4-9803-0800200c9a66', 'ipAddress' => '192.168.199.59'))
      deviceIdIdentifies the device (for example, virtual server) using this portStringNonull5e3898d7-11be-483e-9732-b2f5eccd2b2e
      deviceOwnerIdentifies the entity (for example, DHCP agent) using this portStringNonullnetwork:router_interface
      securityGroupsSpecifies the IDs of any security groups associated with this portIndexed array of stringsNoEmpty arrayarray('f0ac4394-7e4a-4409-9701-ba8be283dbc3')
      +

      You can update a port as shown in the following example:

      +
      $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:

      +
      $port->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/security-group-rules.html b/doc/_build/html/services/networking/security-group-rules.html new file mode 100644 index 000000000..3b6436115 --- /dev/null +++ b/doc/_build/html/services/networking/security-group-rules.html @@ -0,0 +1,410 @@ + + + + + + + + + + Security Group Rules — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Security Group Rules

      +
      +

      Create a security group rule

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      securityGroupIdThe security group ID to associate with this security group rule.StringYes
        +
      • +
      +
      2076db17-a522-4506-91de-c6dd8e837028
      directionThe 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
      ethertypeMust be IPv4 or IPv6, and addresses represented in CIDR must match the ingress or egress rules.String (IPv4 or IPv6)NoIPv4IPv6
      portRangeMinThe 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.IntegerNonull80
      portRangeMaxThe 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.IntegerNonull80
      protocolThe protocol that is matched by the security group rule.String (tcp, udp, icmp)Nonulltcp
      remoteGroupIdThe remote group ID to be associated with this security group rule. You can specify either remoteGroupId or remoteGroupPrefix.StringOptionalnull85cc3048-abc3-43cc-89b3-377341426ac5
      remoteIpPrefixThe remote IP prefix to be associated with this security group rule. You can specify either remoteGroupId or remoteGroupPrefix.StringOptionalnull192.168.5.0
      +

      You can create a security group rule as shown in the following example:

      +
      /** @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:

      +
      $securityGroupRules = $networkingService->listSecurityGroupRules();
      +foreach ($securityGroupRules as $securityGroupRule) {
      +    /** @var $securityGroupRule OpenCloud\Networking\Resource\SecurityGroupRule **/
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/security-groups.html b/doc/_build/html/services/networking/security-groups.html new file mode 100644 index 000000000..97e294709 --- /dev/null +++ b/doc/_build/html/services/networking/security-groups.html @@ -0,0 +1,378 @@ + + + + + + + + + + Security Groups — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Security Groups

      +
      +

      Create a security group

      +

      This operation takes one parameter, an associative array, with the +following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the security group. This name might not be unique.StringYes
        +
      • +
      +
      new-webservers
      descriptionDescription of the security group.StringNonullsecurity group for webservers
      +

      You can create a security group as shown in the following example:

      +
      /** @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:

      +
      $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:

      +
      /** @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:

      +
      $securityGroup->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/networking/subnets.html b/doc/_build/html/services/networking/subnets.html new file mode 100644 index 000000000..980c048ee --- /dev/null +++ b/doc/_build/html/services/networking/subnets.html @@ -0,0 +1,538 @@ + + + + + + + + + + Subnets — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Subnets

      +
      +

      Create a subnet

      +

      This operation takes one parameter, an associative array, with the following keys:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      networkIdNetwork this subnet is associated withStringYes
        +
      • +
      +
      eb60583c-57ea-41b9-8d5c-8fab2d22224c
      ipVersionIP versionInteger (4 or 6)Yes
        +
      • +
      +
      4
      cidrCIDR representing the IP address range for this subnetString (CIDR)Yes
        +
      • +
      +
      192.168.199.0/25
      nameA human-readable name for the subnet. This name might not be unique.StringNonullMy subnet
      gatewayIpIP address of the default gateway used by devices on this subnetString (IP address)NoFirst IP address in CIDR192.168.199.128
      dnsNameserversDNS nameservers used by hosts in this subnetIndexed array of stringsNoEmpty arrayarray('4.4.4.4', '8.8.8.8')
      allocationPoolsSubranges of the CIDR available for dynamic allocation to portsIndexed array of associative arraysNoEvery IP address in CIDR, excluding gateway IP address if configuredarray(array('start' => '192.168.199.2', 'end' => '192.168.199.127'))
      hostRoutesRoutes that should be used by devices with IP addresses from this subnet (not including the local subnet route)Indexed array of associative arraysNoEmpty arrayarray(array('destination' => '1.1.1.0/24', 'nexthop' => '192.168.19.20'))
      enableDhcpSpecifies whether DHCP is enabled for this subnetBooleanNotruefalse
      tenantIdOwner of the subnet. Only admin users can specify a tenant ID other than their own.StringNoSame as tenant creating the subnet123456
      +

      You can create a subnet as shown in the following example:

      +
      /** @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.

      +

      You can create multiple subnets as shown in the following example:

      +
      $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:

      +
      $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:

      +
      /** @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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameA human-readable name for the subnet. This name might not be unique.StringNonullMy updated subnet
      gatewayIpIP address of the default gateway used by devices on this subnetString (IP address)NoFirst IP address in CIDR192.168.62.155
      dnsNameserversDNS nameservers used by hosts in this subnetIndexed array of stringsNoEmpty arrayarray('4.4.4.4', '8.8.8.8')
      hostRoutesRoutes that should be used by devices with IP adresses from this subnet (not including the local subnet route)Indexed array of associative arraysNoEmpty arrayarray(array('destination' => '1.1.1.0/24', 'nexthop' => '192.168.17.19'))
      enableDhcpSpecifies whether DHCP is enabled for this subnetBooleanNotruefalse
      +

      You can update a subnet as shown in the following example:

      +
      $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:

      +
      $subnet->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Access.md.html b/doc/_build/html/services/object-store/Access.md.html new file mode 100644 index 000000000..11ddcb6d3 --- /dev/null +++ b/doc/_build/html/services/object-store/Access.md.html @@ -0,0 +1,246 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(RACKSPACE_US, array(
      +
      +));
      +
      +$service = $client->objectStoreService('cloudFiles', 'IAD'); # Second argument is the region you want
      +
      +
      +
      +
      +

      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:

      +
      $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:

      +
      $object->getTemporaryUrl(60, 'GET');
      +
      +
      +

      To allow PUT access for 1 hour:

      +
      $object->getTemporaryUrl(360, 'PUT');
      +
      +
      +
      +
      +
      +

      Hosting websites on CloudFiles

      +

      To host a static (i.e. HTML) website on CloudFiles, you must follow +these steps:

      +
        +
      1. CDN-enable a container
      2. +
      3. Upload all HTML content. You can use nested directory structures.
      4. +
      5. Tell CloudFiles what to use for your default index page like this:
      6. +
      +
      $container->setStaticIndexPage('index.html');
      +
      +
      +
        +
      1. (Optional) Tell CloudFiles which error page to use by default:
      2. +
      +
      $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.

      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Account.md.html b/doc/_build/html/services/object-store/Account.md.html new file mode 100644 index 000000000..3e2c8a35b --- /dev/null +++ b/doc/_build/html/services/object-store/Account.md.html @@ -0,0 +1,211 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(RACKSPACE_US, array(
      +
      +));
      +
      +$service = $client->objectStoreService('cloudFiles');
      +
      +
      +
      +
      +

      View 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):

      +
      $account = $service->getAccount();
      +
      +// Either return the full Metadata object
      +$details = $account->getDetails();
      +
      +// or individual values
      +$account->getContainerCount();
      +$account->getObjectCount();
      +$account->getBytesUsed();
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Container.md.cdn.html b/doc/_build/html/services/object-store/Container.md.cdn.html new file mode 100644 index 000000000..ea070d286 --- /dev/null +++ b/doc/_build/html/services/object-store/Container.md.cdn.html @@ -0,0 +1,257 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(RACKSPACE_US, array(
      +
      +));
      +
      +$service = $client->objectStoreService('cloudFiles');
      +
      +
      +

      To access the CDN functionality of a particular container:

      +
      $container = $service->getContainer('foo_bar');
      +
      +$cdn = $container->getCdn();
      +
      +
      +
      +
      +

      List CDN-enabled container

      +

      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:

      +
      $cdnService = $service->getCdnService();
      +$cdnContainers = $cdnService->listContainers();
      +
      +foreach ($cdnContainers as $cdnContainer) {
      +
      +}
      +
      +
      +
      +
      +

      CDN-enable and -disable 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.

      +
      $container->enableCdn();
      +$container->disableCdn();
      +
      +
      +
      +
      +

      Serving containers through SSL

      +
      $cdn->getCdnSslUri();
      +
      +
      +
      +
      +

      Streaming CDN-enabled containers

      +
      $cdn->getCdnStreamingUri();
      +
      +
      +
      +
      +

      iOS streaming

      +

      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.

      +
      $cdn->getIosStreamingUri();
      +
      +
      +
      +
      +

      CDN logging

      +

      To enable and disable logging for your CDN:

      +
      $cdn->enableCdnLogging();
      +$cdn->disableCdnLogging();
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Container.md.storage.html b/doc/_build/html/services/object-store/Container.md.storage.html new file mode 100644 index 000000000..34b83dc68 --- /dev/null +++ b/doc/_build/html/services/object-store/Container.md.storage.html @@ -0,0 +1,393 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +
      use OpenCloud\Rackspace;
      +
      +// Create a client object to communicate with various Rackspace Cloud services.
      +$client = new Rackspace(RACKSPACE_US, array(
      +    'username' => 'Replace this with your Rackspace Cloud user name',
      +    'apiKey' => 'Replace this with your Rackspace Cloud API key'
      +));
      +
      +// Create a service object to use the object store service. The sample code
      +// creates the object store in the 'DFW' region.
      +$service = $client->objectStoreService('cloudFiles', 'DFW');
      +
      +
      +
      +
      +

      Create container

      +

      To create a new container, you just need to define its name:

      +
      $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 <http://php.net/urlencode>`__ before passing them in
      +
      +
      +

      List containers

      +
      +

      Return a list of containers

      +
      $containerList = $service->listContainers();
      +
      +while ($container = $containerList->next()) {
      +    // Do stuff; some examples below
      +    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. See 1.3 for ways to +limit and navigate this list.

      +
      +
      +

      Return a formatted list of containers

      +

      Currently, the SDK only supports JSON-formatted responses.

      +
      +
      +

      Controlling a large list of containers

      +

      You may limit and control this list of results 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:

      +
      $someContainers = $service->listContainers(array(
      +    'marker'     => 'container_55',
      +    'end_marker' => 'container_2001'
      +));
      +
      +
      +

      Or to return a limited set:

      +
      $someContainers = $service->listContainers(array('limit' => 560));
      +
      +
      +
      +
      +
      +

      Get container

      +

      To retrieve a certain container, either to access its object or +metadata:

      +
      $container = $service->getContainer('container_name');
      +
      +echo $container->getObjectCount();
      +echo $container->getBytesUsed();
      +
      +
      +
      +
      +

      Delete container

      +

      Deleting a container is easy:

      +
      $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:

      +
      $container->delete(TRUE);
      +
      +
      +

      You can also do it manually:

      +
      $container->deleteAllObjects();
      +$container->delete();
      +
      +
      +
      +
      +

      Create or update container metadata

      +
      $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:

      +
      $metadata = $container->appendToMetadata(array(
      +    'Publisher' => 'Hogarth'
      +));
      +
      +
      +

      If you only want to set the metadata to the local object, and not +immediately retain these values on the API, you can use a standard +setter method - which can contribute to eventual actions like an update:

      +
      $container->setMetadata(array('Foo' => 'Bar'));
      +
      +
      +
      +
      +

      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:

      +
      use OpenCloud\Common\Constants\Size;
      +
      +$container->setCountQuota(1000);
      +$container->setBytesQuota(2.5 * Size::GB);
      +
      +
      +

      And to retrieve them:

      +
      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).

      +
      $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:

      +
      $container->uploadDirectory('/home/Jamie/blog');
      +
      +
      +

      There are four scenarios you should be aware of:

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      LocalRemoteComparisonAction
      File existsFile existsIdentical checksumNo action
      File existsFile existsDifferent checksumLocal file overwrites remote
      File existsFile does not exist
        +
      • +
      +
      Local file created in Swift
      Files does not existFile exists
        +
      • +
      +
      Remote file deleted
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Migrating.md.storage.html b/doc/_build/html/services/object-store/Migrating.md.storage.html new file mode 100644 index 000000000..c831f7294 --- /dev/null +++ b/doc/_build/html/services/object-store/Migrating.md.storage.html @@ -0,0 +1,289 @@ + + + + + + + + + + Migrating containers (across regions) — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Migrating containers (across regions)

      +
      +

      Introduction

      +

      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:
      • +
      +
      php composer.phar install --dev
      +
      +
      +
        +
      • Depending on the size and number of transfer items, you will need to +raise PHP’s memory limit:
      • +
      +
      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:
      • +
      +
      use Guzzle\Plugin\Backoff\BackoffPlugin;
      +
      +$client->addSubscriber(BackoffPlugin::getExponentialBackoff(10, array(500, 503, 408)));
      +
      +
      +

      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:

      +
      $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:

      +
      $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:

      +
      $options = array(
      +    'read.batchLimit'  => 100,
      +    'read.pageLimit'   => 100,
      +    'write.batchLimit' => 50
      +);
      +
      +$iadService->migrateContainer($oldContainer, $newContainer, $options);
      +
      +
      +
      +

      Options explained

      + +++++ + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionDefault
      read.pageLimitWhen 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.batchLimitAfter 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.batchLimitOnce 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
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Object.md.cdn.html b/doc/_build/html/services/object-store/Object.md.cdn.html new file mode 100644 index 000000000..8e408b951 --- /dev/null +++ b/doc/_build/html/services/object-store/Object.md.cdn.html @@ -0,0 +1,201 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +

      You will need to instantiate the container object and access its CDN +functionality as documented +here.

      +
      +
      +

      Purge CDN-enabled objects

      +

      To remove a CDN object from public access:

      +
      $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:

      +
      $object->purge('jamie.hannaford@rackspace.com');
      +$object->purge('hello@example.com,hallo@example.com');
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/Object.md.storage.html b/doc/_build/html/services/object-store/Object.md.storage.html new file mode 100644 index 000000000..0dd100f28 --- /dev/null +++ b/doc/_build/html/services/object-store/Object.md.storage.html @@ -0,0 +1,480 @@ + + + + + + + + + + Setup — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Setup

      +

      Conceptually, a container contains objects (also known as files). In +order to work with objects, you will need to instantiate a container +object first as documented +here.

      +
      +
      +

      Note on object properties

      +

      Please be aware that you cannot directly access the properties of +DataObject anymore, you must use appropriate getter/ setter methods:

      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PropertyMethod
      Parent containergetContainer
      NamegetName
      Body of filegetContent
      Size of filegetContentLength
      Type of filegetContentType
      ETag checksumgetEtag
      Last modified dategetLastModified
      +
      +
      +

      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 <http://php.net/urlencode>`__ before passing them in

      +
      +
      +

      To upload a single/basic file:

      +
      use OpenCloud\ObjectStore\Resource\DataObject;
      +
      +$data = fopen('/path/to/sample.mp3', 'r+');
      +
      +// alternatively, you can pass in a string as the file contents `$data` argument (instead of a resource)
      +
      +$meta = array(
      +    'Author' => 'Camera Obscura',
      +    'Origin' => 'Glasgow'
      +);
      +
      +$metaHeaders = DataObject::stockHeaders($meta);
      +$customHeaders = array();
      +$allHeaders = $metaHeaders + $customHeaders;
      +
      +$container->uploadObject('sample.mp3', $data, $allHeaders);
      +
      +
      +
      +
      +

      To upload multiple small-to-mid sized files:

      +
      $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.

      +
      +
      +

      To upload large files

      +

      For files over 5GB, you will need to use the +OpenCloud\ObjectStore\Upload\TransferBuilder factory to build your +transfer, upon which you can execute your upload functionality. For your +convenience, the Container resource object contains a simple method to +do this heavy lifting for you:

      +
      $transfer = $container->setupObjectTransfer(array(
      +    'name' => 'video.mov',
      +    'path' => '/home/jamie/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 manifest 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.

      +
      +
      +
      +

      List objects in a container

      +

      To return a list of objects:

      +
      $files = $container->objectList();
      +
      +foreach ($files as $file) {
      +    // ... do something
      +}
      +
      +
      +

      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.

      +
      $container->objectList(array('prefix' => 'logFile_'));
      +
      +
      +
      +
      +

      Get object

      +

      To retrieve a specific file from Cloud Files:

      +
      $file = $container->getObject('summer_vacation.mp4');
      +
      +
      +
      +

      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

      +
      $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):

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

      +
      $snippet = $container->getObject('output.log', array('range' => 'bytes=-20'));
      +
      +
      +
      +
      +
      +

      Update an existing object

      +

      Updating content is easy:

      +
      $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 copy a file to another location, you need to specify a string-based +destination path:

      +
      $object->copy('/container_2/new_object_name');
      +
      +
      +
      +
      +

      Delete object

      +
      $object->delete();
      +
      +
      +
      +
      +

      Get object metadata

      +

      You can fetch just the object metadata without fetching the full +content:

      +
      $container->getPartialObject('summer_vacation.mp4');
      +
      +
      +

      In order to access the metadata on a partial or complete object, use:

      +
      $object->getMetadata();
      +
      +
      +

      You can turn a partial object into a full object to get the content +after looking at the metadata:

      +
      $object->refresh();
      +
      +
      +

      You can also update to get the latest metadata:

      +
      $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):

      +
      // 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:

      +
      $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:

      +
      $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:

      +
      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.

      +
      +
      +

      Bulk delete

      +

      Bulk delete a set of paths:

      +
      $pathsToBeDeleted = array('/container_1/old_file', '/container_2/notes.txt', '/container_1/older_file.log');
      +
      +$service->bulkDelete($pathsToBeDeleted);
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/README.md.html b/doc/_build/html/services/object-store/README.md.html new file mode 100644 index 000000000..c43489305 --- /dev/null +++ b/doc/_build/html/services/object-store/README.md.html @@ -0,0 +1,259 @@ + + + + + + + + + + Object Store — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Object Store

      +

      Object Store is an object-based storage system that stores content +and metadata as objects in a cloud.

      +

      Specifically, a cloud is made up of one or more regions. Each region can +have several containers, created by a user. Each container can +container several objects (sometimes referred to as files), uploaded +by the user.

      +
      +

      Getting started

      +
      +

      1. Instantiate an OpenStack or Rackspace client.

      +

      Choose one of the following two options:

      +
        +
      • If you are working with a vanilla OpenStack cloud, instantiate an +OpenCloud\OpenStack client as shown below.

        +
        use OpenCloud\OpenStack;
        +
        + $client = new OpenStack('<OPENSTACK CLOUD IDENTITY ENDPOINT URL>', array(
        +     'username' => '<YOUR OPENSTACK USERNAME>',
        +     'password' => '<YOUR OPENSTACK PASSWORD>'
        + ));
        +
        +
        +
      • +
      • If you are working with the Rackspace cloud, instantiate a +OpenCloud\Rackspace client as shown below.

        +
        use OpenCloud\Rackspace;
        +
        +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        + ));
        +
        +
        +
      • +
      +
      +
      +

      2. Obtain an Object Store service object from the client.

      +
      $region = 'DFW';
      +$objectStoreService = $client->objectStoreService(null, $region);
      +
      +
      +

      In the example above, you are connecting to the DFW region of the +cloud. Any containers and objects created with this +$objectStoreService instance will be stored in that cloud region.

      +
      +
      +

      3. Create a container for your objects (also referred to as files).

      +
      $container = $objectStoreService->createContainer('logos');
      +
      +**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`` <http://php.net/urlencode>`__ before passing them in
      +
      +
      +
      +
      +

      4. Upload an object to the container.

      +
      $localFileName  = '/path/to/local/php-elephant.jpg';
      +$remoteFileName = 'php-elephant.jpg';
      +
      +$fileData = fopen($localFileName, 'r');
      +$container->uploadObject($remoteFileName, $fileData);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Next steps

      +

      There is a lot more you can do with containers and objects. See the +complete user guide to the Object Store service.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/USERGUIDE.md.html b/doc/_build/html/services/object-store/USERGUIDE.md.html new file mode 100644 index 000000000..93b698869 --- /dev/null +++ b/doc/_build/html/services/object-store/USERGUIDE.md.html @@ -0,0 +1,1014 @@ + + + + + + + + + + The Complete User Guide to the Object Store Service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      The Complete User Guide to the Object Store Service

      +

      Object Store is an object-based storage system that stores content +and metadata as objects in a cloud.

      +
      +

      Prerequisites

      +
      +

      Client

      +

      To use the object store service, you must first instantiate a +OpenStack or Rackspace client object.

      +
        +
      • If you are working with a vanilla OpenStack cloud, instantiate an +OpenCloud\OpenStack client as shown below.

        +
        use OpenCloud\OpenStack;
        +
        +$client = new OpenStack('<OPENSTACK CLOUD IDENTITY ENDPOINT URL>', array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        +));
        +
        +
        +
      • +
      • If you are working with the Rackspace cloud, instantiate a +OpenCloud\Rackspace client as shown below.

        +
        use OpenCloud\Rackspace;
        +
        +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        +));
        +
        +
        +
      • +
      +
      +
      +

      Object Store Service

      +

      All operations on the object store are done via an object store service +object.

      +
      $region = 'DFW';
      +$objectStoreService = $client->objectStoreService(null, $region);
      +
      +
      +

      In the example above, you are connecting to the DFW region of the +cloud. Any containers and objects created with this +$objectStoreService instance will be stored in that cloud region.

      +
      +
      +
      +

      Containers

      +

      A container defines a namespace for objects. An object with the +same name in two different containers represents two different objects.

      +

      For example, you may create a container called logos to hold all the +image files for your blog.

      +

      A container may contain zero or more objects in it.

      +
      +
      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 <http://php.net/urlencode>`__ before passing them in
      +
      +

      Create Container

      +
      $container = $objectStoreService->createContainer('logos');
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Get Container Details

      +

      You can retrieve a single container’s details by using its name. An +instance of OpenCloud\ObjectStore\Resource\Container is returned.

      +
      $container = $objectStoreService->getContainer('logos');
      +
      +/** @var $container OpenCloud\ObjectStore\Resource\Container **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      List Containers

      +

      You can retrieve a list of all your containers. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $containers = $objectStoreService->listContainers();
      +foreach ($containers as $container) {
      +    /** @var $container OpenCloud\ObjectStore\Resource\Container  **/
      +}
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Set or Update Container Metadata

      +

      You can set metadata on a container.

      +
      $container->saveMetadata(array(
      +    'author' => 'John Doe'
      +));
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Get Container Metadata

      +

      You can retrieve the metadata for a container.

      +
      $containerMetadata = $container->getMetadata();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Delete Container

      +

      When you no longer have a need for the container, you can remove it.

      +

      If the container is empty (that is, it has no objects in it), you can +remove it as shown below:

      +
      $container->delete();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      If the container is not empty (that is, it has objects in it), you have +two choices in how to remove it:

      + +
      +
      +

      Get Object Count

      +

      You can quickly find out how many objects are in a container.

      +
      $containerObjectCount = $container->getObjectCount();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, $containerObjectCount will contain the number +of objects in the container represented by $container.

      +
      +
      +

      Get Bytes Used

      +

      You can quickly find out the space used by a container, in bytes.

      +
      $containerSizeInBytes = $container->getBytesUsed();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, $containerSizeInBytes will contain the space +used, in bytes, by the container represented by $container.

      +
      +
      +

      Container Quotas

      +
      +

      Set Quota for Number of Objects

      +

      You can set a quota for the maximum number of objects that may be stored +in a container.

      +
      $maximumNumberOfObjectsAllowedInContainer = 25;
      +$container->setCountQuota($maximumNumberOfObjectsAllowedInContainer);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Set Quota for Total Size of Objects

      +

      You can set a quota for the maximum total space (in bytes) used by +objects in a container.

      +
      use OpenCloud\Common\Constants\Size;
      +
      +$maximumTotalSizeOfObjectsInContainer = 5 * Size::GB;
      +$container->setBytesQuota($maximumTotalSizeOfObjectsInContainer);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Get Quota for Number of Objects

      +

      You can retrieve the quota for the maximum number of objects that may be +stored in a container.

      +
      $maximumNumberOfObjectsAllowedInContainer = $container->getCountQuota();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Get Quota for Total Size of Objects

      +

      You can retrieve the quota for the maximum total space (in bytes) used +by objects in a container.

      +
      $maximumTotalSizeOfObjectsAllowedInContainer = $container->getBytesQuota();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +
      +

      Objects

      +

      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.

      +

      For example, you may upload an object named php-elephant.jpg, a JPEG +image file, to the logos container. Further, you may assign metadata +to this object to indicate that the author of this object was someone +named Jane Doe.

      +
      +
      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 <http://php.net/urlencode>`__ before passing them in
      +
      +

      Upload Object

      +

      Once you have created a container, you can upload objects to it.

      +
      $localFileName  = '/path/to/local/php-elephant.jpg';
      +$remoteFileName = 'php-elephant.jpg';
      +
      +$fileData = fopen($localFileName, 'r');
      +$container->uploadObject($remoteFileName, $fileData);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, an image file from the local filesystem +(path/to/local/php-elephant.jpg) is uploaded to a container in the +Object Store.

      +

      Note that while we call fopen to open the file resource, we do not +call fclose at the end. The file resource is automatically closed +inside the uploadObject call.

      +

      It is also possible to upload an object and associate metadata with it.

      +
      use OpenCloud\ObjectStore\Resource\DataObject;
      +
      +$localFileName  = '/path/to/local/php-elephant.jpg';
      +$remoteFileName = 'php-elephant.jpg';
      +$metadata = array('author' => 'Jane Doe');
      +
      +$customHeaders = array();
      +$metadataHeaders = DataObject::stockHeaders($metadata);
      +$allHeaders = $customHeaders + $metadataHeaders;
      +
      +$fileData = fopen($localFileName, 'r');
      +$container->uploadObject($remoteFileName, $fileData, $allHeaders);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      Note that while we call fopen to open the file resource, we do not +call fclose at the end. The file resource is automatically closed +inside the uploadObject call.

      +
      +

      Pseudo-hierarchical Folders

      +

      Although you cannot nest directories in an Object Store, you can +simulate a hierarchical structure within a single container by adding +forward slash characters (/) in the object name.

      +
      $localFileName  = '/path/to/local/php-elephant.jpg';
      +$remoteFileName = 'languages/php/elephant.jpg';
      +
      +$fileData = fopen($localFileName, 'r');
      +$container->uploadObject($remoteFileName, $fileData);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, an image file from the local filesystem +(/path/to/local/php-elephant.jpg) is uploaded to a container in the +Object Store. Within that container, the filename is +languages/php/elephant.jpg, where languages/php/ is a +pseudo-hierarchical folder hierarchy.

      +

      Note that while we call fopen to open the file resource, we do not +call fclose at the end. The file resource is automatically closed +inside the uploadObject call.

      +
      +
      +

      Upload Multiple Objects

      +

      You can upload more than one object at a time to a container.

      +
      $objects = array(
      +    array(
      +        'name' => 'php-elephant.jpg',
      +        'path'   => '/path/to/local/php-elephant.jpg'
      +    ),
      +    array(
      +        'name' => 'python-snake.jpg',
      +        'path'   => '/path/to/local/python-snake.jpg'
      +    ),
      +    a
      +);
      +
      +$container->uploadObjects($objects);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the above example, the contents of two files present on the local +filesystem are uploaded as objects to the container referenced by +$container.

      +

      Instead of specifying the path key in an element of the $objects +array, you can specify a body key whose value is a string or a +stream representation.

      +

      Finally, you can pass headers as the second parameter to the +uploadObjects method. These headers will be applied to every object +that is uploaded.

      +
      $metadata = array('author' => 'Jane Doe');
      +
      +$customHeaders = array();
      +$metadataHeaders = DataObject::stockHeaders($metadata);
      +$allHeaders = $customHeaders + $metadataHeaders;
      +
      +$container->uploadObjects($objects, $allHeaders);
      +
      +
      +

      [ Get the executable PHP script for this +example +]

      +

      In the example above, every object referenced within the $objects +array will be uploaded with the same metadata.

      +
      +
      +
      +

      Large Objects

      +

      If you want to upload objects larger than 5GB in size, you must use a +different upload process.

      +
      $options = array(
      +    'name' => 'san_diego_vacation_video.mp4',
      +    'path'   => '/path/to/local/videos/san_diego_vacation.mp4'
      +);
      +$objectTransfer = $container->setupObjectTransfer($options);
      +$objectTransfer->upload();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      The process shown above will automatically partition your large object +into small chunks and upload them concurrently to the container +represented by $container.

      +

      You can tune the parameters of this process by specifying additional +options in the $options array. Here is a complete listing of keys +that can be specified in the $options array:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Key nameDescriptionData TypeRequired?Default ValueExample
      nameName of large object in containerStringYes
        +
      • +
      +
      san_diego_vacation_video.mp4
      pathPath to file containing object data on local filesystemStringOne of path or body must be specified
        +
      • +
      +
      /path/to/local/videos/san_diego_vacation.mp4
      bodyString or stream representation of object dataString | StreamOne of path or body must be specified
        +
      • +
      +
      ... lots of data ...
      metadataMetadata for the objectAssociative array of metadata key-value pairsNoarray()array( "Author" => "Jane Doe" )
      partSizeThe size, in bytes, of each chunk that the large object is partitioned into prior to uploadingIntegerNo1073741824 (1GB)52428800 (50MB)
      concurrencyThe number of concurrent transfers to execute as part of the uploadIntegerNo1 (no concurrency; upload chunks serially)10
      progressA callable function or method which is called to report progress of the the upload. See `CURLOPT_PROGRESSFUNCTION documentation <http://us2.php.net/curl_setopt>`__ for details on parameters passed to this callable function or method.String (callable function or method name)NoNonereportProgress
      +
      +
      +

      Auto-extract Archive Files

      +

      You can upload a tar archive file and have the Object Store service +automatically extract it into a container.

      +
      use OpenCloud\ObjectStore\Constants\UrlType;
      +
      +$localArchiveFileName  = '/path/to/local/image_files.tar.gz';
      +$remotePath = 'images/';
      +
      +$fileData = fopen($localArchiveFileName, 'r');
      +$objectStoreService->bulkExtract($remotePath, $fileData, UrlType::TAR_GZ);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the above example, a local archive file named image_files.tar.gz +is uploaded to an Object Store container named images (defined by +the $remotePath variable).

      +

      Note that while we call fopen to open a file resource, we do not +call fclose at the end. The file resource is automatically closed +inside the bulkExtract call.

      +

      The third parameter to bulkExtract is the type of the archive file +being uploaded. The acceptable values for this are:

      +
        +
      • UrlType::TAR for tar archive files, or,
      • +
      • UrlType:TAR_GZ for tar archive files that are compressed with +gzip, or
      • +
      • UrlType::TAR_BZ for tar archive file that are compressed with +bzip
      • +
      +

      Note that the value of $remotePath could have been a +(pseudo-hierarchical folder)[#pseudo-hierarchical-folders] such as +images/blog as well.

      +
      +
      +

      List Objects in a Container

      +

      You can list all the objects stored in a container. An instance of +OpenCloud\Common\Collection\PaginatedIterator is returned.

      +
      $objects = $container->objectList();
      +foreach ($objects as $object) {
      +    /** @var $object OpenCloud\ObjectStore\Resource\DataObject  **/
      +}
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      You can list only those objects in the container whose names start with +a certain prefix.

      +
      $options = array(
      +    'prefix' => 'php'
      +);
      +
      +$objects = $container->objectList($options);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In general, the objectList() method described above takes an +optional parameter ($options in the example above). This parameter +is an associative array of various options. Here is a complete listing +of keys that can be specified in the $options array:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Key nameDescriptionData TypeRequired?Default ValueExample
      prefixGiven a string x, limits the results to object names beginning with x.StringNo php
      limitGiven an integer n, limits the number of results to at most n values.IntegerNo 10
      markerGiven a string x, returns object names greater than the specified marker.StringNo php-elephant.jpg
      end_markerGiven a string x, returns object names less than the specified marker.StringNo python-snakes.jpg
      +
      +
      +

      Retrieve Object

      +

      You can retrieve an object and its metadata, given the object’s +container and name.

      +
      $objectName = 'php-elephant.jpg';
      +$object = $container->getObject($objectName);
      +
      +/** @var $object OpenCloud\ObjectStore\Resource\DataObject **/
      +
      +$objectContent = $object->getContent();
      +
      +/** @var $objectContent Guzzle\Http\EntityBody **/
      +
      +// Write object content to file on local filesystem.
      +$objectContent->rewind();
      +$stream = $objectContent->getStream();
      +$localFilename = tempnam("/tmp", 'php-opencloud-');
      +file_put_contents($localFilename, $stream);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, $object is the object named +php-elephant.jpg in the container represented by $container. +Further, $objectContent represents the contents of the object. It is +of type +`Guzzle\Http\EntityBody <http://api.guzzlephp.org/class-Guzzle.Http.EntityBody.html>`__.

      +
      +
      +

      Retrieve Object Metadata

      +

      You can retrieve just an object’s metadata without retrieving its +contents.

      +
      $objectName = 'php-elephant.jpg';
      +$object = $container->getPartialObject($objectName);
      +$objectMetadata = $object->getMetadata();
      +
      +/** @var $objectMetadata \OpenCloud\Common\Metadata **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, while $object is an instance of +OpenCloud\ObjectStore\Resource\DataObject, that instance is only +partially populated. Specifically, only properties of the instance +relating to object metadata are populated.

      +
      +
      +

      Temporary URLs

      +

      The Temporary URL feature allows you to create limited-time Internet +addresses that allow you to grant limited access to your Object Store +account. Using this feature, you can allow others to retrieve or place +objects in your Object Store account for a specified amount of time. +Access to the temporary URL is independent of whether or not your +account is CDN-enabled. Even if you do not +CDN-enable a container, you can still grant temporary public access +through a temporary URL.

      +

      First, you must set the temporary URL secret on your account. This is a +one-time operation; you only need to perform it the very first time you +wish to use the temporary URLs feature.

      +
      $account->setTempUrlSecret();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      Note that this operation is carried out on $account, which is an +instance of OpenCloud\ObjectStore\Resource\Account, a class +representing your object store account.

      +

      The above operation will generate a random secret and set it on your +account. Instead of a random secret, if you wish to provide a secret, +you can supply it as a parameter to the setTempUrlSecret method.

      +
      $account->setTempUrlSecret('<SOME SECRET STRING>');
      +
      +
      +

      [ Get the executable PHP script for this +example +]

      +

      Once a temporary URL secret has been set on your account, you can +generate a temporary URL for any object in your Object Store.

      +
      $expirationTimeInSeconds = 3600; // one hour from now
      +$httpMethodAllowed = 'GET';
      +$tempUrl = $object->getTemporaryUrl($expirationTimeInSeconds, $httpMethodAllowed);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, a temporary URL for the object is generated. This +temporary URL will provide public access to the object for an hour (3600 +seconds), as specified by the $expirationTimeInSeconds variable. +Further, only GET HTTP methods will be allowed on this URL, as specified +by the $httpMethodAllowed variable. The other value allowed for the +$httpMethodAllowed variable would be PUT.

      +

      You can also retrieve the temporary URL secret that has been set on your +account.

      +
      $tempUrlSecret = $account->getTempUrlSecret();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Update Object

      +

      You can update an object’s contents (as opposed to updating its +metadata) by simply re-uploading the +object to its container using the same object name +as before.

      +
      +
      +

      Update Object Metadata

      +

      You can update an object’s metadata after it has been uploaded to a +container.

      +
      $object->saveMetadata(array(
      +    'author' => 'John Doe'
      +));
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Copy Object

      +

      You can copy an object from one container to another, provided the +destination container already exists.

      +
      $object->copy('logos_copy/php.jpg');
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, both the name of the destination container +(logos_copy)and the name of the destination object (php.jpg) +have to be specified, separated by a /.

      +
      +
      +

      Delete Object

      +

      When you no longer need an object, you can delete it.

      +
      $object->delete();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Bulk Delete

      +

      While you can delete individual objects as shown above, you can also +delete objects and empty containers in bulk.

      +
      $objectStoreService->bulkDelete(array(
      +    'logos/php-elephant.png',
      +    'logos/python-snakes.png',
      +    'some_empty_container'
      +));
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, two objects (some_container/object_a.png, +some_other_container/object_z.png) and one empty container +(some_empty_container) are all being deleted in bulk via a single +command.

      +
      +
      +
      +

      CDN Containers

      +

      Note: The functionality described in this section is available only on +the Rackspace cloud. It will not work as described when working with a +vanilla OpenStack cloud.

      +

      Any container can be converted to a CDN-enabled container. When this is +done, the objects within the container can be accessed from anywhere on +the Internet via a URL.

      +
      +

      Enable CDN Container

      +

      To take advantage of CDN capabilities for a container and its objects, +you must CDN-enable that container.

      +
      $container->enableCdn();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Public URLs

      +

      Once you have CDN-enabled a container, you can retrieve a +publicly-accessible URL for any of its objects. There are four types of +publicly-accessible URLs for each object. Each type of URL is meant for +a different purpose. The sections below describe each of these URL types +and how to retrieve them.

      +
      +

      HTTP URL

      +

      You can use this type of URL to access the object over HTTP.

      +
      $httpUrl = $object->getPublicUrl();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Secure HTTP URL

      +

      You can use this type of URL to access the object over HTTP + TLS/SSL.

      +
      use OpenCloud\ObjectStore\Constants\UrlType;
      +
      +$httpsUrl = $object->getPublicUrl(UrlType::SSL);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Streaming URL

      +

      You can use this type of URL to stream a video or audio object using +Adobe’s HTTP Dynamic Streaming.

      +
      use OpenCloud\ObjectStore\Constants\UrlType;
      +
      +$streamingUrl = $object->getPublicUrl(UrlType::STREAMING);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      IOS Streaming URL

      +

      You can use this type of URL to stream an audio or video object to an +iOS device.

      +
      use OpenCloud\ObjectStore\Constants\UrlType;
      +
      +$iosStreamingUrl = $object->getPublicUrl(UrlType::IOS_STREAMING);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Update CDN Container TTL

      +

      You can update the TTL of a CDN-enabled container.

      +
      $cdnContainer = $container->getCdn();
      +$cdnContainer->setTtl(<NEW TTL, IN SECONDS>);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Disable CDN Container

      +

      If you no longer need CDN capabilities for a container, you can disable +them.

      +
      $container->disableCdn();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Accounts

      +

      An account defines a namespace for containers. An account can +have zero or more containers in it.

      +
      +

      Retrieve Account

      +

      You must retrieve the account before performing any operations on it.

      +
      $account = $objectStoreService->getAccount();
      +
      +
      +
      +
      +

      Get Container Count

      +

      You can quickly find out how many containers are in your account.

      +
      $accountContainerCount = $account->getContainerCount();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Get Object Count

      +

      You can quickly find out how many objects are in your account.

      +
      $accountObjectCount = $account->getObjectCount();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, $accountObjectCount will contain the number of +objects in the account represented by $account.

      +
      +
      +

      Get Bytes Used

      +

      You can quickly find out the space used by your account, in bytes.

      +
      $accountSizeInBytes = $account->getBytesUsed();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      In the example above, $accountSizeInBytes will contain the space +used, in bytes, by the account represented by $account.

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/access.html b/doc/_build/html/services/object-store/access.html new file mode 100644 index 000000000..c3befc4c9 --- /dev/null +++ b/doc/_build/html/services/object-store/access.html @@ -0,0 +1,373 @@ + + + + + + + + + + Temporary URLs — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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.

      +

      Get the executable PHP script for this example:

      + +
      +
      +

      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:

      +
      $object->getTemporaryUrl(60, 'GET');
      +
      +
      +

      To allow PUT access for 1 hour:

      +
      $object->getTemporaryUrl(360, 'PUT');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      Hosting HTML sites on CDN

      +
      +

      Note

      +

      This feature is only available to Rackspace users.

      +
      +

      To host a static (i.e. HTML) website on Cloud Files, you must follow +these steps:

      +
        +
      1. CDN-enable a container:
      2. +
      +
      $container = $service->getContainer('html_site');
      +$container->enableCdn();
      +
      +
      +
        +
      1. Upload all HTML content. You can use nested directory structures.
      2. +
      +
      $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'),
      +));
      +
      +
      +
        +
      1. Tell Cloud Files what to use for your default index page like this:
      2. +
      +
      $container->setStaticIndexPage('index.html');
      +
      +
      +
        +
      1. (Optional) Tell Cloud Files which error page to use by default:
      2. +
      +
      $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.

      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/account.html b/doc/_build/html/services/object-store/account.html new file mode 100644 index 000000000..e4ae6f1cc --- /dev/null +++ b/doc/_build/html/services/object-store/account.html @@ -0,0 +1,333 @@ + + + + + + + + + + Account Details — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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

      +
      $account = $service->getAccount();
      +
      +
      +
      +
      +

      View all details

      +
      $details = $account->getDetails();
      +
      +
      +
      +
      +

      Retrieve total container count

      +
      $account->getContainerCount();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Retrieve total object count

      +
      $account->getObjectCount();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Retrieve total bytes used

      +
      $account->getBytesUsed();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/cdn.html b/doc/_build/html/services/object-store/cdn.html new file mode 100644 index 000000000..32d01b3a4 --- /dev/null +++ b/doc/_build/html/services/object-store/cdn.html @@ -0,0 +1,394 @@ + + + + + + + + + + CDN Containers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      CDN Containers

      +
      +

      Note

      +

      This feature is only available to Rackspace users.

      +
      +
      +

      Setup

      +

      In order to interact with CDN containers, you first need to instantiate a +CDN service object:

      +
      $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:

      +
      $cdnContainers = $cdnService->listContainers();
      +
      +foreach ($cdnContainers as $cdnContainer) {
      +  /** @var $cdnContainer OpenCloud\ObjectStore\Resource\CDNContainer */
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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.

      +
      $container->enableCdn();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      CDN-disable a container

      +
      $container->disableCdn();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Operations on CDN-enabled containers

      +

      Once a container has been CDN-enabled, you can retrieve it like so:

      +
      $cdnContainer = $cdnService->cdnContainer('{containerName}');
      +
      +
      +
      +

      Retrieve the SSL URL of a CDN container

      +
      $cdnContainer->getCdnSslUri();
      +
      +
      +
      +
      +

      Retrieve the streaming URL of a CDN container

      +
      $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.

      +
      $cdnContainer->getIosStreamingUri();
      +
      +
      +
      +
      +

      CDN logging

      +

      To enable and disable logging for your CDN-enabled container:

      +
      $cdnContainer->enableCdnLogging();
      +$cdnContainer->disableCdnLogging();
      +
      +
      +
      +
      +
      +

      Purge CDN-enabled objects

      +

      To remove a CDN object from public access:

      +
      $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:

      +
      $object->purge('jamie.hannaford@rackspace.com');
      +$object->purge('hello@example.com,hallo@example.com');
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/containers.html b/doc/_build/html/services/object-store/containers.html new file mode 100644 index 000000000..c92b6df18 --- /dev/null +++ b/doc/_build/html/services/object-store/containers.html @@ -0,0 +1,513 @@ + + + + + + + + + + Containers — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Containers

      +
      +

      Create container

      +

      To create a new container, you just need to define its name:

      +
      $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

      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      List containers

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +

      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:

      +
      $someContainers = $service->listContainers(array(
      +    'marker'     => 'container_55',
      +    'end_marker' => 'container_2001'
      +));
      +
      +
      +

      Or to return a limited set:

      +
      $someContainers = $service->listContainers(array('limit' => 560));
      +
      +
      +
      +
      +
      +

      Get container

      +

      To retrieve a certain container:

      +
      /** @param $container OpenCloud\ObjectStore\Resource\Container */
      +$container = $service->getContainer('{containerName}');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +

      Retrieve a container’s name

      +
      $name = $container->name;
      +
      +
      +
      +
      +

      Retrieve a container’s object count

      +
      $count = $container->getObjectCount();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Retrieve a container’s total bytes used

      +
      $bytes = $container->getBytesUsed();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      Delete container

      +

      Deleting an empty container is easy:

      +
      $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:

      +
      $container->delete(true);
      +
      +
      +

      You can also delete all objects +first, and then call delete.

      +

      Get the executable PHP script for this example

      +
      +
      +

      Deleting all objects inside a container

      +
      $container->deleteAllObjects();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Create or update container metadata

      +
      $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:

      +
      $metadata = $container->appendToMetadata(array(
      +    'Publisher' => 'Hogarth'
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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:

      +
      use OpenCloud\Common\Constants\Size;
      +
      +$container->setCountQuota(1000);
      +$container->setBytesQuota(2.5 * Size::GB);
      +
      +
      +

      And to retrieve them:

      +
      echo $container->getCountQuota();
      +echo $container->getBytesQuota();
      +
      +
      +

      Get the executable PHP scripts for this example:

      + +
      +
      +

      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).

      +
      $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:

      +
      $container->uploadDirectory('/home/user/my-blog');
      +
      +
      +

      There are four scenarios you should be aware of:

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      LocalRemoteComparisonAction
      File existsFile existsIdentical checksumNo action
      File existsFile existsDifferent checksumLocal file overwrites remote
      File existsFile does not exist
        +
      • +
      +
      Local file created in Swift
      Files does not existFile exists
        +
      • +
      +
      Remote file deleted
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/index.html b/doc/_build/html/services/object-store/index.html new file mode 100644 index 000000000..89c7412af --- /dev/null +++ b/doc/_build/html/services/object-store/index.html @@ -0,0 +1,465 @@ + + + + + + + + + + Object Store v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Object Store v1

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Object Store service

      +

      Now to instantiate the Object Store service:

      +
      $service = $client->objectStoreService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      +
      +

      Operations

      +
      + +
      +
      +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/migrating-containers.html b/doc/_build/html/services/object-store/migrating-containers.html new file mode 100644 index 000000000..511cae3bb --- /dev/null +++ b/doc/_build/html/services/object-store/migrating-containers.html @@ -0,0 +1,405 @@ + + + + + + + + + + Migrating containers across regions — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:
      • +
      +
      composer require guzzle/guzzle
      +
      +
      +
        +
      • Depending on the size and number of transfer items, you will need to +raise PHP’s memory limit:
      • +
      +
      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:
      • +
      +
      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:

      +
      $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:

      +
      $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:

      +
      $options = array(
      +    'read.batchLimit'  => 100,
      +    'read.pageLimit'   => 100,
      +    'write.batchLimit' => 50
      +);
      +
      +$iadService->migrateContainer($oldContainer, $newContainer, $options);
      +
      +
      +
      +

      Options explained

      + +++++ + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionDefault
      read.pageLimitWhen 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.batchLimitAfter 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.batchLimitOnce 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
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/objects.html b/doc/_build/html/services/object-store/objects.html new file mode 100644 index 000000000..8525dcf51 --- /dev/null +++ b/doc/_build/html/services/object-store/objects.html @@ -0,0 +1,644 @@ + + + + + + + + + + Objects — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Objects

      +
      +

      Setup

      +

      In order to interact with this feature, you must first retrieve a particular +container using its unique name:

      +
      $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:

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      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:

      +
      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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      Batch upload multiple files (each under 5GB)

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      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:

      +
      $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.

      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      List objects in a container

      +

      To return a list of objects:

      +
      $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.

      +
      $container->objectList(array('prefix' => 'logFile_'));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Get object

      +

      To retrieve a specific file from Cloud Files:

      +
      /** @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

      +
      /** @param $container OpenCloud\ObjectStore\Resource\Container */
      +$container = $object->getContainer();
      +
      +
      +
      +
      +

      Get file name

      +
      /** @param $name string */
      +$name = $object->getName();
      +
      +
      +
      +
      +

      Get file size

      +
      /** @param $size int */
      +$size = $object->getContentLength();
      +
      +
      +
      +
      +

      Get content of file

      +
      /** @param $content Guzzle\Http\EntityBody */
      +$content = $object->getContainer();
      +
      +
      +
      +
      +

      Get type of file

      +
      /** @param $type string */
      +$type = $object->getContentType();
      +
      +
      +
      +
      +

      Get file checksum

      +
      /** @param $etag string */
      +$etag = $object->getEtag();
      +
      +
      +
      +
      +

      Get last modified date of file

      +
      /** @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

      +
      $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):

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

      +
      $snippet = $container->getObject('output.log', array('range' => 'bytes=-20'));
      +
      +
      +
      +
      +
      +

      Update an existing object

      +
      $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:

      +
      $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 the executable PHP script for this example

      +
      +
      +

      Get object metadata

      +

      You can fetch just the object metadata without fetching the full +content:

      +
      $container->getPartialObject('summer_vacation.mp4');
      +
      +
      +

      In order to access the metadata on a partial or complete object, use:

      +
      $object->getMetadata();
      +
      +
      +

      You can turn a partial object into a full object to get the content +after looking at the metadata:

      +
      $object->refresh();
      +
      +
      +

      You can also update to get the latest metadata:

      +
      $object->retrieveMetadata();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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):

      +
      // 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:

      +
      $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:

      +
      $metadata = $object->appendToMetadata(array(
      +  'Author' => 'Hemingway'
      +));
      +
      +$object->saveMetadata($metadata);
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      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:

      +
      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.

      +

      Get the executable PHP script for this example

      +
      +
      +

      Delete object

      +
      $object->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Delete multiple objects

      +

      Bulk delete a set of paths:

      +
      $pathsToBeDeleted = array('/container_1/old_file', '/container_2/notes.txt', '/container_1/older_file.log');
      +
      +$service->bulkDelete($pathsToBeDeleted);
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/object-store/rs-only.html b/doc/_build/html/services/object-store/rs-only.html new file mode 100644 index 000000000..783588e1d --- /dev/null +++ b/doc/_build/html/services/object-store/rs-only.html @@ -0,0 +1,283 @@ + + + + + + + + + + <no title> — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Note

      +

      This feature is only available to Rackspace users.

      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/README.md.html b/doc/_build/html/services/orchestration/README.md.html new file mode 100644 index 000000000..4342e1f82 --- /dev/null +++ b/doc/_build/html/services/orchestration/README.md.html @@ -0,0 +1,270 @@ + + + + + + + + + + Orchestration — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Orchestration

      +

      Orchestration is a service that can be used to create and manage +cloud resources. Examples of such resources are databases, load +balancers, servers and software installed on them.

      +
      +

      Concepts

      +

      To use the Orchestration service effectively, you should understand +several key concepts:

      +
        +
      • 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.
      • +
      +
      +
      +

      Getting started

      +
      +

      1. Instantiate an OpenStack or Rackspace client.

      +

      To use the Orchestration service, you must first instantiate a +OpenStack or Rackspace client object.

      +
        +
      • If you are working with an OpenStack cloud, instantiate an +OpenCloud\OpenStack client as follows:

        +
        use OpenCloud\OpenStack;
        +
        +$client = new OpenStack('<OPENSTACK CLOUD IDENTITY ENDPOINT URL>', array(
        +    'username' => '<YOUR OPENSTACK CLOUD ACCOUNT USERNAME>',
        +    'password' => '<YOUR OPENSTACK CLOUD ACCOUNT PASSWORD>'
        +));
        +
        +
        +
      • +
      • If you are working with the Rackspace cloud, instantiate a +OpenCloud\Rackspace client as follows:

        +
        use OpenCloud\Rackspace;
        +
        +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        + ));
        +
        +
        +
      • +
      +
      +
      +

      2. Obtain an Orchestration service object from the client.

      +

      All Orchestration operations are done via an orchestration service +object. To instantiate this object, call the orchestrationService +method on the $client object as shown in the following example:

      +
      $region = '<CLOUD REGION NAME>';
      +$orchestrationService = $client->orchestrationService(null, $region);
      +
      +
      +

      Any stacks and resources created with this $orchestrationService +instance will be stored in the cloud region specified by $region.

      +
      +
      +

      3. Create a stack from a template.

      +
      $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 ]

      +
      +
      +
      +

      Next steps

      +

      Once you have created a stack, there is more you can do with it. See +complete user guide for orchestration.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/USERGUIDE.md.html b/doc/_build/html/services/orchestration/USERGUIDE.md.html new file mode 100644 index 000000000..8fe353d2e --- /dev/null +++ b/doc/_build/html/services/orchestration/USERGUIDE.md.html @@ -0,0 +1,921 @@ + + + + + + + + + + Complete User Guide for the Orchestration Service — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Complete User Guide for the Orchestration Service

      +

      Orchestration is a service that you can use to create and manage cloud +resources such as databases, load balancers, and servers, and the +software installed on servers.

      + +
      +

      Concepts

      +

      To use the Orchestration service effectively, you should understand the +following key concepts:

      +
        +
      • Template: A JSON or YAML document that describes how a set of +resources should be assembled to produce a working deployment. 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.
      • +
      • Resource: Some component of your architecture (a cloud server, a +group of scaled cloud servers, a load balancer, some configuration +management system, and so on) that is defined in a template.
      • +
      • Stack: A running instance of a template. When a stack is created, +the resources specified in the template are created.
      • +
      +
      +
      +

      Prerequisites

      +
      +

      Client

      +

      To use the Orchestration service, you must first instantiate a +OpenStack or Rackspace client object.

      +
        +
      • If you are working with an OpenStack cloud, instantiate an +OpenCloud\OpenStack client as follows:

        +
        use OpenCloud\OpenStack;
        +
        +$client = new OpenStack('<OPENSTACK CLOUD IDENTITY ENDPOINT URL>', array(
        +    'username' => '<YOUR OPENSTACK CLOUD ACCOUNT USERNAME>',
        +    'password' => '<YOUR OPENSTACK CLOUD ACCOUNT PASSWORD>'
        +));
        +
        +
        +
      • +
      • If you are working with the Rackspace cloud, instantiate a +OpenCloud\Rackspace client as follows:

        +
        use OpenCloud\Rackspace;
        +
        +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
        +    'username' => '<YOUR RACKSPACE CLOUD ACCOUNT USERNAME>',
        +    'apiKey'   => '<YOUR RACKSPACE CLOUD ACCOUNT API KEY>'
        +));
        +
        +
        +
      • +
      +
      +
      +

      Orchestration service

      +

      All Orchestration operations are done via an orchestration service +object. To instantiate this object, call the orchestrationService +method on the $client object. This method takes two arguments:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
      PositionDescriptionData typeRequired?Default valueExample value
      1Name of the service, as it appears in the service catalogStringNonull; automatically determined when possiblecloudOrchestration
      2Cloud regionStringYes
        +
      • +
      +
      DFW
      +
      $region = '<CLOUD REGION NAME>';
      +$orchestrationService = $client->orchestrationService(null, $region);
      +
      +
      +

      Any stacks and resources created with this $orchestrationService +instance will be stored in the cloud region specified by $region.

      +
      +
      +
      +

      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). 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.

      +
      +

      Validate template

      +

      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:

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

      +
      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 +]

      +
      +
      +
      +
      +

      Stacks

      +

      A stack is a running instance of a template. When a stack is created, +the 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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameName of the stackString. Must start with an alphabetic character, and must contain only alphanumeric, _, - or . charactersYes
        +
      • +
      +
      simple-lamp-setup
      templateTemplate contentsString. JSON or YAMLNo, if templateUrl is specifiednullheat_template_version: 2013-05-23\ndescription: LAMP server\n
      templateUrlURL of the template fileString. HTTP or HTTPS URLNo, if template is specifiednullhttps://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml
      parametersArguments to the template, based on the template’s parameters. For example, see the parameters in this template sectionAssociative arrayNonullarray('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:

      +
      $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)'
      +    )
      +));
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ 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:

      +
      $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)'
      +    )
      +));
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ 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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameName of the stackString. Must start with an alphabetic character, and must contain only alphanumeric, _, - or . characters.Yes
        +
      • +
      +
      simple-lamp-setup
      templateTemplate contentsString. JSON or YAMLNo, if templateUrl is specifiednullheat_template_version: 2013-05-23\ndescription: LAMP server\n
      templateUrlURL of template fileString. HTTP or HTTPS URLNo, if template is specifiednullhttps://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml
      parametersArguments to the template, based on the template’s parametersAssociative arrayNonullarray('server_hostname' => 'web01')
      timeoutMinsDuration, in minutes, after which stack creation should time outIntegerYes
        +
      • +
      +
      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:

      +
      $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
      +));
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ 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:

      +
      $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:

      +
      $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:

      +
      $stack = $orchestrationService->getStack('simple-lamp-setup');
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ 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.

      +
      $stackTemplate = $stack->getTemplate();
      +/** @var $stackTemplate string **/
      +
      +
      +

      [ 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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      templateTemplate contentsString. JSON or YAMLNo, if templateUrl is specifiednullheat_template_version: 2013-05-23\ndescription: LAMP server\n
      templateUrlURL of template fileString. HTTP or HTTPS URLNo, if template is specifiednullhttps://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp-updated.yaml
      parametersArguments to the template, based on the template’s parametersAssociative arrayNonullarray('flavor_id' => 'general1-1')
      timeoutMinsDuration, in minutes, after which stack update should time outIntegerYes
        +
      • +
      +
      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:

      +
      $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
      +));
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ 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:

      +
      $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
      +));
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ 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:

      +
      $stack->delete();
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +

      Abandon Stack

      +

      If you want to delete a stack but preserve all its resources, you can +abandon the stack as shown in the following example:

      +
      $abandonStackData = $stack->abandon();
      +/** @var $abandonStackData string **/
      +
      +file_put_contents(__DIR__ . '/sample_adopt_stack_data.json', $abandonStackData);
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +

      Note that 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 operation.

      +
      +
      +

      Adopt stack

      +

      If you have data from an abandoned stack, you can re-create the stack as +shown in the following example:

      +
      $stack = $orchestrationService->adoptStack(array(
      +    'name'           => 'simple-lamp-setup',
      +    'template'       => file_get_contents(__DIR__ . '/lamp.yml'),
      +    'adoptStackData' => $abandonStackData,
      +    'timeoutMins'    => 5
      +));
      +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      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:

      +
      $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:

      +
      $resource = $stack->getResource('load-balancer');
      +/** @var $resource OpenCloud\Orchestration\Resource\Resource **/
      +
      +
      +

      [ 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:

      +
      $resourceMetadata = $resource->getMetadata();
      +/** @var $resourceMetadata \stdClass **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      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:

      +
      $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:

      +
      $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:

      +
      $resourceEvent = $resource->getEvent('c1342a0a-59e6-4413-9af5-07c9cae7d729');
      +/** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      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:

      +
      $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:

      +
      $resourceType = $orchestrationService->getResourceType('OS::Nova::Server');
      +/** @var $resourceType OpenCloud\Orchestration\Resource\ResourceType **/
      +
      +
      +

      [ 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:

      +
      $resourceTypeTemplate = $resourceType->getTemplate();
      +/** @var $resourceTypeTemplate string **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      +

      Build info

      +
      +

      Get build info

      +

      You can retrieve information about the current Orchestration service +build as shown in the following example:

      +
      $buildInfo = $orchestrationService->getBuildInfo();
      +/** @var $resourceType OpenCloud\Orchestration\Resource\BuildInfo **/
      +
      +
      +

      [ Get the executable PHP script for this +example ]

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/build-info.html b/doc/_build/html/services/orchestration/build-info.html new file mode 100644 index 000000000..8f4421b7a --- /dev/null +++ b/doc/_build/html/services/orchestration/build-info.html @@ -0,0 +1,306 @@ + + + + + + + + + + Build info — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Build info

      +
      +

      Get build info

      +

      You can retrieve information about the current Orchestration service +build as shown in the following example:

      +
      /** @var $resourceType OpenCloud\Orchestration\Resource\BuildInfo **/
      +$buildInfo = $orchestrationService->getBuildInfo();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/events.html b/doc/_build/html/services/orchestration/events.html new file mode 100644 index 000000000..18f92260d --- /dev/null +++ b/doc/_build/html/services/orchestration/events.html @@ -0,0 +1,334 @@ + + + + + + + + + + Stack resource events — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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:

      +
      $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:

      +
      /** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/
      +$resourceEvent = $resource->getEvent('c1342a0a-59e6-4413-9af5-07c9cae7d729');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/index.html b/doc/_build/html/services/orchestration/index.html new file mode 100644 index 000000000..bc180c642 --- /dev/null +++ b/doc/_build/html/services/orchestration/index.html @@ -0,0 +1,426 @@ + + + + + + + + + + Orchestration v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Orchestration v1

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Orchestration service

      +

      Now to instantiate the Orchestration service:

      +
      $service = $client->orchestrationService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/resource-types.html b/doc/_build/html/services/orchestration/resource-types.html new file mode 100644 index 000000000..b2ee5e4b2 --- /dev/null +++ b/doc/_build/html/services/orchestration/resource-types.html @@ -0,0 +1,330 @@ + + + + + + + + + + Resource types — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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:

      +
      /** @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:

      +
      /** @var $resourceTypeTemplate string **/
      +$resourceTypeTemplate = $resourceType->getTemplate();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/resources.html b/doc/_build/html/services/orchestration/resources.html new file mode 100644 index 000000000..437e683a3 --- /dev/null +++ b/doc/_build/html/services/orchestration/resources.html @@ -0,0 +1,331 @@ + + + + + + + + + + Stack resources — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      $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:

      +
      /** @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:

      +
      /** @var $resourceMetadata \stdClass **/
      +$resourceMetadata = $resource->getMetadata();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/stacks.html b/doc/_build/html/services/orchestration/stacks.html new file mode 100644 index 000000000..7a2dd4fb2 --- /dev/null +++ b/doc/_build/html/services/orchestration/stacks.html @@ -0,0 +1,667 @@ + + + + + + + + + + Stacks — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Stacks

      +

      A stack is a running instance of a template. When a stack is created, +the 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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameName of the stackString. Must start with an alphabetic character, and must contain only alphanumeric, _, - or . charactersYes
        +
      • +
      +
      simple-lamp-setup
      templateTemplate contentsString. JSON or YAMLNo, if templateUrl is specifiednullheat_template_version: 2013-05-23\ndescription: LAMP server\n
      templateUrlURL of the template fileString. HTTP or HTTPS URLNo, if template is specifiednullhttps://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml
      parametersArguments to the template, based on the template’s parameters. For example, see the parameters in this template sectionAssociative arrayNonullarray('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:

      +
      /** @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:

      +
      /** @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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      nameName of the stackString. Must start with an alphabetic character, and must contain only alphanumeric, _, - or . characters.Yes
        +
      • +
      +
      simple-lamp-setup
      templateTemplate contentsString. JSON or YAMLNo, if templateUrl is specifiednullheat_template_version: 2013-05-23\ndescription: LAMP server\n
      templateUrlURL of template fileString. HTTP or HTTPS URLNo, if template is specifiednullhttps://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml
      parametersArguments to the template, based on the template’s parametersAssociative arrayNonullarray('server_hostname' => 'web01')
      timeoutMinsDuration, in minutes, after which stack creation should time outIntegerYes
        +
      • +
      +
      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:

      +
      /** @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:

      +
      $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:

      +
      $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:

      +
      /** @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.

      +
      /** @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:

      + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescriptionData typeRequired?Default valueExample value
      templateTemplate contentsString. JSON or YAMLNo, if templateUrl is specifiednullheat_template_version: 2013-05-23\ndescription: LAMP server\n
      templateUrlURL of template fileString. HTTP or HTTPS URLNo, if template is specifiednullhttps://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp-updated.yaml
      parametersArguments to the template, based on the template’s parametersAssociative arrayNonullarray('flavor_id' => 'general1-1')
      timeoutMinsDuration, in minutes, after which stack update should time outIntegerYes
        +
      • +
      +
      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:

      +
      /** @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:

      +
      /** @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:

      +
      $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 +operation.

      +
      +

      If you want to delete a stack but preserve all its resources, you can +abandon the stack as shown in the following example:

      +
      /** @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:

      +
      /** @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

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/orchestration/templates.html b/doc/_build/html/services/orchestration/templates.html new file mode 100644 index 000000000..8e6f33e21 --- /dev/null +++ b/doc/_build/html/services/orchestration/templates.html @@ -0,0 +1,340 @@ + + + + + + + + + + Templates — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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). 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:

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

      +
      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

      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/Claim.md.html b/doc/_build/html/services/queues/Claim.md.html new file mode 100644 index 000000000..b01ca78fe --- /dev/null +++ b/doc/_build/html/services/queues/Claim.md.html @@ -0,0 +1,323 @@ + + + + + + + + + + 1. Introduction — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      1. Introduction

      +

      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.

      +
      +
      +

      2. Setup

      +

      A Claim is initialized on its parent object, a Queue:

      +
      // To initialize an empty object:
      +$claim = $queue->getClaim();
      +
      +// or retrieve a specific claim:
      +$claim = $queue->getClaim('51db7067821e727dc24df754');
      +
      +
      +
      +
      +

      3. Claim messages

      +
      +

      3.1 Description

      +

      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.

      +
      +
      +

      3.2 Attributes

      +

      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.

      +
      +
      +

      3.3 Code

      +
      use OpenCloud\Common\Constants\Datetime;
      +
      +$queue->claimMessages(array(
      +    'limit' => 15,
      +    'grace' => 5 * Datetime::MINUTE,
      +    'ttl'   => 5 * Datetime::MINUTE
      +));
      +
      +
      +
      +
      +
      +

      4. Query claim

      +
      +

      4.1 Description

      +

      This operation queries the specified claim for the specified queue. +Claims with malformed IDs or claims that are not found by ID are +ignored.

      +
      +
      +

      4.2 Attributes

      +

      Claim ID.

      +
      +
      +

      4.3 Code

      +
      $claim = $queue->getClaim('51db7067821e727dc24df754');
      +
      +
      +
      +
      +
      +

      5. Update claim

      +
      +

      5.1 Description

      +

      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.

      +
      +
      +

      5.2 Attributes

      +

      See section 4.2.

      +
      +
      +

      5.3 Code

      +
      use OpenCloud\Common\Constants\Datetime;
      +
      +$claim->update(array(
      +    'ttl' => 10 * Datetime::MINUTE
      +));
      +
      +
      +
      +
      +
      +

      6. Release claim

      +
      +

      6.1 Description

      +

      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.

      +
      +
      +

      6.2 Attributes

      +

      See section 4.2.

      +
      +
      +

      6.3 Code

      +
      $message->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/Message.md.html b/doc/_build/html/services/queues/Message.md.html new file mode 100644 index 000000000..cffa9aa2b --- /dev/null +++ b/doc/_build/html/services/queues/Message.md.html @@ -0,0 +1,430 @@ + + + + + + + + + + 1. Introduction — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      1. Introduction

      +

      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.

      +
      +
      +

      2. Setup

      +

      A message is initialized from its parent object, a Queue:

      +
      // Setup an empty object
      +$message = $queue->getMessage();
      +
      +// or retrieve an existing one
      +$message = $queue->getMessage('<message_id>');
      +
      +
      +
      +
      +

      3. Post message

      +
      +

      3.1 Description

      +

      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.

      +
      +
      +

      3.2 Parameters

      +

      How you pass through the array structure depends on whether you are +executing multiple (3.3.2) or single (3.3.3) 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.

      +
      +
      +

      3.3 Code samples

      +
      +

      3.3.1 Posting a single message

      +
      use OpenCloud\Common\Constants\Datetime;
      +
      +$queue->createMessage(array(
      +    'body' => (object) array(
      +        'event'    => 'BackupStarted',
      +        'deadline' => '26.12.2013
      +    ),
      +    'ttl'  => 2 * Datetime::DAY
      +));
      +
      +
      +
      +
      +

      3.3.2 Post a batch of messages

      +

      Please note that the list of messages will be truncated at 10. For more, +please execute another method call.

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

      4. Get messages

      +
      +

      4.1 Description

      +

      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.

      +
      +
      +

      4.2 Parameters

      +

      A hash of options.

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameStyleTypeDescription
      markerQueryStringSpecifies 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.
      limitQueryIntegerWhen 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.
      echoQueryBooleanDetermines 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_claimedQuery​BooleanDetermines 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.
      +
      +
      +

      4.3 Code sample

      +
      $messages = $queue->listMessages(array(
      +    'marker' => '51db6f78c508f17ddc924357',
      +    'limit'  => 20,
      +    'echo'   => true
      +));
      +
      +while ($message = $messages->next()) {
      +    echo $message->getId() . PHP_EOL;
      +}
      +
      +
      +
      +
      +
      +

      5. Get a set of messages by ID

      +
      +

      5.1 Description

      +

      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.

      +
      +
      +

      5.2 Parameters

      +

      A hash of options.

      +

      |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|​String|Specifies +the claim ID with which the message is associated. Optional.| +|—-|—–|—-|———–|

      +
      +
      +

      5.3 Code sample

      +
      $ids = array('51db6f78c508f17ddc924357', 'f5b8c8a7c62b0150b68a50d6');
      +
      +$messages = $queue->listMessages(array('ids' => $ids));
      +
      +while ($message = $messages->next()) {
      +    echo $message->getId() . PHP_EOL;
      +}
      +
      +
      +
      +
      +
      +

      6. Delete a set of messages by ID

      +
      +

      6.1 Description

      +

      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.

      +
      +
      +

      6.2 Parameters

      +

      An array of IDs.

      +
      +
      +

      6.3 Code sample

      +
      $ids = array('51db6f78c508f17ddc924357', 'f5b8c8a7c62b0150b68a50d6');
      +
      +$response = $queue->deleteMessages($ids);
      +
      +
      +
      +
      +
      +

      7. Get a specific message

      +
      +

      7.1 Description

      +

      This operation gets the specified message from the specified queue.

      +
      +
      +

      7.2 Parameters

      +

      Message ID.

      +
      +
      +

      7.3 Object properties

      +

      href is an opaque relative URI that the client can use to uniquely +identify a message resource and interact with it.

      +

      ttl is the TTL that was set on the message when it was posted. The +message expires after (ttl - age) seconds.

      +

      age is the number of seconds relative to the server’s clock.

      +

      body is the arbitrary document that was submitted with the original +request to post the message.

      +
      +
      +

      7.4 Code sample

      +
      $message = $queue->getMessage('51db6f78c508f17ddc924357');
      +
      +
      +
      +
      +
      +

      8. Delete message

      +
      +

      8.1 Description

      +

      This operation immediately deletes the specified message.

      +
      +
      +

      8.2 Parameters

      +

      None.

      +
      +
      +

      8.3 Code sample

      +
      $message->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/Queue.md.html b/doc/_build/html/services/queues/Queue.md.html new file mode 100644 index 000000000..56da5f483 --- /dev/null +++ b/doc/_build/html/services/queues/Queue.md.html @@ -0,0 +1,353 @@ + + + + + + + + + + 1. Introduction — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      1. Introduction

      +

      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.

      +
      +
      +

      2. Setup

      +
      $service = $client->queuesService('cloudQueues', 'ORD');
      +
      +
      +
      +
      +

      3. Client IDs

      +

      With most of Marconi’s operation, 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.

      +
      $service->setClientId();
      +
      +echo $service->getClientId();
      +
      +
      +

      If you call setClientId without any parameters, a UUID is +automatically generated for you.

      +
      +
      +

      4. List queues

      +
      +

      4.1 Description

      +

      This operation lists queues for the project. The queues are sorted +alphabetically by name.

      +
      +
      +

      4.2 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.| +|—-|—–|—-|———–|

      +
      +
      +

      4.3 Code sample

      +
      $queues = $service->listQueues();
      +
      +while ($queue = $queues->next()) {
      +    echo $queue->getName() . PHP_EOL;
      +}
      +
      +
      +
      +
      +
      +

      5. Create queue

      +
      +

      5.1 Description

      +

      This operation creates a new queue.

      +
      +
      +

      5.2 Parameters

      +

      A string representation of the name for your new Queue. The name must +not exceed 64 bytes in length, and it is limited to US-ASCII letters, +digits, underscores, and hyphens.

      +
      +
      +

      5.3 Code sample

      +
      $queue = $service->createQueue('new_queue');
      +
      +
      +
      +
      +
      +

      6. Retrieve queue

      +
      +

      6.1 Description

      +

      Returns a Queue object for use.

      +
      +
      +

      6.2 Parameters

      +

      Queue name.

      +
      +
      +

      6.3 Code sample

      +
      $queue = $service->getQueue('new_queue');
      +
      +
      +
      +
      +
      +

      7. Check queue existence

      +
      +

      7.1 Description

      +

      This operation verifies whether the specified queue exists by returning +TRUE or FALSE.

      +
      +
      +

      7.2 Parameters

      +
      +
      +

      7.3 Code sample

      +
      if ($service->hasQueue('new_queue')) {
      +    // do something
      +}
      +
      +
      +
      +
      +
      +

      8. Update queue metadata (permanently to the API)

      +
      +

      4.1 Description

      +

      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.

      +
      +
      +

      4.2 Parameters

      +

      Hash of key pairs.

      +
      +
      +

      4.3 Code sample

      +
      $queue->saveMetadata(array(
      +    'foo' => 'bar'
      +));
      +
      +
      +
      +
      +
      +

      9. Retrieve the queue metadata (fresh from the API)

      +
      +

      4.1 Description

      +

      This operation returns metadata, such as message TTL, for the queue.

      +
      +
      +

      4.2 Parameters

      +

      None.

      +
      +
      +

      4.3 Code sample

      +
      $metadata = $queue->retrieveMetadata();
      +
      +print_r($metadata->toArray());
      +
      +
      +
      +
      +
      +

      10. Get queue stats

      +
      +

      4.1 Description

      +

      This operation returns queue statistics, including how many messages are +in the queue, categorized by status.

      +
      +
      +

      4.2 Parameters

      +

      None.

      +
      +
      +

      4.3 Code sample

      +
      $queue->getStats();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/claims.html b/doc/_build/html/services/queues/claims.html new file mode 100644 index 000000000..6ed6cb8f8 --- /dev/null +++ b/doc/_build/html/services/queues/claims.html @@ -0,0 +1,392 @@ + + + + + + + + + + Claims — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Claims

      +
      +

      Setup

      +

      In order to work with messages, you must first retrieve a queue by its name:

      +
      $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.

      +
      use OpenCloud\Common\Constants\Datetime;
      +
      +$queue->claimMessages(array(
      +    'limit' => 15,
      +    'grace' => 5 * Datetime::MINUTE,
      +    'ttl'   => 5 * Datetime::MINUTE
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +
      +

      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.

      +
      $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.

      +
      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.

      +
      $message->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/index.html b/doc/_build/html/services/queues/index.html new file mode 100644 index 000000000..207f9661b --- /dev/null +++ b/doc/_build/html/services/queues/index.html @@ -0,0 +1,418 @@ + + + + + + + + + + Queues v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Queues v1

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Queues service

      +

      Now to instantiate the Queues service:

      +
      $service = $client->queuesService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/messages.html b/doc/_build/html/services/queues/messages.html new file mode 100644 index 000000000..5fb2b69e8 --- /dev/null +++ b/doc/_build/html/services/queues/messages.html @@ -0,0 +1,463 @@ + + + + + + + + + + Messages — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Messages

      +
      +

      Setup

      +

      In order to work with messages, you must first retrieve a queue by its name:

      +
      $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

      +
      use OpenCloud\Common\Constants\Datetime;
      +
      +$queue->createMessage(array(
      +    'body' => (object) array(
      +        'event'    => 'BackupStarted',
      +        'deadline' => '26.12.2013',
      +    ),
      +    'ttl'  => 2 * Datetime::DAY
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Post a batch of messages

      +

      Please note that the list of messages will be truncated at 10. For more, +please execute another method call.

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

      +
      $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

      +
      $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.

      +
      $ids = array('id_1', 'id_2');
      +$response = $queue->deleteMessages($ids);
      +
      +
      +
      +
      +

      Get a specific message

      +

      This operation gets the specified message from the specified queue.

      +
      /** @var $message OpenCloud\Queues\Message */
      +$message = $queue->getMessage('{messageId}');
      +
      +
      +

      Once you have access to the Message object, you access its attributes:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      attributemethoddescription
      hrefgetHrefAn opaque relative URI that the client can use to uniquely identify a message resource and interact with it.
      ttlgetTtlThe TTL that was set on the message when it was posted. The message expires after (ttl - age) seconds.
      agegetAgeThe number of seconds relative to the server’s clock.
      bodygetBodyThe arbitrary document that was submitted with the original request to post the message.
      +
      +
      +

      Delete message

      +
      $message->delete();
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/queues/queues.html b/doc/_build/html/services/queues/queues.html new file mode 100644 index 000000000..207655b6d --- /dev/null +++ b/doc/_build/html/services/queues/queues.html @@ -0,0 +1,390 @@ + + + + + + + + + + Queues — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      $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.

      +
      $queues = $service->listQueues();
      +
      +foreach ($queues as $queue) {
      +    echo $queue->getName() , PHP_EOL;
      +}
      +
      +
      +
      +

      Filtering lists

      +

      You can also filter collections using the following query parameters:

      +
      $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.

      +
      $queue = $service->createQueue('new_queue');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Find queue details

      +
      /** @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.

      +
      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.

      +
      $queue->saveMetadata(array(
      +    'foo' => 'bar'
      +));
      +
      +
      +
      +
      +

      Retrieve the queue metadata

      +

      This operation returns metadata, such as message TTL, for the queue.

      +
      $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.

      +
      $queue->getStats();
      +
      +
      +
      +
      +

      Delete queue

      +
      $queue->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/volume/index.html b/doc/_build/html/services/volume/index.html new file mode 100644 index 000000000..2200448ee --- /dev/null +++ b/doc/_build/html/services/volume/index.html @@ -0,0 +1,388 @@ + + + + + + + + + + Volumes v1 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Volumes v1

      +
      +

      Setup

      +
      +

      Rackspace setup

      +

      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:

      +
      use OpenCloud\Rackspace;
      +
      +$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
      +  'username' => '{username}',
      +  'apiKey'   => '{apiKey}',
      +));
      +
      +
      +
      +
      +

      OpenStack setup

      +

      If you’re an OpenStack user, you will also need to prove a few other +configuration parameters:

      +
      $client = new OpenCloud\OpenStack('{keystoneUrl}', array(
      +  'username' => '{username}',
      +  'password' => '{apiKey}',
      +  'tenantId' => '{tenantId}',
      +));
      +
      +
      +
      +
      +

      Volume service

      +

      Now to instantiate the Volume service:

      +
      $service = $client->volumeService('{catalogName}', '{region}', '{urlType}');
      +
      +
      +
        +
      • {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.
      • +
      +
      +
      + +
      +

      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.
      +
      +
      + +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/volume/snapshots.html b/doc/_build/html/services/volume/snapshots.html new file mode 100644 index 000000000..5c330bf09 --- /dev/null +++ b/doc/_build/html/services/volume/snapshots.html @@ -0,0 +1,338 @@ + + + + + + + + + + Snapshots — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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:

      +
      // 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
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      List snapshots

      +
      $snapshots = $service->snapshotList();
      +
      +foreach ($snapshots as $snapshot) {
      +    /** @param $snapshot OpenCloud\Volume\Resource\Snapshot */
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      To get details on a single snapshot

      +
      $snapshot = $dallas->snapshot('{snapshotId}');
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      To delete a snapshot

      +
      $snapshot->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/volume/volume-types.html b/doc/_build/html/services/volume/volume-types.html new file mode 100644 index 000000000..d6cdd1443 --- /dev/null +++ b/doc/_build/html/services/volume/volume-types.html @@ -0,0 +1,320 @@ + + + + + + + + + + Volume Types — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Volume Types

      +
      +

      List volume types

      +
      $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:

      +
      $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
      • +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/services/volume/volumes.html b/doc/_build/html/services/volume/volumes.html new file mode 100644 index 000000000..f6bfbbd24 --- /dev/null +++ b/doc/_build/html/services/volume/volumes.html @@ -0,0 +1,364 @@ + + + + + + + + + + Volumes — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Volumes

      +
      +

      Create a volume

      +

      To create a volume, you must specify its size (in gigabytes). All other +parameters are optional:

      +
      // Create instance of OpenCloud\Volume\Resource\Volume
      +$volume = $service->volume();
      +
      +$volume->create(array(
      +    'size'                => 200,
      +    'volume_type'         => $service->volumeType('<volume_type_id>'),
      +    'display_name'        => 'My Volume',
      +    'display_description' => 'Used for large object storage'
      +));
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      List volumes

      +
      $volumes = $service->volumeList();
      +
      +foreach ($volumes as $volume) {
      +    /** @param $volumeType OpenCloud\Volume\Resource\Volume */
      +}
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Get details on a single volume

      +

      If you specify an ID on the volume() method, it retrieves +information on the specified volume:

      +
      $volume = $dallas->volume('<volume_id>');
      +echo $volume->size;
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      To delete a volume

      +
      $volume->delete();
      +
      +
      +

      Get the executable PHP script for this example

      +
      +
      +

      Attach a volume to a server

      +
      // 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

      +
      $server->detachVolume($volume);
      +
      +
      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/url-types.html b/doc/_build/html/url-types.html new file mode 100644 index 000000000..423c13076 --- /dev/null +++ b/doc/_build/html/url-types.html @@ -0,0 +1,303 @@ + + + + + + + + + + URL types — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      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.

      +
      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/_build/html/using-php-5.3.html b/doc/_build/html/using-php-5.3.html new file mode 100644 index 000000000..0a142de39 --- /dev/null +++ b/doc/_build/html/using-php-5.3.html @@ -0,0 +1,294 @@ + + + + + + + + + + Using the SDK with PHP v5.3 — php-opencloud 1.12.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + + + + +
      +
      +
      + +
      +
      +
      + +
      +

      Using the SDK with PHP v5.3

      +

      Since PHP 5.3 has entered EOL and no longer receives security updates, we have bumped the minimum requirement to 5.4. Using 5.3 is still possible, however, but you will need to use an older stable version of the SDK. There are two ways to do this.

      +

      The first way is by requiring it through the command line:

      +
      composer require rackspace/php-opencloud:1.12
      +
      +
      +

      The second way is by updating your composer.json file, and specifying the appropriate version of the SDK:

      +
      "require": {
      +  "rackspace/php-opencloud": "~1.12"
      +}
      +
      +
      +

      Note that 1.12 is the last minor release supporting PHP 5.3. Version 1.13 and above has shifted to PHP 5.4.

      +
      + + +
      + +
      +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/auth.rst b/doc/auth.rst new file mode 100644 index 000000000..ce5ba7233 --- /dev/null +++ b/doc/auth.rst @@ -0,0 +1,54 @@ +Authentication +============== + +The client does not automatically authenticate against the API when it is +instantiated - it waits for an API call. When this happens, it checks +whether the current “token” has expired, and (re-)authenticates if +necessary. + +You can force authentication, by calling: + +.. code-block:: php + + $client->authenticate(); + +If the credentials are incorrect, a ``401`` error will be returned. If +credentials are correct, a ``200`` status is returned with your Service +Catalog. + + +Service Catalog +--------------- + +The Service Catalog is returned on successful authentication, and is +composed of all the different API services available to the current +tenant. All of this functionality is encapsulated in the ``Catalog`` +object, which allows you greater control and interactivity. + +.. code-block:: php + + /** @var OpenCloud\Common\Service\Catalog */ + $catalog = $client->getCatalog(); + + // Return a list of OpenCloud\Common\Service\CatalogItem objects + foreach ($catalog->getItems() as $catalogItem) { + + $name = $catalogItem->getName(); + $type = $catalogItem->getType(); + + if ($name == 'cloudServersOpenStack' && $type == 'compute') { + break; + } + + // Array of OpenCloud\Common\Service\Endpoint objects + $endpoints = $catalogItem->getEndpoints(); + foreach ($endpoints as $endpoint) { + if ($endpoint->getRegion() == 'DFW') { + echo $endpoint->getPublicUrl(); + } + } + } + +As you can see, you have access to each Service’s name, type and list of +endpoints. Each endpoint provides access to the specific region, along +with its public and private endpoint URLs. 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..73aa3a8d4 --- /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/http-clients.rst b/doc/http-clients.rst new file mode 100644 index 000000000..49828509b --- /dev/null +++ b/doc/http-clients.rst @@ -0,0 +1,56 @@ +HTTP Clients +============ + +Default HTTP headers +-------------------- + +To set default HTTP headers: + +.. code-block:: php + + $client->setDefaultOption('headers/X-Custom-Header', 'FooBar'); + + +User agents +----------- + +php-opencloud will send a default ``User-Agent`` header for every HTTP +request, unless a custom value is provided by the end-user. The default +header will be in this format: + + User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz + +where ``xxx`` is the current version of the SDK, ``yyy`` is the current +version of cURL, and ``zzz`` is the current PHP version. To override +this default, you must run: + +.. code-block:: php + + $client->setUserAgent('MyCustomUserAgent'); + +which will result in: + + User-Agent: MyCustomUserAgent + +If you want to set a *prefix* for the user agent, but retain the default +``User-Agent`` as a suffix, you must run: + +.. code-block:: php + + $client->setUserAgent('MyPrefix', true); + +which will result in: + + User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz + +where ``$client`` is an instance of ``OpenCloud\OpenStack`` or +``OpenCloud\Rackspace``. + + +Other functionality +------------------- + +For a full list of functionality provided by Guzzle, please consult the +`official documentation`_. + +.. _official documentation: http://docs.guzzlephp.org/en/latest/http-client/client.html diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 000000000..9771b365c --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,77 @@ +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. + +.. note:: + + If you are running PHP 5.3, please see our :doc:`using-php-5.3` guide. + +Services +-------- + +.. toctree:: + :glob: + :maxdepth: 1 + + services/**/index + +Usage tips +---------- + +.. toctree:: + :maxdepth: 1 + + debugging + caching-creds + iterators + regions + url-types + logging + http-clients + auth + +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. + +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/logging.rst b/doc/logging.rst new file mode 100644 index 000000000..bb2a3de09 --- /dev/null +++ b/doc/logging.rst @@ -0,0 +1,33 @@ +Logging +======= + +Logger injection +---------------- + +As the ``Rackspace`` client extends the ``OpenStack`` client, they both support +passing ``$options`` as an array via the constructor's third parameter. The +options are passed as a config to the `Guzzle` client, but also allow to inject +your own logger. + +Your logger should implement the ``Psr\Log\LoggerInterface`` `as defined in +PSR-3 `_. +One example of a compatible logger is `Monolog `_. +When the client does create a service, it will inject the logger if one is +available. + +To inject a ``LoggerInterface`` compatible logger into a new client: + +.. code-block:: php + + use Monolog\Logger; + use OpenCloud\OpenStack; + + // create a log channel + $logger = new Logger('name'); + + $client = new OpenStack('http://identity.my-openstack.com/v2.0', array( + 'username' => 'foo', + 'password' => 'bar' + ), array( + 'logger' => $logger, + )); 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/requirements.txt b/doc/requirements.txt new file mode 100644 index 000000000..3f092f372 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1 @@ +sphinxcontrib-phpdomain 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..128986d91 --- /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 :doc:`supported regions page + `. + +* ``{urlType}`` is the :doc:`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..470ce8368 --- /dev/null +++ b/doc/services/compute/flavors.rst @@ -0,0 +1,62 @@ +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 */ + } + +`Get the executable PHP script for this example `_ + + +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..570790c04 --- /dev/null +++ b/doc/services/compute/images.rst @@ -0,0 +1,85 @@ +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) { + + } + +`Get the executable PHP script for this example `_ + + +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..823fcf5a2 --- /dev/null +++ b/doc/services/compute/keypairs.rst @@ -0,0 +1,70 @@ +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(); + +`Get the executable PHP script for this example `_ + + +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 + )); + +`Get the executable PHP script for this example `_ + + +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..3ebb99736 --- /dev/null +++ b/doc/services/compute/servers.rst @@ -0,0 +1,252 @@ +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 | ++--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------+ + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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 | ++-----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------+ +| user_data | User script to configure the server at launch time | string | 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. + +`Get the executable PHP script for this example `_ + + +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' + )); + + +`Get the executable PHP script for this example `_ + + +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. | ++--------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + + +Updating the access IP address(es) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For example, you may have a private cloud with internal addresses in the +10.1.x range. However, you can access a server via a firewall device at +address 50.57.94.244. In this case, you can change the ``accessIPv4`` +attribute to point to the firewall: + +.. code-block:: php + + $server->update(array('accessIPv4' => '50.57.94.244')); + +When a client application retrieves the server’s information, it will +know that it needs to use the ``accessIPv4`` address to connect to the +server, and *not* the IP address assigned to one of the network +interfaces. + + +Retrieving the server’s IP address +---------------------------------- + +The ``Server::ip()`` method is used to retrieve the server’s IP address. +It has one optional parameter: the format (either IPv4 or IPv6) of the +address to return (by default, it returns the IPv4 address): + +.. code-block:: php + + // IPv4 + echo $server->ip(); + echo $server->ip(4); + + // IPv6 + echo $server->ip(6); + + +Delete server +------------- + +.. code-block:: php + + $server->delete(); + +`Get the executable PHP script for this example `_ 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..12917ce6e --- /dev/null +++ b/doc/services/database/users.rst @@ -0,0 +1,79 @@ +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(); + + +Grant database access +--------------------- + +To grant access to one or more databases, you can run: + +.. code-block:: php + + $user = $instance->user('{userName}'); + $user->grantDbAccess(['{dbName1}', '{dbName2}']); + diff --git a/doc/services/dns/domains.rst b/doc/services/dns/domains.rst new file mode 100644 index 000000000..b6c60290c --- /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..944888902 --- /dev/null +++ b/doc/services/identity/users.rst @@ -0,0 +1,175 @@ +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) { + // ... + } + +`Get the executable PHP script for this example `_ + + +Retrieve a user by username +--------------------------- + +.. code-block:: php + + $user = $service->getUser('jamie'); + +`Get the executable PHP script for this example `_ + + +Retrieve a user by user ID +-------------------------- + +.. code-block:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + $user = $service->getUser('{userId}', UserConst::MODE_ID); + +`Get the executable PHP script for this example `_ + + +Retrieve a user by email address +-------------------------------- + +.. code-block:: php + + use OpenCloud\Identity\Constants\User as UserConst; + + $user = $service->getUser('{emailAddress}', UserConst::MODE_EMAIL); + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ 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..42cd68315 --- /dev/null +++ b/doc/services/load-balancer/access.rst @@ -0,0 +1,84 @@ +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. + +Get the executable PHP scripts for this example: + +* `Blacklist IP range `_ +* `Limit access to 1 IP `_ + + +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..d7867755d --- /dev/null +++ b/doc/services/load-balancer/load-balancer.rst @@ -0,0 +1,171 @@ +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. + +`Get the executable PHP script for this example `_ + + +Get 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 **/ + } + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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..413bdc612 --- /dev/null +++ b/doc/services/load-balancer/ssl.rst @@ -0,0 +1,54 @@ +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 `__ + +`Get the executable PHP script for this example `_ + + +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..3e2cf482e --- /dev/null +++ b/doc/services/networking/ports.rst @@ -0,0 +1,165 @@ +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 `_ + +The port list query may be filtered by numerous optional parameters as per the `API documentation `_ + +.. code-block:: php + + $ports = $networkingService->listPorts([ + 'status' => 'ACTIVE', + 'device_id' => '9ae135f4-b6e0-4dad-9e91-3c223e385824' + ]); + + 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..745339d97 --- /dev/null +++ b/doc/services/object-store/access.rst @@ -0,0 +1,104 @@ +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. + +Get the executable PHP script for this example: + +* `Specify a URL secret `_ +* `Generate random URL secret `_ + + +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'); + +`Get the executable PHP script for this example `_ + + +Override TempURL file names +--------------------------- + +Override tempURL file names simply by adding the filename parameter to the url: + +.. code-block:: php + + $tempUrl = $object->getTemporaryUrl(60, 'GET'); + $url = $tempUrl.'&filename='.$label; + + +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..50c17f1a8 --- /dev/null +++ b/doc/services/object-store/account.rst @@ -0,0 +1,52 @@ +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(); + +`Get the executable PHP script for this example `_ + + +Retrieve total object count +--------------------- + +.. code-block:: php + + $account->getObjectCount(); + +`Get the executable PHP script for this example `_ + + +Retrieve total bytes used +------------------------- + +.. code-block:: php + + $account->getBytesUsed(); + +`Get the executable PHP script for this example `_ diff --git a/doc/services/object-store/cdn.rst b/doc/services/object-store/cdn.rst new file mode 100644 index 000000000..b4eebc1b6 --- /dev/null +++ b/doc/services/object-store/cdn.rst @@ -0,0 +1,136 @@ +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 */ + } + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +CDN-disable a container +----------------------- + +.. code-block:: php + + $container->disableCdn(); + +`Get the executable PHP script for this example `_ + + +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}'); + +If you already have a container object and want to avoid instantiating a new service, you can also do: + +.. code-block:: php + + $cdnContainer = $container->getCdn(); + + +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..a2f0485e8 --- /dev/null +++ b/doc/services/object-store/containers.rst @@ -0,0 +1,247 @@ +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 + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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}'); + +`Get the executable PHP script for this example `_ + + +Retrieve a container's name +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $name = $container->name; + + +Retrieve a container's object count +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $count = $container->getObjectCount(); + +`Get the executable PHP script for this example `_ + + +Retrieve a container's total bytes used +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + $bytes = $container->getBytesUsed(); + +`Get the executable PHP script for this example `_ + + +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``. + +`Get the executable PHP script for this example `_ + + +Deleting all objects inside a container +--------------------------------------- + +.. code-block:: php + + $container->deleteAllObjects(); + +`Get the executable PHP script for this example `_ + + +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' + )); + +`Get the executable PHP script for this example `_ + + +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(); + +Get the executable PHP scripts for this example: + +* `Set bytes quota `_ +* `Set count quota `_ + + +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..2a985d20a --- /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; + + // maximum number of retries + $maxRetries = 10; + + // set HTTP error codes + $httpErrors = array(500, 503, 408); + + $backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, $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 ``internalURL`` +as the third argument in the ``objectStoreService`` methods like this: + +.. code-block:: php + + $client->objectStoreService('cloudFiles', 'IAD', 'internalURL'); + + +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..18d3e7502 --- /dev/null +++ b/doc/services/object-store/objects.rst @@ -0,0 +1,540 @@ +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``. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + + +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 +`_. + +`Get the executable PHP script for this example `_ + + +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 the executable PHP script for this example `_ + + +List over 10,000 objects +------------------------ + +To retrieve more than 10,000 objects (the default limit), you'll need to use +the built-in paging which uses a 'marker' parameter to fetch the next page of data. + +.. code-block:: php + + $containerObjects = array(); + $marker = ''; + + while ($marker !== null) { + $params = array( + 'marker' => $marker, + ); + + $objects = $container->objectList($params); + $total = $objects->count(); + $count = 0; + + if ($total == 0) { + break; + } + + foreach ($objects as $object) { + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ + $containerObjects[] = $object->getName(); + $count++; + + $marker = ($count == $total) ? $object->getName() : null; + } + } + +`Get the executable PHP script for this example `_ + + +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 $name string */ + $name = $object->getName(); + + +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->getContent(); + + +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 the executable PHP script for this example `_ + + +Symlinking to this object from another location +----------------------------------------------- + +To create a symlink to this file in another location you need to specify +a string-based source + +.. code-block:: php + + $object->createSymlinkFrom('/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 either does not exist yet or +is an empty file. + +`Get the executable PHP script for this example `_ + + +Setting this object to symlink to another location +-------------------------------------------------- + +To set this file to symlink to another location you need to specify +a string-based destination + +.. code-block:: php + + $object->createSymlinkTo('/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. + +The object must be an empty file. + +`Get the executable PHP script for this example `_ + + +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(); + +`Get the executable PHP script for this example `_ + + +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); + +`Get the executable PHP script for this example `_ + + +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. + +`Get the executable PHP script for this example `_ + +Delete object +--------------------------------- + +.. code-block:: php + + $container->deleteObject('{objectName}'); + + +`Get the executable PHP script for this example `_ + + +Delete already downloaded object +--------------------------------- + +.. code-block:: php + + $object->delete(); + +`Get the executable PHP script for this example `_ + + +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->batchDelete($pathsToBeDeleted); + +`Get the executable PHP script for this example `_ + +Check an object exists +---------------------- + +To check whether an object exists: + +.. code-block:: php + + /** @var bool $exists */ + $exists = $container->objectExists('{objectName}'); 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/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..1111cb9eb --- /dev/null +++ b/doc/services/queues/claims.rst @@ -0,0 +1,121 @@ +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 + )); + +`Get the executable PHP script for this example `_ + + +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..3a5dee89d --- /dev/null +++ b/doc/services/queues/messages.rst @@ -0,0 +1,203 @@ +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 + )); + +`Get the executable PHP script for this example `_ + + +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..f324e3f3b --- /dev/null +++ b/doc/services/queues/queues.rst @@ -0,0 +1,135 @@ +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'); + +`Get the executable PHP script for this example `_ + + +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(); + +Delete queue +------------ + +.. code-block:: php + + $queue->delete(); + +`Get the executable PHP script for this example `_ 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..555824a9d --- /dev/null +++ b/doc/services/volume/snapshots.rst @@ -0,0 +1,56 @@ +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 + )); + +`Get the executable PHP script for this example `_ + + +List snapshots +-------------- + +.. code-block:: php + + $snapshots = $service->snapshotList(); + + foreach ($snapshots as $snapshot) { + /** @param $snapshot OpenCloud\Volume\Resource\Snapshot */ + } + +`Get the executable PHP script for this example `_ + + +To get details on a single snapshot +----------------------------------- + +.. code-block:: php + + $snapshot = $dallas->snapshot('{snapshotId}'); + +`Get the executable PHP script for this example `_ + + +To delete a snapshot +-------------------- + +.. code-block:: php + + $snapshot->delete(); + +`Get the executable PHP script for this example `_ 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..a84ed0421 --- /dev/null +++ b/doc/services/volume/volumes.rst @@ -0,0 +1,88 @@ +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' + )); + +`Get the executable PHP script for this example `_ + + +List volumes +------------ + +.. code-block:: php + + $volumes = $service->volumeList(); + + foreach ($volumes as $volume) { + /** @param $volumeType OpenCloud\Volume\Resource\Volume */ + } + +`Get the executable PHP script for this example `_ + + +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; + +`Get the executable PHP script for this example `_ + + +To delete a volume +------------------ + +.. code-block:: php + + $volume->delete(); + +`Get the executable PHP script for this example `_ + + +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. diff --git a/doc/using-php-5.3.rst b/doc/using-php-5.3.rst new file mode 100644 index 000000000..8790710f2 --- /dev/null +++ b/doc/using-php-5.3.rst @@ -0,0 +1,20 @@ +Using the SDK with PHP v5.3 +=========================== + +Since PHP 5.3 has entered EOL and no longer receives security updates, we have bumped the minimum requirement to 5.4. Using 5.3 is still possible, however, but you will need to use an older stable version of the SDK. There are two ways to do this. + +The first way is by requiring it through the command line: + +.. code-block:: bash + + composer require rackspace/php-opencloud:1.12 + +The second way is by updating your composer.json file, and specifying the appropriate version of the SDK: + +.. code-block:: json + + "require": { + "rackspace/php-opencloud": "~1.12" + } + +Note that **1.12** is the last minor release supporting PHP 5.3. Version 1.13 and above has shifted to PHP 5.4. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..154fd158d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,3 @@ +# Documentation + +Our official docs are hosted on http://docs.php-opencloud.com. diff --git a/docs/changelog/1.7.0.md b/docs/changelog/1.7.0.md index 482f5950b..8e22e3f9e 100644 --- a/docs/changelog/1.7.0.md +++ b/docs/changelog/1.7.0.md @@ -20,7 +20,7 @@ For a complete list of features, [view the official page](http://guzzlephp.org). ## Keypair support -Although code now exists in the SDK for API compatability for creating servers with keypairs, there has been +Although code now exists in the SDK for API compatibility for creating servers with keypairs, there has been a recent bug in Nova where certain endpoints (DFW, IAD and ORD) do not exhibit the desired functionality. A patch will be released in the near future. For reference, you just need to add in an extra array key: diff --git a/docs/generate.sh b/docs/generate.sh old mode 100644 new mode 100755 index 01a43a58e..2c88f3eca --- a/docs/generate.sh +++ b/docs/generate.sh @@ -1,25 +1,43 @@ -#!/bin/bash -# (c)2013 Rackspace Hosting. See COPYING for license. +#!/bin/sh -DOC_DIR=docs/api -LIB_DIR=lib -BIN_FILE=vendor/bin/apigen.php +# Script to be used by Travis CI builds to generate the php-opencloud SDK API +# reference and publish it to the gh-pages branch of the rackerlabs/php-opencloud +# repository. -if [ ! -f $BIN_FILE ]; then - rm composer.lock - php composer.phar require apigen/apigen:dev-master --dev -fi +SOURCE_DIR=lib +WORK_DIR=build/api +API_DOCS_DIR=docs/api +REPO_REMOTE_URL=https://$GH_TOKEN@github.com/rackspace/php-opencloud -if [ ! -d $DOC_DIR ]; then - mkdir $DOC_DIR +# We want our generated API reference to reflect what is +# on the master branch. So if we aren't currently on +# the master branch, or we aren't part of a PR targetted +# to the master branch, do nothing. +if [ "$TRAVIS_BRANCH" != "master" ]; then + exit 0 fi -if [ ! -d docs ]; then - echo "No docs/ directory found; run this script from the top directory" - exit; +# Generate the API references +./vendor/bin/apigen generate \ + --source $SOURCE_DIR \ + --destination $WORK_DIR + +# Switch the branch to gh-pages +git checkout gh-pages +git pull --commit $REPO_REMOTE_URL gh-pages + +if [ $? -ne 0 ]; then + exit 1 fi -rm -rf DOCS_DIR +# Commit the generated API references +rm -rf $API_DOCS_DIR +mv $WORK_DIR $API_DOCS_DIR +git add -f $API_DOCS_DIR +git commit -m "Re-generated API documentation" + +# Push to the remote gh-pages branch so +# changes show up on php-opencloud.com +git push $REPO_REMOTE_URL gh-pages -# regenerate all the docs! -php $BIN_FILE -s $LIB_DIR -d $DOC_DIR --title="PHP OpenCloud API" --groups="namespaces" --download --progressbar \ No newline at end of file +git checkout master diff --git a/docs/getting-started-openstack.md b/docs/getting-started-openstack.md index a76134fe7..1133b948d 100644 --- a/docs/getting-started-openstack.md +++ b/docs/getting-started-openstack.md @@ -1,190 +1,5 @@ # Installing the SDK -You must install through Composer, because this library has a few dependencies: +Our docs have moved! Please visit the below link: -```bash -# Install Composer -curl -sS https://getcomposer.org/installer | php - -# Require php-opencloud as a dependency -php composer.phar require rackspace/php-opencloud:dev-master -``` - -Once you have installed the library, you will need to load Composer's autoloader (which registers all the required -namespaces): - -```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: - -```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: - -```php -$compute = $client->computeService('nova', 'regionOne'); -``` - -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. 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: - -```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: - -```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: - -```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: - -```php -$twoGbFlavor = $compute->flavor('4'); -``` - -## 5. Thunderbirds are go! - -Okay, you're ready to spin up a server: - -```php -$server = $compute->server(); - -try { - $response = $server->create(array( - 'name' => 'My lovely server', - 'image' => $ubuntu, - 'flavor' => $twoGbFlavor - )); -} catch (\Guzzle\Http\Exception\BadResponseException $e) { - - // No! Something failed. Let's find out: - - $responseBody = (string) $e->getResponse()->getBody(); - $statusCode = $e->getResponse()->getStatusCode(); - $headers = $e->getResponse()->getHeaderLines(); - - echo sprintf("Status: %s\nBody: %s\nHeaders: %s", $statusCode, $responseBody, implode(', ', $headers)); -} -``` - -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: - -`nova list` - -You can also execute a polling function immediately after the `create` method that checks the build process: - -```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: - -```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: - -```php -$server = $compute->server('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx'); -``` - -allowing you to update its properties: - -```php -$server->update(array( - 'name' => 'New server name' -)); -``` - -or delete it entirely: - -```php -$server->delete(); -``` - -# Next steps - -Consult our [documentation](https://github.com/rackspace/php-opencloud/tree/master/docs/userguide) about other services -you can use, like [Keystone](https://github.com/rackspace/php-opencloud/tree/master/docs/userguide/Identity) or -[Swift](https://github.com/rackspace/php-opencloud/tree/master/docs/userguide/ObjectStore). If you have any questions or -troubles, feel free to e-mail sdk-support@rackspace.com or open a Github issue with details. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/getting-started-with-openstack.html diff --git a/docs/getting-started.md b/docs/getting-started.md index 48f99fb86..c7d731a4c 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,178 +1,5 @@ # Installing the SDK -You must install through Composer, because this library has a few dependencies: +Our docs have moved! Please visit the below link: -```bash -# Install Composer -curl -sS https://getcomposer.org/installer | php - -# Require php-opencloud as a dependency -php composer.phar require rackspace/php-opencloud:dev-master -``` - -Once you have installed the library, you will need to load Composer's autoloader (which registers all the required -namespaces): - -```php -require 'vendor/autoload.php'; -``` - -And you're good to go! - -# Quick deep-dive: building some cloud servers - -In this example, you will write code that will create a Cloud Server running Ubuntu. - -### 1. Setup the client and pass in your credentials - -To authenticate against the Rackspace API and use its services: - -```php - 'foo', - 'apiKey' => 'bar' -)); -``` - -Alternatively, if you would like to validate against your own API, or just want to access OpenStack services: - -```php -use OpenCloud\OpenStack; - -$client = new OpenStack('http://identity.my-openstack.com/v2.0/', array( - 'username' => 'foo', - 'password' => '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: - -```php -$compute = $client->computeService('cloudServersOpenStack', '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: - -```php -$images = $compute->imageList(); -while ($image = $images->next()) { - if (strpos($image->name, 'Ubuntu') !== false) { - $ubuntu = $image; - break; - } -} -``` - -Alternatively, if you already know the image ID, you can do this much easier: - -```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: - -```php -$flavors = $compute->flavorList(); -while ($flavor = $flavors->next()) { - if (strpos($flavor->name, '2GB') !== false) { - $twoGbFlavor = $flavor; - break; - } -} -``` - -Again, it's much easier if you know the ID: - -```php -$twoGbFlavor = $compute->flavor('4'); -``` - -## 5. Thunderbirds are go! - -Okay, you're ready to spin up a server: - -```php -use OpenCloud\Compute\Constants\Network; - -$server = $compute->server(); - -try { - $response = $server->create(array( - 'name' => 'My lovely server', - 'image' => $ubuntu, - 'flavor' => $twoGbFlavor, - 'networks' => array( - $compute->network(Network::RAX_PUBLIC), - $compute->network(Network::RAX_PRIVATE) - ) - )); -} catch (\Guzzle\Http\Exception\BadResponseException $e) { - - // No! Something failed. Let's find out: - - $responseBody = (string) $e->getResponse()->getBody(); - $statusCode = $e->getResponse()->getStatusCode(); - $headers = $e->getResponse()->getHeaderLines(); - - echo sprintf("Status: %s\nBody: %s\nHeaders: %s", $statusCode, $responseBody, implode(', ', $headers)); -} -``` - -As you can see, you're creating a server called "My lovely server", and you've inserted it in two networks: the Rackspace -private network (ServiceNet), and the Rackspace public network (for Internet connectivity). This will take a few -minutes for the build to complete. - -You can also call a polling function that checks on the build process: - -```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. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/getting-started-with-rackspace.html diff --git a/docs/userguide/Autoscale/Config.md b/docs/userguide/Autoscale/Config.md old mode 100755 new mode 100644 index a619bf277..328fdcc93 --- a/docs/userguide/Autoscale/Config.md +++ b/docs/userguide/Autoscale/Config.md @@ -1,47 +1,5 @@ # Group configurations -##Intro +Our docs have moved! Please visit the below link: -There are two types of configuration associated with an Auto Scale group: - -- **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. - -## Setup - -To interact with the configuration of a scaling group, you will need to setup the group object beforehand: - -```php -$groupId = 'e41380ae-173c-4b40-848a-25c16d7fa83d'; -$group = $service->getGroup($groupId); -``` - -For more information about setting up the `$service` object, please see the userguide tutorial for [groups](). - -## Get group/launch configuration - -```php -$groupConfig = $group->getGroupConfig(); -$launchConfig = $group->getLaunchConfig(); -``` - -## Edit group/launch configuration - -```php -$groupConfig->update(array( - 'name' => 'New name!' -)); - -$launchConfig = $group->getLaunchConfig(); - -$server = $launchConfig->args->server; -$server->name = "BRAND NEW SERVER NAME"; - -$launchConfig->update(array - 'args' => array( - 'server' => $server, - 'loadBalancers' => $launchConfig->args->loadBalancers - ) -)); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/autoscale/group-config.html diff --git a/docs/userguide/Autoscale/Groups.md b/docs/userguide/Autoscale/Groups.md old mode 100755 new mode 100644 index 98dfb43dc..e0d8bfcdb --- a/docs/userguide/Autoscale/Groups.md +++ b/docs/userguide/Autoscale/Groups.md @@ -1,96 +1,5 @@ #Auto Scale groups -## Intro +Our docs have moved! Please visit the below link: -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. - -## Service setup - -Nothing special here; you setup your client and service objects in the same way as every other resource: - -```php -$service = $client->autoscaleService(); -``` - -Please consult the [client doc](docs/userguide/Client.md) for more information about creating clients. - -## List all groups - -```php -$groups = $service->groupList(); -``` - -Please consult the [iterator documentation](docs/userguide/Iterators.md) for more information about iterators. - -## Retrieve one group by ID - -```php -$group = $service->group('605e13f6-1452-4588-b5da-ac6bb468c5bf'); -``` - -## Create a new group - -You can create a new scaling group in two ways: either pass in a JSON string (easier option); or instantiate a new object and manually set its properties (a lot more verbose) - -```php - -// Easy way: - -$jsonString = <<create($jsonString); - -// More granular (and verbose) way: - -$object = new \stdClass; - -// Set the config object for this autoscale group; contains all of properties -// which determine its behaviour -$object->groupConfiguration = new \stdClass; -$object->groupConfiguration->name = 'New autoscale group'; -$object->groupConfiguration->minEntities = 5; -$object->groupConfiguration->maxEntities = 25; -$object->groupConfiguration->cooldown = 60; - -// We need specify what is going to be launched. For now, we'll launch a new server -$object->launchConfiguration = new \stdClass; -$object->launchConfiguration->type = 'launch_server'; - -// To launch a new server, we need two `args` properties: `server` and `loadBalancer` -$server = new \stdClass; -$server->flavorRef = 3; -$server->name = 'webhead'; -$server->imageRef = "0d589460-f177-4b0f-81c1-8ab8903ac7d8"; - -$loadBalancer = new \stdClass; -$loadBalancer->loadBalancerId = 2200; -$loadBalancer->port = 8081; - -$object->launchConfiguration->args = new \stdClass; -$object->launchConfiguration->args->server = $server; -$object->launchConfiguration->args->loadBalancers = array($loadBalancer); - -// Do we want particular scaling policies? -$policy = new \stdClass; -$policy->name = "scale up by 10"; -$policy->change = 10; -$policy->cooldown = 5; -$policy->type = "webhook"; - -$object->scalingPolicies = array($policy); - -$group->create($object); -``` - -## Delete an autoscale group -```php -$group->delete(); -``` - -## Get the current state of the scaling group - -```php -$group->getState(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/autoscale/groups.html diff --git a/docs/userguide/Autoscale/Policies.md b/docs/userguide/Autoscale/Policies.md old mode 100755 new mode 100644 index 6f3d1b282..1f890d7ad --- a/docs/userguide/Autoscale/Policies.md +++ b/docs/userguide/Autoscale/Policies.md @@ -1,68 +1,5 @@ #Policies -## Setup +Our docs have moved! Please visit the below link: -To interact with the policies of a scaling group, you will need to setup the group object beforehand. - -```php -$groupId = 'foobar'; -$group = $service->getGroup($groupId); -``` - -For more information about setting up the `$service` object, please see the userguide tutorial for [Autoscale groups](). - -## Get all policies - -```php -$policies = $group->getPolicies(); - -while ($policy = $policies->next()) { - // do something - echo "{$policy->name} {($policy->type)}" . PHP_EOL; -} -``` - -## Create a new scaling policy - -Creating policies is achieved through passing an array to the `create` method. - -```php -$policy = new \stdClass; -$policy->name = "NEW NAME"; -$policy->change = 1; -$policy->cooldown = 150; -$policy->type = "webhook"; - -$group->getPolicy()->create(array($policy)); - -// or even: - -$group->getPolicy()->create(array( - (object) array( - 'name' => 'NEW NAME', - 'change' => 1, - 'cooldown' => 150, - 'type' => 'webhook' - ), - // etc. -)); -``` - -## Get, update and delete a scaling policy - -```php -$policyId = 'foobar'; -$policy = $group->getPolicy($policyId); - -$policy->update(array( - 'name' => 'More relevant name' -)); - -$policy->delete(); -``` - -## Execute a scaling policy - -```php -$policy->execute(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/autoscale/policies.html diff --git a/docs/userguide/Autoscale/Webhooks.md b/docs/userguide/Autoscale/Webhooks.md old mode 100755 new mode 100644 index e634cc073..783075508 --- a/docs/userguide/Autoscale/Webhooks.md +++ b/docs/userguide/Autoscale/Webhooks.md @@ -1,52 +1,5 @@ # Webhooks -## Setup +Our docs have moved! Please visit the below link: -To interact with the webhooks of a group's scaling policy, you will need to setup the group and policy objects beforehand. - -```php -$groupId = 'foo'; -$policyId = 'bar'; - -$group = $service->getGroup($groupId); -$policy = $group->getPolicy($policyId); -``` - -For more information about setting up the `$service` object, please see the userguide tutorial for [Autoscale groups](). - -## Get all webhooks - -```php -$webhooks = $policy->getWebookList(); -``` - -## Create a new webhook - -```php -$policy->getWebhook()->create(array( - (object) array( - 'name' => 'Alice', - 'metadata' => array( - 'firstKey' => 'foo', - 'secondKey' => 'bar' - ) - ) -)); -``` - -## Get, update and delete an individual webhook - -```php -$webhookId = 'baz'; -$webhook = $policy->getWebhook($webhookId); - -// Update the metadata -$metadata = $webhook->metadata; -$metadata->thirdKey = 'blah'; -$webhook->update(array( - 'metadata' => $metadata -)); - -// Delete it -$webhook->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/autoscale/webhooks.html diff --git a/docs/userguide/CDN/README.md b/docs/userguide/CDN/README.md new file mode 100644 index 000000000..fbe813627 --- /dev/null +++ b/docs/userguide/CDN/README.md @@ -0,0 +1,96 @@ +# CDN + +**CDN** is a service that you can use to manage your CDN-enabled domains and the origins and assets associated with those domains. + +## Concepts + +To use the CDN service effectively, you should understand the following key concepts: + +* **Content delivery network**: A content delivery network (CDN) is a system of multiple computers that contains copies of data stored at various network nodes. A CDN is designed to improve performance of publicly distributed assets. Assets can be anything from website content, to web application components, to media such as videos, ads, and interactive experiences.  CDNs decrease the load time of these assets by caching them on edge servers, also called points of presence (PoPs).  Edge servers are distributed around the globe, meaning requests only travel to a local location to grab assets, rather than to and from a data center based far from the end user. + +* **Edge node**: CDN providers have many points of presence (PoP) servers around the world. These servers are known as edge nodes. These edge nodes cache the content and serve it directly to customers, thus reducing transit time to a customers location. + +* **Edge server**: An edge server is the same as an edge node. + +* **Origin**: An origin is an address (IP or domain) from which the CDN provider pulls content. A service can have multiple origins. + +* **Flavor**: A flavor is a configuration option. A flavor enables you to choose from a generic setting that is powered by one or more CDN providers. + +* **Service**: A service represents your web application that has its content cached to the edge nodes. + +* **Status**: The status indicates the current state of the service. The time it takes for a service configuration to be distributed amongst a CDN provider cache can vary. + +* **Purge**: Purging removes content from the edge servers - thus invalidating the content - so that it can be refreshed from your origin servers. + +* **Caching rule**: A caching rule provides you with fine-grained control over the time-to-live (TTL) of an object. When the TTL expires for an object, the edge node pulls the object from the origin again. + +* **Restriction**: A restriction enables you to define rules about who can or cannot access content from the cache. Examples of a restriction are allowing requests only from certain domains, geographies, or IP addresses. + +## Getting started + +### 1. Instantiate an OpenStack or Rackspace client. + +To use the CDN service, you must first instantiate a `OpenStack` or `Rackspace` client object. + +* If you are working with an OpenStack cloud, instantiate an `OpenCloud\OpenStack` client as follows: + + ```php + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + ``` + +* If you are working with the Rackspace cloud, instantiate a `OpenCloud\Rackspace` client as follows: + + ```php + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + ``` + +### 2. Obtain a CDN service object from the client. +All CDN operations are done via an _CDN service object_. To +instantiate this object, call the `cdnService` method on the `$client` +object. This method takes one argument: + +| Position | Description | Data type | Required? | Default value | Example value | +| -------- | ----------- | ----------| --------- | ------------- | ------------- | +| 1 | Name of the service, as it appears in the service catalog | String | No | `null`; automatically determined when possible | `rackCDN` | + + +```php +$cdnService = $client->cdnService(); +``` + +### 3. Create a service (to represent your web application). +```php +$service = $cdnService->createService(array( + 'name' => 'acme_site', + 'domains' => array( + array( + 'domain' => 'www.acme.com' + ), + array( + 'domain' => 'acme.com' + ) + ), + 'origins' => array( + array( + 'origin' => 'origin.acme.com' + ) + ), + 'flavorId' => 'cdn' +)); +``` + +[ [Get the executable PHP script for this example](/samples/CDN/create-service.php) ] + +## Next steps + +Once you have created a service, there is more you can do with it. See [complete user guide for CDN](USERGUIDE.md). \ No newline at end of file diff --git a/docs/userguide/CDN/USERGUIDE.md b/docs/userguide/CDN/USERGUIDE.md new file mode 100644 index 000000000..971175219 --- /dev/null +++ b/docs/userguide/CDN/USERGUIDE.md @@ -0,0 +1,294 @@ +# Complete User Guide for the CDN Service + +CDN is a service that you can use to manage your CDN-enabled domains and the origins and assets associated with those domains. + +## Table of contents + * [Concepts](#concepts) + * [Prerequisites](#prerequisites) + * [Client](#client) + * [CDN service](#cdn-service) + * [Services](#services) + * [Create a service](#create-a-service-to-represent-your-web-application) + * [List Services](#list-services) + * [Get a service](#get-a-service) + * [Update a service](#update-a-service) + * [Delete a service](#delete-a-service) + * [Service Assets](#service-assets) + * [Purge all cached service assets](#purge-all-cached-service-assets) + * [Purge a specific cached service asset](#purge-a-specific-cached-service-asset) + * [Flavors](#flavors) + * [List flavors](#list-flavors) + * [Get a flavor](#get-a-flavor) + +## Concepts + +To use the CDN service effectively, you should understand the following +key concepts: + +* **Content delivery network**: A content delivery network (CDN) is a system of multiple computers that contains copies of data stored at various network nodes. A CDN is designed to improve performance of publicly distributed assets. Assets can be anything from website content, to web application components, to media such as videos, ads, and interactive experiences.  CDNs decrease the load time of these assets by caching them on edge servers, also called points of presence (PoPs).  Edge servers are distributed around the globe, meaning requests only travel to a local location to grab assets, rather than to and from a data center based far from the end user. + +* **Edge node**: CDN providers have many points of presence (PoP) servers around the world. These servers are known as edge nodes. These edge nodes cache the content and serve it directly to customers, thus reducing transit time to a customers location. + +* **Edge server**: An edge server is the same as an edge node. + +* **Origin**: An origin is an address (IP or domain) from which the CDN provider pulls content. A service can have multiple origins. + +* **Flavor**: A flavor is a configuration option. A flavor enables you to choose from a generic setting that is powered by one or more CDN providers. + +* **Service**: A service represents your web application that has its content cached to the edge nodes. + +* **Status**: The status indicates the current state of the service. The time it takes for a service configuration to be distributed amongst a CDN provider cache can vary. + +* **Purge**: Purging removes content from the edge servers - thus invalidating the content - so that it can be refreshed from your origin servers. + +* **Caching rule**: A caching rule provides you with fine-grained control over the time-to-live (TTL) of an object. When the TTL expires for an object, the edge node pulls the object from the origin again. + +* **Restriction**: A restriction enables you to define rules about who can or cannot access content from the cache. Examples of a restriction are allowing requests only from certain domains, geographies, or IP addresses. + + +## Prerequisites + +### Client +To use the CDN service, you must first instantiate a `OpenStack` or `Rackspace` client object. + +* If you are working with an OpenStack cloud, instantiate an `OpenCloud\OpenStack` client as follows: + + ```php + use OpenCloud\OpenStack; + + $client = new OpenStack('', array( + 'username' => '', + 'password' => '' + )); + ``` + +* If you are working with the Rackspace cloud, instantiate a `OpenCloud\Rackspace` client as follows: + + ```php + use OpenCloud\Rackspace; + + $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + 'username' => '', + 'apiKey' => '' + )); + ``` + +### CDN service + +All CDN operations are done via an _CDN service object_. To +instantiate this object, call the `cdnService` method on the `$client` +object. This method takes one argument: + +| Position | Description | Data type | Required? | Default value | Example value | +| -------- | ----------- | ----------| --------- | ------------- | ------------- | +| 1 | Name of the service, as it appears in the service catalog | String | No | `null`; automatically determined when possible | `rackCDN` | + + +```php +$cdnService = $client->cdnService(); +``` + +## Services + +A service represents your web application that has its content cached to the edge nodes. + +### Create a service (to represent your web application) + + +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 service. This name must be unique. | String | Yes | - | `acme_site` | +| `flavorId` | The ID of the flavor to use for this service. | String | Yes | - | `cdn` | +| `domains` | List of domain for your service. | Array of associative arrays | Yes | - | `array( ... )` | +| `domains[n]` | Information about a domain for your service. | Associative array | Yes | - | `array( ... )` | +| `domains[n]['domain']` | A domain name used by your service. | String | Yes | - | 'www.acme.com' | +| `domains[n]['protocol']` | The protocol used by your service web site, `http` or `https`. | String | No | `http` | `http` | +| `origins` | List of origin servers for your service. | Array of associative arrays | Yes | - | `array( ... )` | +| `origins[n]` | Information about an origin server for your service. | Associative array | Yes | - | `array( ... )` | +| `origins[n]['origin']` | The origin server address, from where the CDN will pull your web site's assets. | String | Yes | - | `origin.acme.com` | +| `origins[n]['port']` | The origin server's port. | Integer | No | 80 | `8080` | +| `origins[n]['ssl']` | Whether origin server uses SSL. | Boolean | No | `false` | `true` | +| `origins[n]['rules']` | List of rules defining the conditions when this origin should be accessed. | Array of associative arrays | No | `null` | `array( ... )` | +| `origins[n]['rules'][n]` | Information about an access rule. | Associative array | No | `null` | `array( ... )` | +| `origins[n]['rules'][n]['name']` | A human-readable name of the rule. | String | No | `null` | `images` | +| `origins[n]['rules'][n]['requestUrl']` | The request URL this rule should match (regex supported). | String | No | `null` | `^/images/.+$` | +| `caching` | List of TTL rules for assets of this service. | Array of associative arrays | No | `null` | `array( ... )` | +| `caching[n]` | Information about a TTL rule. | Associative array | No | `null` | `array( ... )` | +| `caching[n]['name']` | A human-readable name of the TTL rule. | String | No | `null` | `long_ttl` | +| `caching[n]['ttl']` | The TTL value, in seconds. | Integer | No | `null` | `604800` | +| `caching[n]['rules']` | List of rules that determine if this TTL should be applied to an asset. | Array of associative arrays | No | `null` | `array( ... )` | +| `caching[n]['rules'][n]` | Information about a TTL rule. | Associative array | No | `null` | `array( ... )` | +| `caching[n]['rules'][n]['name']` | A human-readable name of the TTL rule. | No | `null` | `images` | +| `caching[n]['rules'][n]['requestUrl']` | The request URL this rule should match (regex supported). | String | No | `null` | `^/images/.+$` | +| `restrictions` | List of restrictions on where the service can be accessed from. | Array of associative arrays | No | `null` | `array( ... )` | +| `restrictions[n]` | Information about an access restriction. | Associative array | No | `null` | `array( ... )` | +| `restrictions[n]['name']` | A human-readable name of the restriction. | String | No | `null` | `affiliate_sites_only` | +| `restrictions[n]['rules']` | List of restriction rules. | Array of associative arrays | No | `null` | `array( ... )` | +| `restrictions[n]['rules'][n]` | Information about a restriction rule. | Associative array | No | `null` | `array( ... )` | +| `restrictions[n]['rules'][n]['name']` | A human-readable name of the restriction rule. | String | No | `null` | `Wile E. Coyote's site` | +| `restrictions[n]['rules'][n]['referrer']` | The domain from which the service can be accessed. | String | No | `null` | `www.wilecoyote.com` | + +You can create a service as shown in the following example: + +```php +$service = $cdnService->createService(array( + 'name' => 'acme_site', + 'domains' => array( + array( + 'domain' => 'www.acme.com' + ), + array( + 'domain' => 'acme.com' + ) + ), + 'origins' => array( + array( + 'origin' => 'origin.acme.com' + ) + ), + 'flavorId' => 'cdn' +)); +``` + +[ [Get the executable PHP script for this example](/samples/CDN/create-service.php) ] + +### List Services + +You can list all the services you have created as shown in the following example: + +```php +$services = $cdnService->listServices(); +foreach ($services as $service) { + /** @var $service OpenCloud\CDN\Resource\Service **/ +} +``` + +[ [Get the executable PHP script for this example](/samples/CDN/list-services.php) ] + +### Get a service + +You can retrieve a specific service by using that service's ID, as shown in the following example: + +```php +$service = $cdnService->getService('0e09ad12-2bfe-4607-80fd-116fa68d9c79'); +/** @var $service OpenCloud\CDN\Resource\Service **/ +``` + +[ [Get the executable PHP script for this example](/samples/CDN/get-service.php) ] + +### Update a service + +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 service. This name must be unique. | String | Yes | - | `acme_site` | +| `flavorId` | The ID of the flavor to use for this service. | String | Yes | - | `cdn` | +| `domains` | List of domain for your service. | Array of associative arrays | Yes | - | `array( ... )` | +| `domains[n]` | Information about a domain for your service. | Associative array | Yes | - | `array( ... )` | +| `domains[n]['domain']` | The domain name for your service. | String | Yes | - | 'www.acme.com' | +| `domains[n]['protocol']` | The protocol used by your service web site, `http` or `https`. | String | No | `http` | `http` | +| `origins` | List of origin servers for your service. | Array of associative arrays | Yes | - | `array( ... )` | +| `origins[n]` | Information about an origin server for your service. | Associative array | Yes | - | `array( ... )` | +| `origins[n]['origin']` | The origin server address, from where the CDN will pull your web site's assets. | String | Yes | - | `origin.acme.com` | +| `origins[n]['origin']['port']` | The origin server's port. | Integer | No | 80 | `8080` | +| `origins[n]['origin']['ssl']` | Whether origin server uses SSL. | Boolean | No | `false` | `true` | +| `origins[n]['origin']['rules']` | List of rules defining the conditions when this origin should be accessed. | Array of associative arrays | No | `null` | `array( ... )` | +| `origins[n]['origin']['rules'][n]` | Information about an access rule. | Associative array | No | `null` | `array( ... )` | +| `origins[n]['origin']['rules'][n]['name']` | A human-readable name of the rule. | String | No | `null` | `images` | +| `origins[n]['origin']['rules'][n]['requestUrl']` | The request URL this rule should match (regex supported). | String | No | `null` | `^/images/.+$` | +| `caching` | List of TTL rules for assets of this service. | Array of associative arrays | No | `null` | `array( ... )` | +| `caching[n]` | Information about a TTL rule. | Associative array | No | `null` | `array( ... )` | +| `caching[n]['name']` | A human-readable name of the TTL rule. | String | No | `null` | `long_ttl` | +| `caching[n]['ttl']` | The TTL value, in seconds. | Integer | No | `null` | `604800` | +| `caching[n]['rules']` | List of rules that determine if this TTL should be applied to an asset. | Array of associative arrays | No | `null` | `array( ... )` | +| `caching[n]['rules'][n]` | Information about a TTL rule. | Associative array | No | `null` | `array( ... )` | +| `caching[n]['rules'][n]['name']` | A human-readable name of the TTL rule. | No | `null` | `images` | +| `caching[n]['rules'][n]['requestUrl']` | The request URL this rule should match (regex supported). | String | No | `null` | `^/images/.+$` | +| `restrictions` | List of restrictions on where the service can be accessed from. | Array of associative arrays | No | `null` | `array( ... )` | +| `restrictions[n]` | Information about an access restriction. | Associative array | No | `null` | `array( ... )` | +| `restrictions[n]['name']` | A human-readable name of the restriction. | String | No | `null` | `affiliate_sites_only` | +| `restrictions[n]['rules']` | List of restriction rules. | Array of associative arrays | No | `null` | `array( ... )` | +| `restrictions[n]['rules'][n]` | Information about a restriction rule. | Associative array | No | `null` | `array( ... )` | +| `restrictions[n]['rules'][n]['name']` | A human-readable name of the restriction rule. | String | No | `null` | `Wile E. Coyote's site` | +| `restrictions[n]['rules'][n]['referrer']` | The domain from which the service can be accessed. | String | No | `null` | `www.wilecoyote.com` | + +You can update a service as shown in the following example: + +```php +$service->update(array( + 'origins' => array( + array( + 'origin' => '44.33.22.11', + 'port' => 80, + 'ssl' => false + ) + ) +)); +``` + +[ [Get the executable PHP script for this example](/samples/CDN/update-service.php) ] + +### Delete a service + +You can delete a service as shown in the following example: + +```php +$service->delete(); +``` + +[ [Get the executable PHP script for this example](/samples/CDN/delete-service.php) ] + +## Service Assets +A service will have its assets distributed and cached across a CDN's edge nodes. + +### Purge all cached service assets + +You can purge all cached assets of a service as shown in the following example: + +```php +$service->purgeAssets(); +``` + +[ [Get the executable PHP script for this example](/samples/CDN/purge-cached-service-assets.php) ] + +### Purge a specific cached service asset + +You can purge a specific asset of a service by providing its relative URL, as shown in the following example: + +```php +$service->purgeAssets('/images/logo.png'); +``` + +[ [Get the executable PHP script for this example](/samples/CDN/purge-cached-service-asset.php) ] + +## Flavors + +A flavor is a configuration option. A flavor enables you to choose from a generic setting that is powered by one or more CDN providers. + +### List flavors + +You can list all available flavors as shown in the following example: + +```php +$flavors = $cdnService->listFlavors(); +foreach ($flavors as $flavor) { + /** @var $flavor OpenCloud\CDN\Resource\Flavor **/ +} +``` + +[ [Get the executable PHP script for this example](/samples/CDN/list-flavors.php) ] + +### Get a flavor + +You can retrieve a specific flavor by using that flavor's ID, as shown in the +following example: + +```php +$flavor = $cdnService->getFlavor('cdn'); +/** @var $flavor OpenCloud\CDN\Resource\Flavor **/ +``` + +[ [Get the executable PHP script for this example](/samples/CDN/get-flavor.php) ] diff --git a/docs/userguide/Clients.md b/docs/userguide/Clients.md index 954769de7..762a7ed70 100644 --- a/docs/userguide/Clients.md +++ b/docs/userguide/Clients.md @@ -1,99 +1,5 @@ # Clients -## Overview +Our docs have moved! Please visit the below link: -A Client is the object responsibile for issuing HTTP requests and receiving responses from the API. In short, it forms the core of the SDK because it controls how functionality is executed. All services depend on the client to work. - -Users have access to two types of client: `OpenCloud\OpenStack` and `OpenCloud\Rackspace`. The latter extends the former, meaning that much of the functionality is shared between them. The OpenStack client extends functionality from other base classes, that trace all the way back to Guzzle's root class: - -1. `Guzzle\Http\Client` -2. `OpenCloud\Common\Http\Client` -3. `OpenCloud\OpenStack` -4. `OpenCloud\Rackspace` - -## Initializing a client - -### Rackspace - -First, you need to select the Identity endpoint you want to authenticate against. If you're using Rackspace, you can either use the UK or US endpoints. There are class constants defined for your convenience: - -- `OpenCloud\Rackspace::US_IDENTITY_ENDPOINT` (https://identity.api.rackspacecloud.com/v2.0) -- `OpenCloud\Rackspace::UK_IDENTITY_ENDPOINT` (https://lon.identity.api.rackspacecloud.com/v2.0) - -Then you need to find your username and apiKey. Your username will be visible at the top right of the Rackspace Control panel; and your API key can be retrieved by going to Account Settings. Once this is done: - -```php -use OpenCloud\OpenStack; - -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => 'foo', - 'apiKey' => 'bar' -)); -``` - -### OpenStack - -To initialize an OpenStack client, the process is the same: - -```php -use OpenCloud\OpenStack; - -$client = new OpenStack('http://identity.my-openstack.com/v2.0', array( - 'username' => 'foo', - 'password' => 'bar' -)); -``` - -## Authentication - -The Client does not automatically authenticate against the API on object creation - it waits for an API call. When this happens, it checks whether the current "token" has expired, and (re-)authenticates if necessary. - -You can force authentication, by calling: - -```php -$client->authenticate(); -``` - -If the credentials are incorrect, a `401` error will be returned. If credentials are correct, a `200` status is returned with your Service Catalog. - -## Service Catalog - -The Service Catalog is returned on successful authentication, and is composed of all the different API services available to the current tenant. All of this functionality is encapsulated in the `Catalog` object, which allows you greater control and interactivity. - -```php -/** @var OpenCloud\Common\Service\Catalog */ -$catalog = $client->getCatalog(); - -// Return a list of OpenCloud\Common\Service\CatalogItem objects -foreach ($catalog->getItems() as $catalogItem) { - - $name = $catalogItem->getName(); - $type = $catalogItem->getType(); - - if ($name == 'cloudServersOpenStack' && $type == 'compute') { - break; - } - - // Array of OpenCloud\Common\Service\Endpoint objects - $endpoints = $catalogItem->getEndpoints(); - foreach ($endpoints as $endpoint) { - if ($endpoint->getRegion() == 'DFW') { - echo $endpoint->getPublicUrl(); - } - } -} -``` - -As you can see, you have access to each Service's name, type and list of endpoints. Each endpoint provides access to the specific region, along with its public and private endpoint URLs. - -## Default HTTP headers - -To set default HTTP headers: - -```php -$client->setDefaultOption('headers/X-Custom-Header', 'FooBar'); -``` - -## Other functionality - -For a full list of functionality provided by Guzzle, please consult the [official documentation](http://docs.guzzlephp.org/en/latest/http-client/client.html). \ No newline at end of file +http://docs.php-opencloud.com/en/latest/index.html diff --git a/docs/userguide/CloudMonitoring/Agents.md b/docs/userguide/CloudMonitoring/Agents.md old mode 100755 new mode 100644 index 7e67e7d0b..f1b8cab5d --- a/docs/userguide/CloudMonitoring/Agents.md +++ b/docs/userguide/CloudMonitoring/Agents.md @@ -1,149 +1,5 @@ # Agents -## Intro +Our docs have moved! Please visit the below link: -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](http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-agent.html). - -## Setup - -```php -$agentId = '00-agent.example.com'; -$agent = $service->getAgent($agentId); -``` - -You can view the [service page](Service.md) for more information about setting up the Cloud Monitoring service. - -## List agents - -```php -$agents = $service->getAgents(); - -foreach ($agents as $agent) { - echo $agent->getLastConnected(); -} -``` - -Please consult the [iterator doc](docs/userguide/Iterators.md) for more information about iterators. - -## List connections - -```php -$connections = $agent->getConnections(); -``` - -Please consult the [iterator doc](docs/userguide/Iterators.md) for more information about iterators. - -## Get connection -```php -/** @var \OpenCloud\CloudMonitoring\Resource\AgentConnection */ -$connection = $agent->getConnection('cntl4qsIbA'); -``` - -### Agent Connection properties - -Name|Description|Type|Method -----|-----------|----|------ -id|-|-|`getId()` -guid|-|-|`getGuid()` -agent_id|-|-|`getAgentId()` -endpoint|-|-|`getEndpoint()` -process_version|-|-|`getProcessVersion()` -bundle_version|-|-|`getBundleVersion()` -agent_ip|-|-|`getAgentIp()` - - -# Agent tokens - -## Intro - -Agent tokens are used to authenticate Monitoring agents to the Monitoring Service. Multiple agents can share a single token. - -## Setup -```php -$tokenId = '4c5e28f0-0b3f-11e1-860d-c55c4705a286:1234'; -$agentToken = $service->getAgentToken($tokenId); -``` - -## Create agent token -```php -$newToken = $service->getAgentToken(); -$newToken->create(array('label' => 'Foobar')); -``` - -## List agent tokens -```php -$agentTokens = $service->getAgentTokens(); - -foreach ($agentTokens as $token) { - echo $token->getLabel(); -} -``` - -Please consult the [iterator doc](docs/userguide/Iterators.md) for more information about iterators. - -## Update and delete Agent Token -```php -// Update -$token->update(array( - 'label' => 'New label' -)); - -// Delete -$token->delete(); -``` - -# Agent Host Information - -## Info - -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 -```php -$host = $monitoringService->getAgentHost(); -``` - -## Get some metrics -```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 - -## Info - -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 -```php -$targets = $service->getAgentTargets(); - -foreach ($targets as $target) { - echo $target->getType(); -} - -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/agents.html diff --git a/docs/userguide/CloudMonitoring/Alarms.md b/docs/userguide/CloudMonitoring/Alarms.md old mode 100755 new mode 100644 index bf4a75652..b64c1e948 --- a/docs/userguide/CloudMonitoring/Alarms.md +++ b/docs/userguide/CloudMonitoring/Alarms.md @@ -1,56 +1,5 @@ # Alarms -## Info +Our docs have moved! Please visit the below link: -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](http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/alerts-language.html). - -## Setup - -Alarms are sub-resources of Entities: - -```php -$alarmId = 'alAAAA'; -$alarm = $check->getAlarm(); -``` - -For more information about working with Checks, please see the [appropriate documentation](Checks.md). - -## Attributes - -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 -```php -$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 -```php -$alarms = $entity->getAlarms(); - -foreach ($alarms as $alarm) { - echo $alarm->getId(); -} -``` - -## Update and delete Alarm -```php -// Update -$alarm->update(array( - 'criteria' => 'if (metric["duration"] >= 5) { return new AlarmStatus(OK); } return new AlarmStatus(CRITICAL);' -)); - -// Delete -$alarm->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/alarms.html diff --git a/docs/userguide/CloudMonitoring/Changelogs.md b/docs/userguide/CloudMonitoring/Changelogs.md old mode 100755 new mode 100644 index 0f8fe48d0..a1d137c9f --- a/docs/userguide/CloudMonitoring/Changelogs.md +++ b/docs/userguide/CloudMonitoring/Changelogs.md @@ -1,14 +1,5 @@ # Changelogs -## Info +Our docs have moved! Please visit the below link: -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. - -## Working with Changelogs -```php -$changelog = $service->getChangelog(); - -foreach ($changelog as $item) { - $entity = $item->getEntityId(); -} -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/changelogs.html diff --git a/docs/userguide/CloudMonitoring/Checks.md b/docs/userguide/CloudMonitoring/Checks.md old mode 100755 new mode 100644 index 265c0675d..37aefb644 --- a/docs/userguide/CloudMonitoring/Checks.md +++ b/docs/userguide/CloudMonitoring/Checks.md @@ -1,141 +1,5 @@ # Checks -## Info +Our docs have moved! Please visit the below link: -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). - -## Setup - -Checks are sub-resources of Entities: -```php -$checkId = 'chAAAA'; -$check = $entity->getCheck($checkId); -``` - -## 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) - -###Attributes used for 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 (before create) -```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' -); - -// You can do a test to see what would happen -// if a Check is launched with these params -$response = $entity->testNewCheckParams($params); - -echo $response->timestamp; // When was it executed? -echo $response->available; // Was it available? -echo $response->status; // Status code -``` -## Create a Check -```php -$entity->createCheck($params); -``` - -## Test existing Check -```php -// Set arg to TRUE for debug information -$response = $check->test(true); - -echo $response->debug_info; -``` - -## List Checks -```php -$checks = $entity->getChecks(); - -foreach ($checks as $check) { - echo $check->getId(); -} -``` - -### Update and delete Check -```php -// Update -$check->update(array('period' => 500)); - -// Delete -$check->delete(); -``` - -# Check types - -## Info - -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](http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/appendix-check-types.html). - -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. - -## Setup - -If you want to see the type for an existing Check: - -```php -/** @var \OpenCloud\CloudMonitoring\Resource\CheckType */ -$checkType = $check->getCheckType(); -``` - -Alternatively, you can retrieve a specific type based on its ID: - -```php -$checkTypeId = 'remote.dns'; -$checkType = $service->getCheckType($checkTypeId); -``` - -## 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()` - -## List all possible check types -```php -$checkTypes = $service->getCheckTypes(); - -foreach ($checkTypes as $checkType) { - echo $checkType->getId(); -} -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/checks.html diff --git a/docs/userguide/CloudMonitoring/Entities.md b/docs/userguide/CloudMonitoring/Entities.md old mode 100755 new mode 100644 index c9885604b..0f09a74a2 --- a/docs/userguide/CloudMonitoring/Entities.md +++ b/docs/userguide/CloudMonitoring/Entities.md @@ -1,55 +1,5 @@ # Entities -## Info +Our docs have moved! Please visit the below link: -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. - -## Setup - -```php -$entity = $service->getEntity(); -``` - -For more information about setting up the `$service` object, please see the userguide tutorial for [services](Service.md). - -## Attributes - -Name|Description|Required?|Data type|Method ----|---|---|---|--- -label|Defines a name for the entity.|Required|String (1..255 chars)|`getLabel()` -agent_id|Agent to which this entity is bound to.|Optional|String matching the regex: `/^[-\.\w]{1,255}$/`|`getAgentId()` -ip_addresses|Hash of IP addresses that can be referenced by checks on this entity.|Optional|Array|`getIpAddresses()` -metadata|Arbitrary key/value pairs that are passed during the alerting phase.|Optional|`OpenCloud\Common\Metadata`|`getMetadata()` - -## Create Entity -```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' - ) -)); -``` - - -## Update and delete Entity -```php -// Update -$entity->update(array( - 'label' => 'New label for my entity' -)); - -// Delete -$entity->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/entities.html diff --git a/docs/userguide/CloudMonitoring/Metrics.md b/docs/userguide/CloudMonitoring/Metrics.md old mode 100755 new mode 100644 index 6799f8881..86450bee9 --- a/docs/userguide/CloudMonitoring/Metrics.md +++ b/docs/userguide/CloudMonitoring/Metrics.md @@ -1,79 +1,5 @@ # Metrics -## Info +Our docs have moved! Please visit the below link: -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 - -Metrics are sub-resources of Checks. For more information about working with Checks, please see the [relevant documentation](Checks.md). - -## List all metrics -```php -$metrics = $check->getMetrics(); - -foreach ($metrics as $metric) { - echo $metric->getName(); -} -``` - -## Fetch data points -```php -$data = $check->fetchDataPoints('mzdfw.available', array( - 'resolution' => 'FULL', - 'from' => 1369756378450, - 'to' => 1369760279018 -)); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/metrics.html diff --git a/docs/userguide/CloudMonitoring/Notifications.md b/docs/userguide/CloudMonitoring/Notifications.md old mode 100755 new mode 100644 index 81a890f56..30a1cf97c --- a/docs/userguide/CloudMonitoring/Notifications.md +++ b/docs/userguide/CloudMonitoring/Notifications.md @@ -1,203 +1,5 @@ # Notifications -## Info +Our docs have moved! Please visit the below link: -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). - -## Setup - -```php -$id = 'ntAAAA'; -$notification = $service->getNotification($id); -``` - -## Attributes - -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()` - -## Test parameters -```php -$params = array( - 'label' => 'My webhook #1', - 'type' => 'webhook', - 'details' => array( - 'url' => 'http://example.com' - ) -); - -// Test it -$response = $notification->testParams($params); - -if ($response->status == 'Success') { - echo $response->message; -} -``` - -## Create Notification - -```php -$notification->create($params); -``` - -## Test existing notification -```php -$response = $notification->testExisting(true); -echo $response->debug_info; -``` - -## List Notifications -```php -$notifications = $service->getNotifications(); - -foreach ($notifications as $notification) { - echo $notification->getId(); -} -``` - -## Update and delete Notifications -```php -// Update -$notification->update(array( - 'label' => 'New notification label' -)); - -// Delete -$notification->delete(); -``` - -# Notification types - -## Info - -Pretty self-explanatory. 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: - -```php -$type = $notification->getNotificationType(); -``` - -Alternatively, you can retrieve an independent resource using the ID: - -```php -$typeId = 'pagerduty'; -$type = $service->getNotificationType($typeId); -``` - -## List all possible notification types -```php -$types = $service->getNotificationTypes(); - -foreach ($types as $type) { - echo sprintf('%s %s', $type->getName(), $type->getDescription()); -} -``` - -# Notification plans - -## Info - -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. - -## Setup - -```php -$planId = 'npAAAA'; -$plan = $service->getNotificationPlan(); -``` - -## Attributes - -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 -```php -$plan->create(array( - 'label' => 'New Notification Plan', - 'critical_state' => array('ntAAAA'), - 'ok_state' => array('ntBBBB'), - 'warning_state' => array('ntCCCC') -)); -``` - -## Update and delete Notification Plan - -```php -// Update -$plan->update(array( - 'label' => 'New label for my plan' -)); - -// Delete -$plan->delete(); -``` - -# Alarm Notification History - -## Info - -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 - -Notification History is a sub-resource of an Alarm. For more information about working with Alarms, please consult the relevant [documentation](Alarms.md). - -## Discover which Checks have a Notification History - -This operation list checks for which alarm notification history is available: - -```php -$checks = $alarm->getRecordedChecks(); -``` - -## List Alarm Notification History for a particular Check -```php -$checkHistory = $alarm->getNotificationHistoryForCheck('chAAAA'); -``` - -## Get a particular Notification History item -```php -$checkId = 'chAAAA'; -$itemUuid = '646ac7b0-0b34-11e1-a0a1-0ff89fa2fa26'; - -$singleItem = $history->getNotificationHistoryItem($checkId, $itemUuid); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/notifications.html diff --git a/docs/userguide/CloudMonitoring/Service.md b/docs/userguide/CloudMonitoring/Service.md old mode 100755 new mode 100644 index 5647eedc2..be9f9435f --- a/docs/userguide/CloudMonitoring/Service.md +++ b/docs/userguide/CloudMonitoring/Service.md @@ -1,16 +1,5 @@ # Cloud Monitoring Service -Initializing the Cloud Monitoring is easy - and can be done in a similar way to all other Rackspace services: +Our docs have moved! Please visit the below link: -1. Create client and pass in auth details. For more information about creating clients, please consult the [Client documentation](../Clients.md). -2. Use the factory method, specifying additional parameters where necessary: - -```php -$service = $client->cloudMonitoringService('cloudMonitoring', 'ORD', 'publicURL'); -``` - -All three parameters are optional - if not specified, it will revert to the service's default values which are: - -- Name = `cloudMonitoring` -- Region = `DFW` -- URL type = `publicURL` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/index.html diff --git a/docs/userguide/CloudMonitoring/Views.md b/docs/userguide/CloudMonitoring/Views.md old mode 100755 new mode 100644 index b6b505efc..7672c2ea8 --- a/docs/userguide/CloudMonitoring/Views.md +++ b/docs/userguide/CloudMonitoring/Views.md @@ -1,19 +1,5 @@ # Views -## Info +Our docs have moved! Please visit the below link: -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 - -```php -$views = $service->getViews(); - -foreach ($views as $view) { - $entity = $view->getEntity(); - - echo $view->getTimestamp(); -} - ``` - -Please consult the [iterator doc](docs/userguide/Iterators.md) for more information about iterators. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/views.html diff --git a/docs/userguide/CloudMonitoring/Zones.md b/docs/userguide/CloudMonitoring/Zones.md old mode 100755 new mode 100644 index 338bb1053..8257efa29 --- a/docs/userguide/CloudMonitoring/Zones.md +++ b/docs/userguide/CloudMonitoring/Zones.md @@ -1,46 +1,5 @@ # Zones -## Info +Our docs have moved! Please visit the below link: -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. - -## Setup -```php -$zoneId = 'mzAAAAA'; -$zone = $monitoringService->getMonitoringZone($zoneId); -``` - -## Attributes - -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 - -```php -$zones = $service->getMonitoringZones(); -``` - -Please consult the [iterator doc](docs/userguide/Iterators.md) for more information about iterators. - -## Perform a traceroute - -```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; -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/monitoring/zones.html diff --git a/docs/userguide/Compute/Images.md b/docs/userguide/Compute/Images.md index d09b0b0eb..b7a99025d 100644 --- a/docs/userguide/Compute/Images.md +++ b/docs/userguide/Compute/Images.md @@ -1,65 +1,5 @@ # Compute Images -## Intro +Our docs have moved! Please visit the below link: -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. - -In addition to creating images manually, you can also schedule images of your server automatically. Please consult the [official docs](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/scheduled_images.html) for more information about this extension, including enabling and disabling scheduled images and showing scheduled images. - -With standard servers, the entire disk (OS and data) is captured in the image. With Performance servers, only the system 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. - -## Setup - -You first need to setup a Compute service. For information, please consult the [Compute service](Service.md) documentation. - -## List images - -```php -$images = $service->imageList(); - -foreach ($images as $image) { - -} -``` - -For more information about [iterators](docs/userguide/Iterators.md), please consult the official documentation. - -### Query parameters - -You can also refine the list of images returned by providing specific URL parameters: - -|Field name|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](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ChangesSince.html) for more information.| -|marker|The ID of the last item in the previous list. See the [official docs](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Paginated_Collections-d1e664.html) for more information.| -|limit|Sets the page size. See the [official docs](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Paginated_Collections-d1e664.html) for more information.| -|type|Filters base Rackspace images or any custom server images that you have created. Can either be `BASE` or `SNAPSHOT`.| - -### Example - -You can return more information about each image by setting the `$details` argument to `true`. The second argument can be an array of query parameters: - -```php -use OpenCloud\Compute\Constants\ImageState; - -$list = $service->imageList(true, array( - 'server' => 'fooBar', - 'status' => ImageState::ACTIVE -)); -``` - -## Get an image - -```php -$imageId = '3afe97b2-26dc-49c5-a2cc-a2fc8d80c001'; -$image = $service->image($imageId); -``` - -## Delete an image - -```php -$image->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/compute/images.html diff --git a/docs/userguide/Compute/Keypair.md b/docs/userguide/Compute/Keypair.md index e314db32c..a3e0b4870 100644 --- a/docs/userguide/Compute/Keypair.md +++ b/docs/userguide/Compute/Keypair.md @@ -1,91 +1,5 @@ # Keypairs -## Generate new keypair +Our docs have moved! Please visit the below link: -This operation creates a new keypair under a provided name; the public key value is automatically generated for you. - -```php -$keypair = $service->keypair(); - -$keypair->create(array( - 'name' => 'jamie_keypair_1' -)); - -echo $keypair->getPublicKey(); - -// Save private key to a file so you can use it to SSH into -// your server later. -$sshPrivateKeyFilename = 'jamie_keypair_1_rsa'; -$privateKey = $keypair->getPrivateKey(); -file_put_contents($sshPrivateKeyFilename, $privateKey); -chmod($sshPrivateKeyFilename, 0600); -``` - -## Upload existing keypair - -This operation creates a new keypair under a provided name using a provided public key value. This public key will probably exist on your local filesystem, and so provide easy access to your server when uploaded. - -```php -$keypair = $service->keypair(); - -$key = <<create(array( - 'name' => 'jamie_macbook', - 'publicKey' => $key -)); - -``` - -## List keypairs - -To list all existing keypairs: - -```php -$keys = $service->listKeypairs(); - -foreach ($keys as $key) { - // ... -} -``` - -For more information about iterators, please see [the docs](../Iterators.md). - -## Delete keypairs - -To delete a specific keypair: - -```php -$keypair->delete(); -``` - -## Creating a server with a keypair - -In order to spawn 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: - -```php -use Guzzle\Http\Exception\BadResponseException; -use OpenCloud\Compute\Constants\Network; - -$server = $compute->server(); - -try { - $response = $server->create(array( - 'name' => 'New server', - 'image' => $ubuntuImage, - 'flavor' => $twoGbFlavor, - 'networks' => array( - $compute->network(Network::RAX_PUBLIC), - $compute->network(Network::RAX_PRIVATE) - ), - 'keypair' => 'jamie_macbook' - )); -} catch (BadResponseException $e) { - // error... -} -``` - -So, as you can see, you specify the **name** of an existing keypair that you previously created on the API. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/compute/keypairs.html diff --git a/docs/userguide/Compute/Server.md b/docs/userguide/Compute/Server.md index 8cc0d17e7..dedc1da77 100644 --- a/docs/userguide/Compute/Server.md +++ b/docs/userguide/Compute/Server.md @@ -1,180 +1,5 @@ # Servers -## Intro +Our docs have moved! Please visit the below link: -A server is a virtual machine instance in the Cloud Servers environment. - -## Setup - -Server objects are instantiated from the Compute service. For more details, see the [Service](Service.md) docs. - -## Get server - -The easiest way to retrieve a specific server is by its unique ID: - -```php -$serverId = 'ef08aa7a-b5e4-4bb8-86df-5ac56230f841'; -$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. - -```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 - -There are a few parameter requirements when creating a server using an image: - -* **name** - needs to be a string; -- **flavor** - a `OpenCloud\Compute\Resource\Flavor` object, that is populated with the values of a real API flavor; -* **image** - a `OpenCloud\Compute\Resource\Image` object, that is populated with the values of a real API image; - -Firstly we need to find our flavor and image using their UUIDs. For more information about these concepts, including how to find flavor/image UUIDs, please consult §§ 3-4 in the [Getting Started guide](https://github.com/rackspace/php-opencloud/blob/master/docs/getting-started.md#3-select-your-server-image). - -```php -$ubuntuImage = $compute->image('868a0966-0553-42fe-b8b3-5cadc0e0b3c5'); -$twoGbFlavor = $compute->flavor('4'); -``` - -Now we're ready to create our instance: - -```php -use OpenCloud\Compute\Constants\Network; - -$server = $compute->server(); - -try { - $response = $server->create(array( - 'name' => 'My lovely server', - 'image' => $ubuntuImage, - 'flavor' => $twoGbFlavor - )); -} catch (\Guzzle\Http\Exception\BadResponseException $e) { - - // No! Something failed. Let's find out: - $responseBody = (string) $e->getResponse()->getBody(); - $statusCode = $e->getResponse()->getStatusCode(); - $headers = $e->getResponse()->getHeaderLines(); - - echo sprintf('Status: %s\nBody: %s\nHeaders: %s', $statusCode, $responseBody, implode(', ', $headers); -} -``` - -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 - -There are a few parameter requirements when creating a server using a bootable volume: - -* **name** - needs to be a string; -* **flavor** - a `OpenCloud\Compute\Resource\Flavor` object, that is populated with the values of a real API flavor; -* **volume** - a `OpenCloud\Volume\Resource\Volume` object, that is populated with the values of a real API volume; - -Firstly we need to find our flavor and volume using their IDs. - -```php -$volumeService = $client->volumeService(); -$bootableVolume = $volumeService->volume(''); -$flavor = $compute->flavor(''); -``` - -Now we're ready to create our instance: - -```php -use OpenCloud\Compute\Constants\Network; - -$server = $compute->server(); - -try { - $response = $server->create(array( - 'name' => 'My lovely server', - 'volume' => $bootableVolume, - 'flavor' => $flavor - )); -} catch (\Guzzle\Http\Exception\BadResponseException $e) { - // No! Something failed. Let's find out: - echo $e->getRequest() . PHP_EOL . PHP_EOL; - echo $e->getResponse(); -} -``` - -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 - -Please see the [Keypair](Keypair.md) docs for more information. - -### 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. - -```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](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/Server_Personality-d1e2543.html). - -## Update server - -You can update certain attributes of an existing server instance. These attributes are detailed in the next section. - -```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 - -```php -$server->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/compute/servers.html diff --git a/docs/userguide/Compute/Service.md b/docs/userguide/Compute/Service.md index faff788bb..9bb8e996a 100644 --- a/docs/userguide/Compute/Service.md +++ b/docs/userguide/Compute/Service.md @@ -1,18 +1,5 @@ # Compute service -## Setup +Our docs have moved! Please visit the below link: -To instantiate a Compute service object, you first need to setup a Rackspace/OpenStack client. To do this, or for more -information, please consult the [Clients documentation](../Clients.md). - -```php -$service = $client->computeService(); -``` - -If no arguments are provided to the above method, certain values are set to their default values: - -|Param|Default value| -|---|---| -|`$name`|cloudServersOpenStack| -|`$region`|DFW| -|`$urltype`|publicURL| \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/compute/index.html diff --git a/docs/userguide/DNS/Domains.md b/docs/userguide/DNS/Domains.md index 827020256..53aa45c3b 100644 --- a/docs/userguide/DNS/Domains.md +++ b/docs/userguide/DNS/Domains.md @@ -1,230 +1,5 @@ # Domains -A domain is an entity/container of all DNS-related information containing one or more records. +Our docs have moved! Please visit the below link: -## Setup - -Limit methods will be called on the DNS service, an instance of `OpenCloud\DNS\Service`. Please see the [DNS service](Service.md) documentation for setup instructions. - -## Get domain - -To retrieve a specific domain, you will need the domain's **id**, not its domain name. - -```php -$domain = $service->domain(12345); -``` - -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. - -```php -$domains = $service->domainList(); - -# Return detailed information for each domain -$domains = $service->domainList(true); -``` - -Please consult the [iterator documentation](/docs/userguide/Iterators.md) for more information about iterators. - -### Filter parameters - -You can filter the aforementioned search by using the `name` parameter in a key/value array supplied as a method argument. For example, providing `array('name' => 'hoola.com')` will return hoola.com and similar names such as main.hoola.com and sub.hoola.com. - -```php -$hoolaDomains = $service->domainList(array( - 'name' => 'hoola.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 - -If you know a domain's name, but not its unique identifier, you can do this: - -```php -$domains = $service->domainList(array( - 'name' => 'foo.com' -)); - -foreach ($domains as $domain) { - $id = $domain->id; -} -``` - -## List domain changes - -This call shows all changes to the specified domain since the specified date/time. The since parameter is optional and defaults to midnight of the current day. - -```php -$changes = $domain->changes(); - -# Changes since last week -$since = date('c', strtotime('last week')); -$changes = $domain->changes($since); - -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); - } -} -``` - -## Export domain - -This call provides the BIND (Berkeley Internet Name Domain) 9 formatted contents of 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 (that is, no subdomain information is provided). - -```php -$asyncResponse = $domain->export(); -$body = $asyncResponse->waitFor('COMPLETE'); -echo $body['contents']; -``` - -## Create domain - -A domain is composed of DNS records (e.g. `A`, `CNAME` or `MX` records) and an optional list of sub-domains. You will need to specify these before creating the domain itself: - -```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); - -// add optional C record -$cRecord = $domain->record(array( - 'type' => 'CNAME', - 'name' => 'www.example.com', - 'data' => 'example.com', - 'ttl' => 3600 -)); -$domain->addRecord($cRecord); - -// add optional MX record -$mxRecord = $domain->record(array( - 'type' => 'MX', - 'data' => 'mail.example.com', - 'name' => 'example.com', - 'ttl' => 3600, - 'priority' => 5 -)); -$domain->addRecord($mxRecord); - -// add optional NS records -$nsRecord1 = $domain->record(array( - 'type' => 'NS', - 'data' => 'dns1.stabletransit.com', - 'name' => 'example.com', - 'ttl' => 5400 -)); -$domain->addRecord($nsRecord1); - -$nsRecord2 = $domain->record(array( - 'type' => 'NS', - 'data' => 'dns2.stabletransit.com', - 'name' => 'example.com', - 'ttl' => 5400 -)); -$domain->addRecord($nsRecord2); - -// add optional subdomains -$sub1 = $domain->subdomain(array( - 'emailAddress' => 'foo@example.com', - 'name' => 'dev.example.com', - 'comment' => 'Dev portal' -)); -$domain->addSubdomain($sub1); - -// send to API -$domain->create(array( - 'emailAddress' => 'webmaster@example.com', - 'ttl' => 3600, - 'name' => 'example.com', - 'comment' => 'Optional comment' -)); -``` - -## Clone domain - -This call will duplicate a single existing domain configuration with a new domain name for the specified Cloud account. By default, all records and, optionally, subdomain(s) are duplicated as well. - -The method signature you will need to use is: - -```php -cloneDomain ( string $newDomainName [, bool $subdomains [, bool $comments [, bool $email [, bool $records ]]]] ) -``` - -Name|Data type|Default|Description ----|---|---|--- -`$newDomainName`|`string`|-|The new name for your cloned domain -`$subdomains`|`bool`|`true`|Set to `TRUE` to clone all the subdomains for this domain -`$comments`|`bool`|`true`|Set to `TRUE` to replace occurrences of the reference domain name with the new domain name in comments on the cloned (new) domain. -`$email`|`bool`|`true`|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: - -```php -$asyncResponse = $domain->cloneDomain('new-name.com', true); -``` - -## Import domain - -This call provisions a new DNS domain under the account specified by the BIND 9 formatted file configuration contents defined in the request object. - -You will need to ensure that the BIND 9 formatted file configuration contents are valid by adhering 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: - -```php -$bind9Data = <<import($bind9Data); -``` - -## Modify domain - -This call modifies DNS domain(s) attributes only. 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](/docs/userguide/DNS/Records.md#add-record), [modify records](/docs/userguide/DNS/Records.md#modify-record) or [remove records](/docs/userguide/DNS/Records.md#delete-record) operations respectively. - -```php -$domain->update(array( - 'ttl' => ($domain->ttl + 100), - 'emailAddress' => 'new_dev@foo.com' -)); -``` - -## Remove domain - -```php -$domain->delete(); -``` +http://docs.php-opencloud.com/en/latest/services/dns/domains.html diff --git a/docs/userguide/DNS/Limits.md b/docs/userguide/DNS/Limits.md index 6e7aeb042..68e928594 100644 --- a/docs/userguide/DNS/Limits.md +++ b/docs/userguide/DNS/Limits.md @@ -1,58 +1,5 @@ # Limits -## Setup +Our docs have moved! Please visit the below link: -Limit methods will be called on the DNS service, an instance of `OpenCloud\DNS\Service`. Please see the [DNS service](Service.md) documentation for setup instructions. - -## List all limits - -This call provides a list of all applicable limits for the specified account. - -```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: - -```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: - -```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 - -```php -$limit = $service->limits('DOMAIN_LIMIT'); - -echo $limit->absolute->limits->value; - ->>> 500 -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/dns/limits.html diff --git a/docs/userguide/DNS/Records.md b/docs/userguide/DNS/Records.md index b8f71bda2..fb428c60e 100644 --- a/docs/userguide/DNS/Records.md +++ b/docs/userguide/DNS/Records.md @@ -1,87 +1,5 @@ # Records -A DNS record belongs to a particular domain and is used to specify information about the domain. +Our docs have moved! Please visit the below link: -There are several types of DNS records. 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. - -It is represented by the `OpenCloud\DNS\Resource\Record` class. Records belong to a [Domain](Domains.md). - -## Get record - -In order to retrieve details for a specific DNS record, you will need its **id**: - -```php -$record = $domain->record('NS-1234567'); -``` - -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. - -```php -$records = $domain->recordList(); - -foreach ($records as $record) { - printf("Record name: %s, ID: %s, TTL: %s\n", $record->name, $record->id, $record->ttl); -} -``` - -Please consult the [iterator documentation](docs/userguide/Iterators.md) for more information about iterators. - -### Query parameters - -You can pass in an array of query parameters for greater control over your search: - -Name|Data type|Default|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: - -```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: - -```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 - -```php -$record = $domain->record(123456); -$record->ttl -= 100; -$record->update(); -``` - -## Delete record - -```php -$record->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/dns/records.html diff --git a/docs/userguide/DNS/Reverse-DNS.md b/docs/userguide/DNS/Reverse-DNS.md index a269a0057..84a3a2d15 100644 --- a/docs/userguide/DNS/Reverse-DNS.md +++ b/docs/userguide/DNS/Reverse-DNS.md @@ -1,71 +1,5 @@ # Reverse DNS -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. +Our docs have moved! Please visit the below link: -## 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: - -```php -/** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */ - -$ptr = $service->ptrRecord(array( - 'parent' => $parent -)); -``` - -So, in the above example, a `$parent` 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/Server.md) and [load balancer documentation](../LoadBalancer/USERGUIDE.md) for more detailed usage instructions. - -## List PTR records - -```php -/** @param $parent OpenCloud\DNS\Resource\HasPtrRecordsInterface */ - -$ptrRecords = $service->ptrRecordList($parent); - -foreach ($ptrRecords as $ptrRecord) { - -} -``` - -Please consult the [iterator documentation](docs/userguide/Iterators.md) for more information about iterators. - -## Add PTR record - -```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 - -```php -$ptr->update(array( - 'ttl' => $ptr->ttl * 2 -)); -``` - -## Delete PTR record - -```php -$ptr->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/dns/reverse-dns.html diff --git a/docs/userguide/DNS/Service.md b/docs/userguide/DNS/Service.md index ccabb1242..993648cd9 100644 --- a/docs/userguide/DNS/Service.md +++ b/docs/userguide/DNS/Service.md @@ -1,11 +1,5 @@ # DNS Service -To instantiate a Compute service object, you first need to setup a -Rackspace/OpenStack client. To do this, or for more information, please consult -the [Clients documentation](../Clients.md). +Our docs have moved! Please visit the below link: -You will then need to run: - -```php -$service = $client->dnsService(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/dns/index.html diff --git a/docs/userguide/Database/README.md b/docs/userguide/Database/README.md index 9a5822e5b..2fc712efd 100644 --- a/docs/userguide/Database/README.md +++ b/docs/userguide/Database/README.md @@ -1,116 +1,5 @@ # Databases -A **cloud database** is a MySQL relational database service that allows -customers to programatically provision database instances of varying virtual -resource sizes without the need to maintain and/or update MySQL. +Our docs have moved! Please visit the below link: -## Getting started - -### 1. Instantiate a Rackspace client. - -```php -use OpenCloud\Rackspace; -use OpenCloud\Common\Constants\State; - -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => '', - 'apiKey' => '' -)); -``` - -### 2. Create a database server instance. - -```php -$databaseService = $client->databaseService('cloudDatabases', 'DFW'); - -$twoGbFlavor = $databaseService->flavor(3); - -$dbInstance = $databaseService->instance(); -$dbInstance->name = 'Demo database instance'; -$dbInstance->volume = new stdClass(); -$dbInstance->volume->size = 20; // GB -$dbInstance->flavor = $twoGbFlavor; -$dbInstance->create(); - -$dbInstance->waitFor(State::ACTIVE, null, function ($dbInstance) { - - printf("Database instance build status: %s\n", $dbInstance->status); - -}); -``` - -The example above creates a database server instance with 20GB of disk space and -2GB of memory, then waits for it to become ACTIVE. - -### 3. Create a database on the database server instance. - -```php -$db = $dbInstance->database(); -$db->name = 'demo_db'; - -$db->create(); -``` - -The example above creates a database named `demo_db` on the database server -instance created in the previous step. - -### 4. Create database user and give it access to database. - -```php -$user = $dbInstance->user(); -$user->name = 'demo_user'; -$user->password = 'h@X0r!'; -$user->databases = array('demo_db'); - -$user->create(); -``` - -The example above creates a database user named `demo_user`, sets its password -and gives it access to the `demo_db` database created in the previous step. - -### 5. Optional step: Create a load balancer to allow access to the database from the Internet. - -The database 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. - -```php -$loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW'); - -$loadBalancer = $loadBalancerService->loadBalancer(); - -$loadBalancer->name = 'Load balancer - DB'; -$loadBalancer->addNode($dbInstance->hostname, 3306); -$loadBalancer->port = 3306; -$loadBalancer->protocol = 'MYSQL'; -$loadBalancer->addVirtualIp('PUBLIC'); - -$loadBalancer->create(); - -$loadBalancer->waitFor(State::ACTIVE, null, function ($lb) { - printf("Load balancer build status: %s\n", $lb->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. +http://docs.php-opencloud.com/en/latest/services/database/index.html diff --git a/docs/userguide/Debugging.md b/docs/userguide/Debugging.md index 0fc970c0a..8922df10d 100644 --- a/docs/userguide/Debugging.md +++ b/docs/userguide/Debugging.md @@ -1,89 +1,5 @@ # Debugging -There are two important debugging strategies to use when encountering problems -with HTTP transactions. +Our docs have moved! Please visit the below link: -## 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](https://github.com/guzzle/guzzle/tree/master/src/Guzzle/Http/Exception) -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: - -```php -use Guzzle\Http\Exception\ClientErrorResponseException; - -try { - return $service->getObject('foo.jpg'); -} catch (ClientErrorResponseException $e) { - // Okay, the resource probably does not exist - return false; -} catch (\Exception $e) { - // Some other exception was thrown, probably critical - $this->logException($e); - $this->alertDevs(); -} -``` - -Both `ClientErrorResponseException` and `ServerErrorResponseException` have -two methods that allow you to access the HTTP transaction: - -```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](http://docs.guzzlephp.org/en/latest/plugins/log-plugin.html) -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 - -```bash -php composer.phar require guzzle/plugin-log:~3.8 -``` - -#### Add to your client - -```php -use Guzzle\Plugin\Log\LogPlugin; - -$client->addSubscriber(LogPlugin::getDebugPlugin()); -``` - -The above will add a generic logging subscriber to your client, which will be -notified every time a relevant HTTP event is fired off. +http://docs.php-opencloud.com/en/latest/debugging.html diff --git a/docs/userguide/Identity/Roles.md b/docs/userguide/Identity/Roles.md index e2d49e71d..5d608bf51 100644 --- a/docs/userguide/Identity/Roles.md +++ b/docs/userguide/Identity/Roles.md @@ -1,68 +1,5 @@ # Roles -## Intro +Our docs have moved! Please visit the below link: -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. - -## Setup - -Role objects are instantiated from the Identity service. For more details, see the [Service](Service.md) docs. - -## 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. - -```php -$roles = $service->getRoles(); - -foreach ($roles as $role) { - // ... -} -``` - -For more information about how to use iterators, see the [documentation](../Iterators.md). - -## Get role - -This call lists detailed information (id, name, description) for a specified role. - -```php -$roleId = '123abc'; -$role = $service->getRole($roleId); -``` - -## Add/delete user roles - -To add/remove user roles, you must first instantiate a [user](Users.md) object: - -```php -$roleId = '123abc'; - -// 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: - -```php -$roles = $user->getRoles(); - -foreach ($roles as $role) { - // ... -} -``` - -For more information about how to use iterators, see the [documentation](../Iterators.md). \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/identity/roles.html diff --git a/docs/userguide/Identity/Service.md b/docs/userguide/Identity/Service.md index 6cc80eb5a..4195d4bcb 100644 --- a/docs/userguide/Identity/Service.md +++ b/docs/userguide/Identity/Service.md @@ -1,24 +1,5 @@ # Identity service -## Intro +Our docs have moved! Please visit the below link: -The Identity service is regionless, so you do not need to specify a region when instantiating the service object. Although this was primarily based on Rackspace's implementation of Cloud Identity, it should also work for OpenStack Keystone. - -## A note on object creation - -Normally, when services are created the client handles authenticates automatically. But because Keystone/Identity is fundamental to the authentication process itself, it proves difficult to do this procedure as its normally done. For this reason, you have two options when creating the service object: - -1: Use the client's factory method - -```php -$identity = $client->identityService(); -``` - -2: Authenticate manually - -```php -use OpenCloud\Identity\Service as IdentityService; - -$identity = IdentityService::factory($client); -$identity->getClient()->authenticate(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/identity/index.html diff --git a/docs/userguide/Identity/Tenants.md b/docs/userguide/Identity/Tenants.md index b30cb661d..2129f9604 100644 --- a/docs/userguide/Identity/Tenants.md +++ b/docs/userguide/Identity/Tenants.md @@ -1,21 +1,5 @@ # Tenants -## Intro +Our docs have moved! Please visit the below link: -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. - -## Setup - -Tenant objects are instantiated from the Identity service. For more details, see the [Service](Service.md) docs. - -## List tenants - -```php -$tenants = $service->getTenants(); - -foreach ($tenants as $tenant) { - // ... -} -``` - -For more information about how to use iterators, see the [documentation](../Iterators.md). \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/identity/tenants.html diff --git a/docs/userguide/Identity/Tokens.md b/docs/userguide/Identity/Tokens.md index 04a3ec327..f59835ef4 100644 --- a/docs/userguide/Identity/Tokens.md +++ b/docs/userguide/Identity/Tokens.md @@ -1,84 +1,5 @@ # Tokens -## Intro +Our docs have moved! Please visit the below link: -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. - -## Setup - -Token objects are instantiated from the Identity service. For more details, see the [Service](Service.md) docs. - -## Useful object properties/methods - -Property|Description|Getter|Setter ----|---|---|--- -id|The unique ID of the token|`getId()`|`setId()` -expires|Timestamp of when the token will expire|`getExpires()` or `hasExpired()`|`setExpires()` - -## 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. - -Request body for Rackspace's generate token operation: - -```json -{ - "auth": { - "RAX-KSKEY:apiKeyCredentials": { - "username": "foo", - "apiKey": "aaaaa-bbbbb-ccccc-12345678" - }, - "tenantId": "1100111" - } -} -``` - -Request body for Keystone's generate token operation: - -```json -{ - "auth": { - "passwordCredentials":{ - "username":"demoauthor", - "password":"theUsersPassword" - }, - "tenantId": "12345678" - } -} -``` - -The only real differences you'll notice is the name of the object key (`RAX-KSKEY:apiKeyCredentials`/`passwordCredentials`) and the secret (`apiKey`/`password`). The `tenantId` property in both templates are optional. You can also add `tenantName` too. - -```php -use OpenCloud\Common\Http\Message\Formatter; - -$template = sprintf( - '{"auth": {"RAX-KSKEY:apiKeyCredentials":{"username": "%s", "apiKey": "%s"}}}', - 'my_username', - 'my_api_key' -); - -$response = $service->generateToken($template); - -$body = Formatter::decode($response); - -// service catalog -$catalog = $body->access->serviceCatalog; - -// token -$token = $body->access->token; - -// user -$user = $body->access->user; -``` - -As you will notice, these variables will be stdClass objects - for fully fledged functionality, let the client authenticate by itself because it ends up stocking the necessary models for you. - -To see the response body structure, consult the [official docs](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/POST_authenticate_v2.0_tokens_Token_Calls.html). - -## Revoke token (destroy session) - -```php -$tokenId = '1234567'; -$service->revokeToken($tokenId); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/identity/tokens.html diff --git a/docs/userguide/Identity/Users.md b/docs/userguide/Identity/Users.md index 286aa6007..a69fbb7dc 100644 --- a/docs/userguide/Identity/Users.md +++ b/docs/userguide/Identity/Users.md @@ -1,128 +1,5 @@ # Users -## Intro +Our docs have moved! Please visit the below link: -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. - -## Setup - -User objects are instantiated from the Identity service. For more details, see the [Service](Service.md) docs. - -## Useful 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 - -```php -$users = $service->getUsers(); - -foreach ($users as $user) { - // ... -} -``` - -For more information about how to use iterators, see the [documentation](../Iterators.md). - -## Get user - -There are various ways to get a specific user: by name, ID and email address. - -```php -use OpenCloud\Identity\Constants\User as UserConst; - -// Get user by name -$user1 = $service->getUser('jamie'); - -// Get user by ID -$user2 = $service->getUser(123456, UserConst::MODE_ID); - -// Get user by email -$user3 = $service->getUser('jamie.hannaford@rackspace.com', UserConst::MODE_EMAIL); -``` - -## Create user - -There are a few things to remember 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. - -* Within an account, a maximum of 100 account users can be added. - -* 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. - -```php -use Guzzle\Http\Exception\ClientErrorResponseException; - -try { - // execute operation - $user = $service->createUser(array( - 'username' => 'newUser', - 'email' => 'foo@bar.com' - )); -} catch (ClientErrorResponseException $e) { - // catch 4xx HTTP errors - echo $e->getResponse()->toString(); -} - -// show generated password -echo $user->getPassword(); -``` - -## Update user - -When updating a user, specify which attribute/property you want to update: - -```php -$user->update(array( - 'email' => 'new_email@bar.com' -)); -``` - -### Updating a user password - -Updating a user password requires calling a distinct method: -```php -$user->updatePassword('password123'); -``` - -## Delete user - -```php -$user->delete(); -``` - -## List credentials - -This operation allows you to see your non-password credential types for all authentication methods available. - -```php -$creds = $user->getOtherCredentials(); -``` - -## Get user API key - -```php -echo $user->getApiKey(); -``` - -## Reset user API key - -When resetting an API key, a new one will be automatically generated for you: - -```php -$user->resetApiKey(); -echo $user->getApiKey(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/identity/users.html diff --git a/docs/userguide/Image/Images.md b/docs/userguide/Image/Images.md index c0efee9a1..95824b2a5 100644 --- a/docs/userguide/Image/Images.md +++ b/docs/userguide/Image/Images.md @@ -1,97 +1,5 @@ # Images -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). +Our docs have moved! Please visit the below link: -An Image is represented by the `OpenCloud\Image\Resource\Image` class. - -## Setup - -You instantiate an Image object from its `OpenCloud\Image\Service` class, which -is available from the OpenStack/Rackspace client: - -```php -$service = $client->imageService('cloudImages', 'IAD'); -``` - -View the guides for more information about [clients](../Clients.md) or -[services](../Services.md). - -## List images - -```php -$images = $service->listImages(); - -foreach ($images as $image) { - /** @param $image OpenCloud\Image\Resource\Image */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](../Iterators.md). - -## Get image details - -```php -/** @param $image OpenCloud\Image\Resource\Image */ -$image = $service->getImage(''); -``` - -### A note on schema classes - -Both `OpenCloud\Image\Resource\Image` and `OpenCloud\Image\Resource\Member` -extend the `AbstractSchemaResource` abstract 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 way different than -conventional getter/setter methods, and even class properties. For this reason, -they implement SPL's native -[`ArrayAccess`](http://www.php.net/manual/en/class.arrayaccess.php) -interface which allows you to access their state as a conventional array: - -```php -$image = $service->getImage(''); - -$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](Schemas.md). - -Although you should be able to add new and replace existing properties, always -prepare yourself for a situation where it might be forbidden: - -```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 - -```php -$image->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/image/images.html diff --git a/docs/userguide/Image/Schemas.md b/docs/userguide/Image/Schemas.md index b634b5705..5efce8c59 100644 --- a/docs/userguide/Image/Schemas.md +++ b/docs/userguide/Image/Schemas.md @@ -1,159 +1,5 @@ # JSON schemas -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. +Our docs have moved! Please visit the below link: -A JSON Schema is represented by the `OpenCloud\Image\Resource\Schema\Schema` -class. - -## 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: - -```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: - -```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: - -```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. - -```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](http://docs.guzzlephp.org/en/latest/webservice-client/guzzle-service-descriptions.html), -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](http://tools.ietf.org/html/rfc6902). - -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: - -``` -[ - {"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](http://tools.ietf.org/html/rfc6901). - -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](http://docs.rackspace.com/images/api/v2/ci-devguide/content/patch-method.html) -for additional information. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/image/schemas.html diff --git a/docs/userguide/Image/Sharing.md b/docs/userguide/Image/Sharing.md index e83470073..3fbe0c1d1 100644 --- a/docs/userguide/Image/Sharing.md +++ b/docs/userguide/Image/Sharing.md @@ -1,110 +1,5 @@ # Sharing images -Images can be created and deleted by image producers, updated by image -consumers, and listed by both image producers and image consumers: +Our docs have moved! Please visit the below link: -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](Images.md), so you will -need to set this up first. - -## List image members - -This operation is available for both producers and consumers. - -```php -$members = $image->listMembers(); - -foreach ($members as $member) { - /** @param $member OpenCloud\Image\Resource\Member */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](../Iterators.md). - -## Create image member - -This operation is only available for producers. - -```php -$tenantId = 12345; - -/** @param $response Guzzle\Http\Message\Response */ -$response = $image->createMember($tenantId); -``` - -## Delete image member - -This operation is only available for producers. - -```php -$tenantId = 12345; - -/** @param $member OpenCloud\Image\Resource\Member */ -$member = $image->getMember($tenantId); - -$member->delete(); -``` - -## Update image member status - -This operation is only available for consumers. - -```php -use OpenCloud\Images\Enum\MemberStatus; - -$tenantId = 12345; - -/** @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. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/image/sharing.html diff --git a/docs/userguide/Image/Tags.md b/docs/userguide/Image/Tags.md index 019e336e5..2686391f4 100644 --- a/docs/userguide/Image/Tags.md +++ b/docs/userguide/Image/Tags.md @@ -1,23 +1,5 @@ # Image tags -An image tag is a string of characters used to identify a specific image or -images. +Our docs have moved! Please visit the below link: -## Setup - -All member operations are executed against an [Image](Images.md), so you will -need to set this up first. - -## Add image tag - -```php -/** @param $response Guzzle\Http\Message\Response */ -$response = $image->addTag('jamie_dev'); -``` - -## Delete image tag - -```php -/** @param $response Guzzle\Http\Message\Response */ -$response = $image->deleteTag('jamie_dev'); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/image/tags.html diff --git a/docs/userguide/Iterators.md b/docs/userguide/Iterators.md index 553507937..4c8c794ce 100644 --- a/docs/userguide/Iterators.md +++ b/docs/userguide/Iterators.md @@ -1,118 +1,5 @@ # Iterators -## Intro +Our docs have moved! Please visit the below link: -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](http://php.net/manual/en/class.iterator.php), [ArrayAccess](http://www.php.net/manual/en/class.arrayaccess.php) and [Countable](http://php.net/manual/en/class.countable.php) 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 - -```php -$iterator = $computeService->flavorList(); -``` - -There are two ways to traverse an iterator. The first is the longer, more traditional way: - -```php -while ($iterator->valid()) { - $flavor = $iterator->current(); - - // do stuff.. - echo $flavor->id; - - $iterator->next(); -} -``` - -There is also a shorter and more intuitive version: - -```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: - -```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 - -```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()` +http://docs.php-opencloud.com/en/latest/iterators.html diff --git a/docs/userguide/LoadBalancer/README.md b/docs/userguide/LoadBalancer/README.md index 03364f103..3531e3dc8 100644 --- a/docs/userguide/LoadBalancer/README.md +++ b/docs/userguide/LoadBalancer/README.md @@ -1,80 +1,5 @@ # Load Balancers -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. +Our docs have moved! Please visit the below link: -## Getting started - -### 1. Instantiate a Rackspace client. - -```php - -use OpenCloud\Rackspace; - -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => '', - 'apiKey' => '' -)); -``` - -### 2. Retrieve the server instances you want to add as nodes of the load balancer. - -```php -$computeService = $client->computeService('cloudServersOpenStack', 'DFW'); - -$serverOne = $computeService->server('e836fc4e-056d-4447-a80e-fefcaa640216'); -$serverTwo = $computeService->server('5399cd36-a23f-41a6-bdf7-20902aec0e74'); -``` - -The example above uses two server instances that have already been created. It -retrieves the server instances using their IDs. See also: [creating server instances](). - -### 3. Obtain a Load Balancer service object from the client. - -This object will be used to first define the load balancer nodes and later create the load balancer itself. - -```php -$loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW'); -``` - -### 4. Define a load balancer node for each server. - -```php -$loadBalancer = $loadBalancerService->loadBalancer(); - -$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'; -``` - -In the example above, each node runs a service that listens on port 8080. Further, -each node will start out as `ENABLED`, which means it will be ready to receive -network traffic from the load balancer as soon as it is created. - -### 5. Create the load balancer with the two nodes. - -```php -$loadBalancer->addVirtualIp('PUBLIC'); -$loadBalancer->create(array( - 'name' => 'My smart load balancer', - 'port' => 80, - 'protocol' => 'HTTP', - 'nodes' => array($serverOneNode, $serverTwoNode) -)); -``` - -In the example above, the load balancer will have a virtual IP address accessible -from the public Internet. Also notice that the port the load balancer listens -on (80) does not need to match the ports of its nodes (8080). - -## Next steps - -Once you have created a load balancer, there is a lot you can do with it. See -the [complete user guide for load balancers](USERGUIDE.md). \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/load-balancer/index.html diff --git a/docs/userguide/LoadBalancer/USERGUIDE.md b/docs/userguide/LoadBalancer/USERGUIDE.md index 8efa98ffe..d29925da0 100644 --- a/docs/userguide/LoadBalancer/USERGUIDE.md +++ b/docs/userguide/LoadBalancer/USERGUIDE.md @@ -1,626 +1,5 @@ # The Complete User Guide to Load Balancers -## Prerequisites +Our docs have moved! Please visit the below link: -### Client -To use the load balancers service, you must first instantiate a `Rackspace` -client object. - -```php -use OpenCloud\Rackspace; - -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => '', - 'apiKey' => '' -)); -``` - -### Load Balancer Service -All operations on load balancers are done via a load balancer service object. - -```php -$loadBalancerService = $client->loadBalancerService('cloudLoadBalancers', 'DFW'); -``` - -### Cloud Servers -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. - -## Load Balancers - -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. - -### Create Load Balancer - -```php -$loadBalancer = $loadBalancerService->loadBalancer(); - -$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'; - -$loadBalancer->addVirtualIp('PUBLIC'); -$loadBalancer->create(array( - 'name' => 'My smart load balancer', - 'port' => 80, - 'protocol' => 'HTTP', - 'nodes' => array($serverOneNode, $serverTwoNode) -)); -``` - -### List Load Balancer Details - -You can retrieve a single load balancer's details by using its ID. - -```php -$loadBalancer = $loadBalancerService->loadBalancer('254889'); - -/** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ -``` - -### List Load Balancers - -You can retrieve a list of all your load balancers. An instance of `OpenCloud\Common\Collection\PaginatedIterator` -is returned. - -```php -$loadBalancers = $loadBalancerService->loadBalancerList(); -foreach ($loadBalancers as $loadBalancer) { - /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ -} -``` - -### Update Load Balancer Attributes - -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). - -#### Updating a single attribute of a load balancer -```php -$loadBalancer->update(array( - 'name' => 'New name' -)); -``` - -#### Updating multiple attributes of a load balancer -```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. - -```php -$loadBalancer->delete(); -``` - -## Nodes - -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. - -### List Nodes - -You can list the nodes attached to a load balancer. An instance of `OpenCloud\Common\Collection\PaginatedIterator` -is returned. - -```php -$nodes = $loadBalancer->listNodes(); -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. - -```php -$address = $serverThree->addresses->private[0]->addr; -$loadBalancer->addNode($address, 8080); -$loadBalancer->addNodes(); -``` - -The `addNode` method accepts three more optional parameters, in addition to the two shown above: - -| Position | Description | Data type | Required? | Default value | -| ----------- | --------------- | --------------| -------------- | ----------------- | -| 1 | IP address of node | String | Yes | - | -| 2 | Port used by node's service | Integer | Yes | - | -| 3 | Starting condition of node:
      • `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.
      | String | No | `ENABLED` | -| 4 | Type of node to add:
      • `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.
      | String | No | `PRIMARY` | -| 5 | 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. | Integer | No | 1 | - -### 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. - -#### Modifying a single attribute of a node -```php -use OpenCloud\LoadBalancer\Enum\NodeCondition; - -$node->update(array( - 'condition' => NodeCondition::DISABLED -)); -``` - -#### Modifying multiple attributes of a node -```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. - -#### Given an `OpenCloud\LoadBalancer\Resource\Node` instance -```php -$node->delete(); -``` - -#### Given an `OpenCloud\LoadBalancer\Resource\LoadBalancer` instance and a node ID -```php -$loadBalancer->removeNode(490639); -``` - -The `removeNode` method, as shown above, accepts the following arguments: - -|Position| Description | Data type | Required? | Default value | -|----------- | --------------- | -------------- |-------------- | ----------------- | -| 1 | ID of node | Integer | Yes | - | - -### View Node Service Events -You can view events associated with the activity between a node and a load balancer. An instance of `OpenCloud\Common\Collection\PaginatedIterator` is returned. - -```php -$nodeEvents = $loadBalancer->nodeEventList(); -foreach ($nodeEvents as $nodeEvent) { - /** @var $nodeEvent OpenCloud\LoadBalancer\Resource\NodeEvent **/ -} -``` - -## Virtual IPs - -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. - -### List Virtual IPs - -You can list the VIPs associated with a load balancer. An instance of `OpenCloud\Common\Collection\PaginatedIterator` is returned. - -```php -$vips = $loadBalancer->virtualIpList(); -foreach ($vips as $vip) { - /** @var $vip of OpenCloud\LoadBalancer\Resource\VirtualIp **/ -} -``` - -### Add Virtual IPv6 - -You can add additional IPv6 VIPs to a load balancer. - -```php -use OpenCloud\LoadBalancer\Enum\IpType; - -$loadBalancer->addVirtualIp(IpType::PUBLIC, 6); -``` - -The `addVirtualIp` method, as shown above, accepts the following arguments: - -| Position | Description | Data type | Required? | Default value | -| ----------- | --------------- | -------------- |-------------- | ----------------- | -| 1 | Type of VIP:
      • `PUBLIC` – An IP address that is routable on the public Internet.
      • `SERVICENET` – An IP address that is routable only on ServiceNet.
      | String | No | `PUBLIC` | -| 2 | IP version: Must be `6` | Integer | Yes | - | - - -### Remove Virtual IPs - -You can remove a VIP from a load balancer. - -```php -$vip->remove(); -``` - -Please note that 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. - -## Algorithms - -Load balancers use an **algorithm** to determine how incoming traffic is distributed amongst the back-end nodes. - -### List Load Balancing Algorithms - -You can list all supported load balancing algorithms using a load balancer service object. An instance of `OpenCloud\Common\Collection\PaginatedIterator` is returned. - -```php -$algorithms = $loadBalancerService->algorithmList(); -foreach ($algorithms as $algorithm) { - /** @var $algorithm OpenCloud\LoadBalancer\Resource\Algorithm **/ -} -``` - -## 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. - -### List Load Balancing Protocols - -You can list all supported network protocols using a load balancer service object. An instance of `OpenCloud\Common\Collection\PaginatedIterator` is returned. - -```php -$protocols = $loadBalancerService->protocolList(); -foreach ($protocols as $protocol) { - /** @var $protocol OpenCloud\LoadBalancer\Resource\Protocol **/ -} -``` - -## 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. - -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. | - -### List Session Persistence Configuration - -```php -$sessionPersistence = $loadBalancer->sessionPersistence(); -$sessionPersistenceType = $sessionPersistence->persistenceType; - -/** @var $sessionPersistenceType null | 'HTTP_COOKIE' | 'SOURCE_IP' **/ -``` - -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 - -```php -$sessionPersistence = $loadBalancer->sessionPersistence(); -$sessionPersistence->update(array( - 'persistenceType' => 'HTTP_COOKIE' -)); -``` - -### Disable Session Persistence - -```php -$sessionPersistence = $loadBalancer->sessionPersistence(); -$sessionPersistence->delete(); -``` - -## 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. - -### Check Logging Configuration - -```php -/** @var $connectionLogging bool **/ - -$connectionLogging = $loadBalancer->hasConnectionLogging(); -``` -In the example above: - -* If connection logging is enabled, the value of `$connectionLogging` is `true`. -* If connection logging is disabled, the value of `$connectionLogging` is `false`. - -### Enable Connection Logging - -```php -$loadBalancer->enableConnectionLogging(true); -``` - -### Disable Connection Logging - -```php -$loadBalancer->enableConnectionLogging(false); -``` - -## Error Page - -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 - -```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 - -```php -$errorPage = $loadBalancer->errorPage(); -$errorPage->update(array( - 'content' => '' -)); -``` - -### Delete Custom Error Page - -```php -$errorPage = $loadBalancer->errorPage(); -$errorPage->delete(); -``` - -## Allowed Domains - -**Allowed domains** are a restricted set of domain names that are allowed to add load balancer nodes. - -### List Allowed Domains - -You can list all allowed domains using a load balancer service object. An instance of `OpenCloud\Common\Collection\PaginatedIterator` -is returned. - -```php -$allowedDomains = $loadBalancerService->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`. - -### View Access List - -You can view a load balancer's access list. An instance of `OpenCloud\Common\Collection\PaginatedIterator` -is returned. - -```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: - -```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. - -```php -$networkItem->delete(); -``` - -## 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. - -### Check Content Caching Configuration - -```php -/** @var $contentCaching bool **/ - -$contentCaching = $loadBalancer->hasContentCaching(); -``` -In the example above: - -* If content caching is enabled, the value of `$contentCaching` is `true`. -* If content caching is disabled, the value of `$contentCaching` is `false`. - -### Enable Content Caching - -```php -$loadBalancer->enableContentCaching(true); -``` - -### Disable Content Caching - -```php -$loadBalancer->enableContentCaching(false); -``` - -## 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. - -### View current SSL termination config - -```php -/** @var $sslConfig OpenCloud\LoadBalancer\Resource\SSLTermination **/ - -$sslConfig = $loadBalancer->SSLTermination(); -``` - -### Update SSL termination config - -```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](http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/SSLTermination-d1e2479.html) - -### Delete SSL termination config - -```php -$sslConfig->delete(); -``` - -## 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. - -### List metadata - -```php -$metadataList = $loadBalancer->metadataList(); - -foreach ($metadataList as $metadataItem) { - printf("Key: %s, Value: %s", $metadataItem->key, $metadataItem->value); -} -``` - -Please consult the [iterator documentation](docs/userguide/Iterators.md) for more information about iterators. - -### Add metadata - -```php -$metadataItem = $loadBalancer->metadata(); -$metadataItem->create(array( - 'key' => 'foo', - 'value' => 'bar' -)); -``` - -### Modify metadata - -```php -$metadataItem = $loadBalancer->metadata('foo'); -$metadataItem->update(array( - 'value' => 'baz' -)); -``` - -### Remove metadata - -```php -$metadataItem->delete(); -``` - -## Monitors - -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. - -```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](http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Monitor_Connections-d1e3536.html) - -### Update or delete - -```php -// Update -$healthMonitor->update(array( - 'delay' => 120, - 'timeout' => 60, - 'type' => 'CONNECT' - 'attemptsBeforeDeactivation' => 3 -)); - -// Delete -$healthMonitor->delete(); -``` - -## Statistics - -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. - -```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. - -```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; -} -``` +http://docs.php-opencloud.com/en/latest/services/load-balancer/index.html diff --git a/docs/userguide/Networking/README.md b/docs/userguide/Networking/README.md new file mode 100644 index 000000000..9597c33a1 --- /dev/null +++ b/docs/userguide/Networking/README.md @@ -0,0 +1,5 @@ +# Networking + +Our docs have moved! Please visit the below link: + +http://docs.php-opencloud.com/en/latest/services/networking/index.html diff --git a/docs/userguide/Networking/USERGUIDE.md b/docs/userguide/Networking/USERGUIDE.md new file mode 100644 index 000000000..d3185c6f2 --- /dev/null +++ b/docs/userguide/Networking/USERGUIDE.md @@ -0,0 +1,5 @@ +# Complete User Guide for the Networking Service + +Our docs have moved! Please visit the below link: + +http://docs.php-opencloud.com/en/latest/services/networking/index.html diff --git a/docs/userguide/ObjectStore/Access.md b/docs/userguide/ObjectStore/Access.md old mode 100755 new mode 100644 index 0b15a2d19..53466362e --- a/docs/userguide/ObjectStore/Access.md +++ b/docs/userguide/ObjectStore/Access.md @@ -1,66 +1,5 @@ ## Setup -```php -use OpenCloud\Rackspace; +Our docs have moved! Please visit the below link: -$client = new Rackspace(RACKSPACE_US, array( - -)); - -$service = $client->objectStoreService('cloudFiles', 'IAD'); # Second argument is the region you want -``` - -## 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: - -```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: - -```php -$object->getTemporaryUrl(60, 'GET'); -``` - -To allow PUT access for 1 hour: - -```php -$object->getTemporaryUrl(360, 'PUT'); -``` - -## Hosting websites on CloudFiles - -To host a static (i.e. HTML) website on CloudFiles, you must follow these steps: - -1. CDN-enable a container -2. Upload all HTML content. You can use nested directory structures. -3. Tell CloudFiles what to use for your default index page like this: - -```php -$container->setStaticIndexPage('index.html'); -``` - -4. (Optional) Tell CloudFiles which error page to use by default: - -```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. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/object-store/access.html diff --git a/docs/userguide/ObjectStore/Account.md b/docs/userguide/ObjectStore/Account.md old mode 100755 new mode 100644 index edd26c2c1..286bb9ca1 --- a/docs/userguide/ObjectStore/Account.md +++ b/docs/userguide/ObjectStore/Account.md @@ -1,28 +1,5 @@ ## Setup -```php -use OpenCloud\Rackspace; +Our docs have moved! Please visit the below link: -$client = new Rackspace(RACKSPACE_US, array( - -)); - -$service = $client->objectStoreService('cloudFiles'); -``` - -## View 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): - -```php -$account = $service->getAccount(); - -// Either return the full Metadata object -$details = $account->getDetails(); - -// or individual values -$account->getContainerCount(); -$account->getObjectCount(); -$account->getBytesUsed(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/object-store/account.html diff --git a/docs/userguide/ObjectStore/CDN/Container.md b/docs/userguide/ObjectStore/CDN/Container.md old mode 100755 new mode 100644 index 3d06216fc..c854b31e5 --- a/docs/userguide/ObjectStore/CDN/Container.md +++ b/docs/userguide/ObjectStore/CDN/Container.md @@ -1,69 +1,5 @@ ## Setup -```php -use OpenCloud\Rackspace; +Our docs have moved! Please visit the below link: -$client = new Rackspace(RACKSPACE_US, array( - -)); - -$service = $client->objectStoreService('cloudFiles'); -``` - -To access the CDN functionality of a particular container: - -```php -$container = $service->getContainer('foo_bar'); - -$cdn = $container->getCdn(); -``` - -## List CDN-enabled container - -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. - -## CDN-enable and -disable 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. - -```php -$container->enableCdn(); -$container->disableCdn(); -``` - -## Serving containers through SSL - -```php -$cdn->getCdnSslUri(); -``` - -## Streaming CDN-enabled containers - -```php -$cdn->getCdnStreamingUri(); -``` - -## iOS streaming - -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. - -```php -$cdn->getIosStreamingUri(); -``` - -## CDN logging - -To enable and disable logging for your CDN: - -```php -$cdn->enableCdnLogging(); -$cdn->disableCdnLogging(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/object-store/cdn.html diff --git a/docs/userguide/ObjectStore/CDN/Object.md b/docs/userguide/ObjectStore/CDN/Object.md old mode 100755 new mode 100644 index 79e3d4cdc..c854b31e5 --- a/docs/userguide/ObjectStore/CDN/Object.md +++ b/docs/userguide/ObjectStore/CDN/Object.md @@ -1,20 +1,5 @@ ## Setup -You will need to instantiate the container object and access its CDN functionality as -[documented here](https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/ObjectStore/CDN/Container.md). +Our docs have moved! Please visit the below link: -## Purge CDN-enabled objects - -To remove a CDN object from public access: - -```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: - -```php -$object->purge('jamie.hannaford@rackspace.com'); -$object->purge('hello@example.com,hallo@example.com'); -``` +http://docs.php-opencloud.com/en/latest/services/object-store/cdn.html diff --git a/docs/userguide/ObjectStore/README.md b/docs/userguide/ObjectStore/README.md index 7da7fd24a..c66bbabdb 100644 --- a/docs/userguide/ObjectStore/README.md +++ b/docs/userguide/ObjectStore/README.md @@ -1,63 +1,5 @@ # Object Store -**Object Store** is an object-based storage system that stores content and metadata as objects in a cloud. +Our docs have moved! Please visit the below link: -Specifically, a cloud is made up of one or more regions. Each region can have several **containers**, created by a user. Each container can container several **objects** (sometimes referred to as files), uploaded by the user. - -## Getting started - -### 1. Instantiate an OpenStack or Rackspace client. - -Choose one of the following two options: - -* If you are working with a vanilla OpenStack cloud, instantiate an `OpenCloud\OpenStack` client as shown below. - - ```php - use OpenCloud\OpenStack; - - $client = new OpenStack('', array( - 'username' => '', - 'password' => '' - )); - ``` - -* If you are working with the Rackspace cloud, instantiate a `OpenCloud\Rackspace` client as shown below. - - ```php - use OpenCloud\Rackspace; - - $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => '', - 'apiKey' => '' - )); - ``` - -### 2. Obtain an Object Store service object from the client. -```php -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); -``` - -In the example above, you are connecting to the ``DFW`` region of the cloud. Any containers and objects created with this `$objectStoreService` instance will be stored in that cloud region. - -### 3. Create a container for your objects (also referred to as files). - -```php -$container = $objectStoreService->createContainer('logos'); -``` - -### 4. Upload an object to the container. - -```php -$localFileName = '/path/to/local/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; - -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/quickstart.php) ] - -## Next steps - -There is a lot more you can do with containers and objects. See -the [complete user guide to the Object Store service](USERGUIDE.md). +http://docs.php-opencloud.com/en/latest/services/object-store/index.html diff --git a/docs/userguide/ObjectStore/Storage/Container.md b/docs/userguide/ObjectStore/Storage/Container.md old mode 100755 new mode 100644 index d30cd0796..ab705fa15 --- a/docs/userguide/ObjectStore/Storage/Container.md +++ b/docs/userguide/ObjectStore/Storage/Container.md @@ -1,181 +1,5 @@ ## Setup -```php -use OpenCloud\Rackspace; +Our docs have moved! Please visit the below link: -// Create a client object to communicate with various Rackspace Cloud services. -$client = new Rackspace(RACKSPACE_US, array( - 'username' => 'Replace this with your Rackspace Cloud user name', - 'apiKey' => 'Replace this with your Rackspace Cloud API key' -)); - -// Create a service object to use the object store service. The sample code -// creates the object store in the 'DFW' region. -$service = $client->objectStoreService('cloudFiles', 'DFW'); -``` - -## Create container - -To create a new container, you just need to define its name: - -```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. - - -## List containers - -### Return a list of containers - -```php -$containerList = $service->listContainers(); - -while ($container = $containerList->next()) { - // Do stuff; some examples below - 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. See 1.3 for ways to limit and navigate this list. - -### Return a formatted list of containers - -Currently, the SDK only supports JSON-formatted responses. - -### Controlling a large list of containers - -You may limit and control this list of results 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: - -```php -$someContainers = $service->listContainers(array( - 'marker' => 'container_55', - 'end_marker' => 'container_2001' -)); -``` - -Or to return a limited set: - -```php -$someContainers = $service->listContainers(array('limit' => 560)); -``` - -## Get container - -To retrieve a certain container, either to access its object or metadata: - -```php -$container = $service->getContainer('container_name'); - -echo $container->getObjectCount(); -echo $container->getBytesUsed(); -``` - -## Delete container - -Deleting a container is easy: -```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: - -```php -$container->delete(TRUE); -``` - -You can also do it manually: - -```php -$container->deleteAllObjects(); -$container->delete(); -``` - -## Create or update container metadata - -```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: - -```php -$metadata = $container->appendToMetadata(array( - 'Publisher' => 'Hogarth' -)); -``` - -If you only want to set the metadata to the local object, and not immediately retain these values on the API, you can -use a standard setter method - which can contribute to eventual actions like an update: - -```php -$container->setMetadata(array('Foo' => 'Bar')); -``` - -## 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: - -```php -use OpenCloud\Common\Constants\Size; - -$container->setCountQuota(1000); -$container->setBytesQuota(2.5 * Size::GB); -``` - -And to retrieve them: - -```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). - -```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: - -```php -$container->uploadDirectory('/home/Jamie/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 \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/object-store/containers.html diff --git a/docs/userguide/ObjectStore/Storage/Migrating.md b/docs/userguide/ObjectStore/Storage/Migrating.md index d92528cbf..550268f60 100644 --- a/docs/userguide/ObjectStore/Storage/Migrating.md +++ b/docs/userguide/ObjectStore/Storage/Migrating.md @@ -1,83 +1,5 @@ # Migrating containers (across regions) -## Introduction +Our docs have moved! Please visit the below link: -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: - -```bash -php composer.phar install --dev -``` - -* Depending on the size and number of transfer items, you will need to raise PHP's memory limit: - -```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: - -```php -use Guzzle\Plugin\Backoff\BackoffPlugin; - -$client->addSubscriber(BackoffPlugin::getExponentialBackoff(10, array(500, 503, 408))); -``` - -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: - -```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: - -```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: - -```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 \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/object-store/migrating-containers.html diff --git a/docs/userguide/ObjectStore/Storage/Object.md b/docs/userguide/ObjectStore/Storage/Object.md old mode 100755 new mode 100644 index b5f324c9f..2ecca81e1 --- a/docs/userguide/ObjectStore/Storage/Object.md +++ b/docs/userguide/ObjectStore/Storage/Object.md @@ -1,272 +1,5 @@ ## Setup -Conceptually, a container contains objects (also known as files). In order to work with -objects, you will need to instantiate a container object first as [documented here](https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/ObjectStore/Storage/Container.md). +Our docs have moved! Please visit the below link: -## Note on object properties - -Please be aware that you cannot directly access the properties of DataObject anymore, you __must__ use appropriate getter/ -setter methods: - -|Property|Method| -|--------|------| -|Parent container|`getContainer`| -|Name|`getName`| -|Body of file|`getContent`| -|Size of file|`getContentLength`| -|Type of file|`getContentType`| -|ETag checksum|`getEtag`| -|Last modified date|`getLastModified`| - -## Create an object - -There are three ways to upload a new file, each of which has different business needs. - -__N.B__: Unlike previous versions, you do not need to manually specify your object's content type. The API will do this -for you. - -### To upload a single/basic file: - -```php -use OpenCloud\ObjectStore\Resource\DataObject; - -$data = fopen('/path/to/sample.mp3', 'r+'); - -// alternatively, you can pass in a string as the file contents `$data` argument (instead of a resource) - -$meta = array( - 'Author' => 'Camera Obscura', - 'Origin' => 'Glasgow' -); - -$metaHeaders = DataObject::stockHeaders($meta); -$customHeaders = array(); -$allHeaders = $metaHeaders + $customHeaders; - -$container->uploadObject('sample.mp3', $data, $allHeaders); -``` - -### To upload multiple small-to-mid sized files: - -```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. - -### To upload large files - -For files over 5GB, you will need to use the `OpenCloud\ObjectStore\Upload\TransferBuilder` factory to build your transfer, -upon which you can execute your upload functionality. For your convenience, the Container resource object contains a -simple method to do this heavy lifting for you: - -```php -$transfer = $container->setupObjectTransfer(array( - 'name' => 'video.mov', - 'path' => '/home/jamie/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 manifest 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. - -## List objects in a container - -To return a list of objects: - -```php -$files = $container->objectList(); -while ($file = $files->next()) { - // ... do something -} -``` - -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](http://docs.openstack.org/api/openstack-object-storage/1.0/content/list-objects.html). - -```php -$container->objectList(array('prefix' => 'logFile_')); -``` - -## Get object - -To retrieve a specific file from Cloud Files: - -```php -$file = $container->getObject('summer_vacation.mp4'); -``` - -### Conditional requests - -You can also perform conditional requests according to [RFC 2616 specification](http://www.ietf.org/rfc/rfc2616.txt) -(§§ 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 - -```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): - -``` -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: - -```php -$snippet = $container->getObject('output.log', array('range' => 'bytes=-20')); -``` - -## Update an existing object - -Updating content is easy: - -```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 copy a file to another location, you need to specify a string-based destination path: - -```php -$object->copy('/container_2/new_object_name'); -``` - -## Delete object - -```php -$object->delete(); -``` - -## Get object metadata -You can fetch just the object metadata without fetching the full content: -```php -$container->getPartialObject('summer_vacation.mp4'); -``` - -In order to access the metadata on a partial or complete object, use: - -```php -$object->getMetadata(); -``` - -You can turn a partial object into a full object to get the content after looking at the metadata: -```php -$object->refresh(); -``` - -You can also update to get the latest metadata: - -```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): - -```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: - -```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: - -```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: - -```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. - -## Bulk delete - -Bulk delete a set of paths: - -```php -$pathsToBeDeleted = array('/container_1/old_file', '/container_2/notes.txt', '/container_1/older_file.log'); - -$service->bulkDelete($pathsToBeDeleted); -``` +http://docs.php-opencloud.com/en/latest/services/object-store/objects.html diff --git a/docs/userguide/ObjectStore/USERGUIDE.md b/docs/userguide/ObjectStore/USERGUIDE.md index 0cfab2680..3773b0078 100644 --- a/docs/userguide/ObjectStore/USERGUIDE.md +++ b/docs/userguide/ObjectStore/USERGUIDE.md @@ -1,596 +1,5 @@ # The Complete User Guide to the Object Store Service -**Object Store** is an object-based storage system that stores content and metadata as objects in a cloud. +Our docs have moved! Please visit the below link: -## Prerequisites - -### Client -To use the object store service, you must first instantiate a `OpenStack` or `Rackspace` client object. - -* If you are working with a vanilla OpenStack cloud, instantiate an `OpenCloud\OpenStack` client as shown below. - - ```php - use OpenCloud\OpenStack; - - $client = new OpenStack('', array( - 'username' => '', - 'apiKey' => '' - )); - ``` - -* If you are working with the Rackspace cloud, instantiate a `OpenCloud\Rackspace` client as shown below. - - ```php - use OpenCloud\Rackspace; - - $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => '', - 'apiKey' => '' - )); - ``` - -### Object Store Service -All operations on the object store are done via an object store service object. - -```php -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); -``` - -In the example above, you are connecting to the ``DFW`` region of the cloud. Any containers and objects created with this `$objectStoreService` instance will be stored in that cloud region. - -## Containers -A **container** defines a namespace for **objects**. An object with the same name in two different containers represents two different objects. - -For example, you may create a container called `logos` to hold all the image files for your blog. - -A container may contain zero or more objects in it. - -### Create Container -```php -$container = $objectStoreService->createContainer('logos'); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/create-container.php) ] - -### Get Container Details -You can retrieve a single container's details by using its name. An instance of `OpenCloud\ObjectStore\Resource\Container` is returned. - -```php -$container = $objectStoreService->getContainer('logos'); - -/** @var $container OpenCloud\ObjectStore\Resource\Container **/ -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-container.php) ] - -### List Containers -You can retrieve a list of all your containers. An instance of `OpenCloud\Common\Collection\PaginatedIterator` -is returned. - -```php -$containers = $objectStoreService->listContainers(); -foreach ($containers as $container) { - /** @var $container OpenCloud\ObjectStore\Resource\Container **/ -} -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/list-containers.php) ] - -### Set or Update Container Metadata -You can set metadata on a container. - -```php -$container->saveMetadata(array( - 'author' => 'John Doe' -)); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/set-container-metadata.php) ] - -### Get Container Metadata -You can retrieve the metadata for a container. - -```php -$containerMetadata = $container->getMetadata(); - -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-container-metadata.php) ] - -### Delete Container -When you no longer have a need for the container, you can remove it. - -If the container is empty (that is, it has no objects in it), you can remove it as shown below: - -```php -$container->delete(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/delete-container.php) ] - -If the container is not empty (that is, it has objects in it), you have two choices in how to remove it: - -* [Individually remove each object](#delete-object) in the container, then remove the container itself as shown above, or - -* Remove the container and all the objects within it as shown below: - - ```php - $container->delete(true); - ``` - [ [Get the executable PHP script for this example](/samples/ObjectStore/delete-container-recursive.php) ] - -### Get Object Count - -You can quickly find out how many objects are in a container. - -```php -$containerObjectCount = $container->getObjectCount(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-container-object-count.php) ] - -In the example above, `$containerObjectCount` will contain the number of objects in the container represented by `$container`. - -### Get Bytes Used - -You can quickly find out the space used by a container, in bytes. - -```php -$containerSizeInBytes = $container->getBytesUsed(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-container-bytes-used.php) ] - -In the example above, `$containerSizeInBytes` will contain the space used, in bytes, by the container represented by `$container`. - -### Container Quotas - -#### Set Quota for Number of Objects - -You can set a quota for the maximum number of objects that may be stored in a container. - -```php -$maximumNumberOfObjectsAllowedInContainer = 25; -$container->setCountQuota($maximumNumberOfObjectsAllowedInContainer); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/set-container-count-quota.php) ] - -#### Set Quota for Total Size of Objects - -You can set a quota for the maximum total space (in bytes) used by objects in a container. - -```php -use OpenCloud\Common\Constants\Size; - -$maximumTotalSizeOfObjectsInContainer = 5 * Size::GB; -$container->setBytesQuota($maximumTotalSizeOfObjectsInContainer); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/set-container-bytes-quota.php) ] - -#### Get Quota for Number of Objects - -You can retrieve the quota for the maximum number of objects that may be stored in a container. - -```php -$maximumNumberOfObjectsAllowedInContainer = $container->getCountQuota(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-container-count-quota.php) ] - -#### Get Quota for Total Size of Objects - -You can retrieve the quota for the maximum total space (in bytes) used by objects in a container. - -```php -$maximumTotalSizeOfObjectsAllowedInContainer = $container->getBytesQuota(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-container-bytes-quota.php) ] - -## Objects - -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. - -For example, you may upload an object named `php-elephant.jpg`, a JPEG image file, to the `logos` container. Further, you may assign metadata to this object to indicate that the author of this object was someone named Jane Doe. - -### Upload Object - -Once you have created a container, you can upload objects to it. - -```php -$localFileName = '/path/to/local/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; - -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/upload-object.php) ] - -In the example above, an image file from the local filesystem (`path/to/local/php-elephant.jpg`) is uploaded to a container in the Object Store. - -Note that while we call `fopen` to open the file resource, we do not call `fclose` at the end. The file resource is automatically closed inside the `uploadObject` call. - -It is also possible to upload an object and associate metadata with it. - -```php -use OpenCloud\ObjectStore\Resource\DataObject; - -$localFileName = '/path/to/local/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; -$metadata = array('author' => 'Jane Doe'); - -$customHeaders = array(); -$metadataHeaders = DataObject::stockHeaders($metadata); -$allHeaders = $customHeaders + $metadataHeaders; - -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData, $allHeaders); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/upload-object-with-metadata.php) ] - -Note that while we call `fopen` to open the file resource, we do not call `fclose` at the end. The file resource is automatically closed inside the `uploadObject` call. - -#### Pseudo-hierarchical Folders -Although you cannot nest directories in an Object Store, you can simulate a hierarchical structure within a single container by adding forward slash characters (`/`) in the object name. - -```php -$localFileName = '/path/to/local/php-elephant.jpg'; -$remoteFileName = 'languages/php/elephant.jpg'; - -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/pseudo-hierarchical-folders.php) ] - -In the example above, an image file from the local filesystem (`/path/to/local/php-elephant.jpg`) is uploaded to a container in the Object Store. Within that container, the filename is `languages/php/elephant.jpg`, where `languages/php/` is a pseudo-hierarchical folder hierarchy. - -Note that while we call `fopen` to open the file resource, we do not call `fclose` at the end. The file resource is automatically closed inside the `uploadObject` call. - -#### Upload Multiple Objects -You can upload more than one object at a time to a container. - -```php -$objects = array( - array( - 'name' => 'php-elephant.jpg', - 'path' => '/path/to/local/php-elephant.jpg' - ), - array( - 'name' => 'python-snake.jpg', - 'path' => '/path/to/local/python-snake.jpg' - ), - a -); - -$container->uploadObjects($objects); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/upload-multiple-objects.php) ] - -In the above example, the contents of two files present on the local filesystem are uploaded as objects to the container referenced by `$container`. - -Instead of specifying the `path` key in an element of the `$objects` array, you can specify a `body` key whose value is a string or a stream representation. - -Finally, you can pass headers as the second parameter to the `uploadObjects` method. These headers will be applied to every object that is uploaded. - -``` -$metadata = array('author' => 'Jane Doe'); - -$customHeaders = array(); -$metadataHeaders = DataObject::stockHeaders($metadata); -$allHeaders = $customHeaders + $metadataHeaders; - -$container->uploadObjects($objects, $allHeaders); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/upload-multiple-objects-with-metadata.php) ] - -In the example above, every object referenced within the `$objects` array will be uploaded with the same metadata. - -### Large Objects - -If you want to upload objects larger than 5GB in size, you must use a different upload process. - -```php -$options = array( - 'name' => 'san_diego_vacation_video.mp4', - 'path' => '/path/to/local/videos/san_diego_vacation.mp4' -); -$objectTransfer = $container->setupObjectTransfer($options); -$objectTransfer->upload(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/upload-large-object.php) ] - -The process shown above will automatically partition your large object into small chunks and upload them concurrently to the container represented by `$container`. - -You can tune the parameters of this process by specifying additional options in the `$options` array. Here is a complete listing of keys that can be specified in the `$options` array: - -| Key name | Description | Data Type | Required? | Default Value | Example | -| -------------- | --------------- | ------------- | -------------- | ------------------ | ----------- | -| `name` | Name of large object in container | String | Yes | - | `san_diego_vacation_video.mp4` | -| `path` | Path to file containing object data on local filesystem | String | One of `path` or `body` must be specified | - | `/path/to/local/videos/san_diego_vacation.mp4` | -| `body` | String or stream representation of object data | String \| Stream | One of `path` or `body` must be specified | - | `... lots of data ...` | -| `metadata` | Metadata for the object | Associative array of metadata key-value pairs | No | `array()` | `array( "Author" => "Jane Doe" )` | -| `partSize` | The size, in bytes, of each chunk that the large object is partitioned into prior to uploading | Integer | No | `1073741824` (1GB) | `52428800` (50MB) | -| `concurrency` | The number of concurrent transfers to execute as part of the upload | Integer | No | `1` (no concurrency; upload chunks serially) | `10` | -| `progress` | A [callable function or method](http://us1.php.net/manual/en/language.types.callable.php) which is called to report progress of the the upload. See [`CURLOPT_PROGRESSFUNCTION` documentation](http://us2.php.net/curl_setopt) for details on parameters passed to this callable function or method. | String (callable function or method name) | No | None | `reportProgress` | - -### Auto-extract Archive Files - -You can upload a tar archive file and have the Object Store service automatically extract it into a container. - -```php -use OpenCloud\ObjectStore\Constants\UrlType; - -$localArchiveFileName = '/path/to/local/image_files.tar.gz'; -$remotePath = 'images/'; - -$fileData = fopen($localArchiveFileName, 'r'); -$objectStoreService->bulkExtract($remotePath, $fileData, UrlType::TAR_GZ); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/auto-extract-archive-files.php) ] - -In the above example, a local archive file named `image_files.tar.gz` is uploaded to an Object Store container named `images` (defined by the `$remotePath` variable). - -Note that while we call `fopen` to open a file resource, we do not call `fclose` at the end. The file resource is automatically closed inside the `bulkExtract` call. - -The third parameter to `bulkExtract` is the type of the archive file being uploaded. The acceptable values for this are: - -* `UrlType::TAR` for tar archive files, *or*, -* `UrlType:TAR_GZ` for tar archive files that are compressed with gzip, *or* -* `UrlType::TAR_BZ` for tar archive file that are compressed with bzip - -Note that the value of `$remotePath` could have been a (pseudo-hierarchical folder)[#psuedo-hierarchical-folders] such as `images/blog` as well. - -### List Objects in a Container -You can list all the objects stored in a container. An instance of `OpenCloud\Common\Collection\PaginatedIterator` is returned. - -```php -$objects = $container->objectList(); -foreach ($objects as $object) { - /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ -} -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/list-objects.php) ] - -You can list only those objects in the container whose names start with a certain prefix. - -```php -$options = array( - 'prefix' => 'php' -); - -$objects = $container->objectList($options); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/list-objects-with-params.php) ] - -In general, the `objectList()` method described above takes an optional parameter (`$options` in the example above). This parameter is an associative array of various options. Here is a complete listing of keys that can be specified in the `$options` array: - -| Key name | Description | Data Type | Required? | Default Value | Example | -| -------------- | --------------- | ------------- | -------------- | ------------------ | ----------- | -| `prefix` | Given a string x, limits the results to object names beginning with x. | String | No | | `php` | -| `limit` | Given an integer n, limits the number of results to at most n values. | Integer | No | | 10 | -| `marker` | Given a string x, returns object names greater than the specified marker. | String | No | | `php-elephant.jpg` | -| `end_marker` | Given a string x, returns object names less than the specified marker. | String | No | | `python-snakes.jpg` | - -### Retrieve Object -You can retrieve an object and its metadata, given the object's container and name. - -```php -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); - -/** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ - -$objectContent = $object->getContent(); - -/** @var $objectContent Guzzle\Http\EntityBody **/ - -// Write object content to file on local filesystem. -$objectContent->rewind(); -$stream = $objectContent->getStream(); -$localFilename = tempnam("/tmp", 'php-opencloud-'); -file_put_contents($localFilename, $stream); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-object.php) ] - -In the example above, `$object` is the object named `php-elephant.jpg` in the container represented by `$container`. Further, `$objectContent` represents the contents of the object. It is of type [`Guzzle\Http\EntityBody`](http://api.guzzlephp.org/class-Guzzle.Http.EntityBody.html). - -### Retrieve Object Metadata -You can retrieve just an object's metadata without retrieving its contents. - -```php -$objectName = 'php-elephant.jpg'; -$object = $container->getPartialObject($objectName); -$objectMetadata = $object->getMetadata(); - -/** @var $objectMetadata \OpenCloud\Common\Metadata **/ -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-object-metadata.php) ] - -In the example above, while `$object` is an instance of `OpenCloud\ObjectStore\Resource\DataObject`, that instance is only partially populated. Specifically, only properties of the instance relating to object metadata are populated. - -### Temporary URLs - -The Temporary URL feature allows you to create limited-time Internet addresses that allow you to grant limited access to your Object Store account. Using this feature, you can allow others to retrieve or place objects in your Object Store account for a specified amount of time. Access to the temporary URL is independent of whether or not your account is [CDN-enabled](#cdn-containers). Even if you do not CDN-enable a container, you can still grant temporary public access through a temporary URL. - -First, you must set the temporary URL secret on your account. This is a one-time operation; you only need to perform it the very first time you wish to use the temporary URLs feature. - -```php -$account->setTempUrlSecret(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/set-account-temp-url-secret.php) ] - -Note that this operation is carried out on `$account`, which is an instance of `OpenCloud\ObjectStore\Resource\Account`, a class representing [your object store account](#accounts). - -The above operation will generate a random secret and set it on your account. Instead of a random secret, if you wish to provide a secret, you can supply it as a parameter to the `setTempUrlSecret` method. - -```php -$account->setTempUrlSecret(''); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/set-account-temp-url-secret-specified.php) ] - -Once a temporary URL secret has been set on your account, you can generate a temporary URL for any object in your Object Store. - -```php -$expirationTimeInSeconds = 3600; // one hour from now -$httpMethodAllowed = 'GET'; -$tempUrl = $object->getTemporaryUrl($expirationTimeInSeconds, $httpMethodAllowed); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-object-temporary-url.php) ] - -In the example above, a temporary URL for the object is generated. This temporary URL will provide public access to the object for an hour (3600 seconds), as specified by the `$expirationTimeInSeconds` variable. Further, only GET HTTP methods will be allowed on this URL, as specified by the `$httpMethodAllowed` variable. The other value allowed for the `$httpMethodAllowed` variable would be `PUT`. - -You can also retrieve the temporary URL secret that has been set on your account. - -```php -$tempUrlSecret = $account->getTempUrlSecret(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-account-temp-url-secret.php) ] - -### Update Object - -You can update an object's contents (as opposed to [updating its metadata](#update-object-metadata)) by simply re-[uploading the object](#upload-object) to its container using the same object name as before. - -### Update Object Metadata - -You can update an object's metadata after it has been uploaded to a container. - -```php -$object->saveMetadata(array( - 'author' => 'John Doe' -)); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/update-object-metadata.php) ] - -### Copy Object - -You can copy an object from one container to another, provided the destination container already exists. - -```php -$object->copy('logos_copy/php.jpg'); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/copy-object.php) ] - -In the example above, both the name of the destination container (`logos_copy`)and the name of the destination object (`php.jpg`) have to be specified, separated by a `/`. - -### Delete Object - -When you no longer need an object, you can delete it. - -```php -$object->delete(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/delete-object.php) ] - -### Bulk Delete - -While you can delete individual objects as shown above, you can also delete objects and empty containers in bulk. - -```php -$objectStoreService->bulkDelete(array( - 'logos/php-elephant.png', - 'logos/python-snakes.png', - 'some_empty_container' -)); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/bulk-delete.php) ] - -In the example above, two objects (`some_container/object_a.png`, `some_other_container/object_z.png`) and one empty container (`some_empty_container`) are all being deleted in bulk via a single command. - -## CDN Containers - -Note: The functionality described in this section is available only on the Rackspace cloud. It will not work as described when working with a vanilla OpenStack cloud. - -Any container can be converted to a CDN-enabled container. When this is done, the objects within the container can be accessed from anywhere on the Internet via a URL. - -### Enable CDN Container - -To take advantage of CDN capabilities for a container and its objects, you must CDN-enable that container. - -```php -$container->enableCdn(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/enable-container-cdn.php) ] - -### Public URLs - -Once you have CDN-enabled a container, you can retrieve a publicly-accessible URL for any of its objects. There are four types of publicly-accessible URLs for each object. Each type of URL is meant for a different purpose. The sections below describe each of these URL types and how to retrieve them. - -#### HTTP URL -You can use this type of URL to access the object over HTTP. - -``` -$httpUrl = $object->getPublicUrl(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-cdn-object-http-url.php) ] - -#### Secure HTTP URL -You can use this type of URL to access the object over HTTP + TLS/SSL. - -``` -use OpenCloud\ObjectStore\Constants\UrlType; - -$httpsUrl = $object->getPublicUrl(UrlType::SSL); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-cdn-object-https-url.php) ] - -#### Streaming URL -You can use this type of URL to stream a video or audio object using Adobe's HTTP Dynamic Streaming. - -``` -use OpenCloud\ObjectStore\Constants\UrlType; - -$streamingUrl = $object->getPublicUrl(UrlType::STREAMING); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-cdn-object-streaming-url.php) ] - -#### IOS Streaming URL - -You can use this type of URL to stream an audio or video object to an iOS device. - -``` -use OpenCloud\ObjectStore\Constants\UrlType; - -$iosStreamingUrl = $object->getPublicUrl(UrlType::IOS_STREAMING); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-cdn-object-ios-streaming-url.php) ] - -### Disable CDN Container - -If you no longer need CDN capabilities for a container, you can disable them. - -```php -$container->disableCdn(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/disable-container-cdn.php) ] - -## Accounts -An **account** defines a namespace for **containers**. An account can have zero or more containers in it. - -### Retrieve Account -You must retrieve the account before performing any operations on it. - -```php -$account = $objectStoreService->getAccount(); -``` - -### Get Container Count - -You can quickly find out how many containers are in your account. - -```php -$accountContainerCount = $account->getContainerCount(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-account-container-count.php) ] - -### Get Object Count - -You can quickly find out how many objects are in your account. - -```php -$accountObjectCount = $account->getObjectCount(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-account-object-count.php) ] - -In the example above, `$accountObjectCount` will contain the number of objects in the account represented by `$account`. - -### Get Bytes Used - -You can quickly find out the space used by your account, in bytes. - -```php -$accountSizeInBytes = $account->getBytesUsed(); -``` -[ [Get the executable PHP script for this example](/samples/ObjectStore/get-account-bytes-used.php) ] - -In the example above, `$accountSizeInBytes` will contain the space used, in bytes, by the account represented by `$account`. +http://docs.php-opencloud.com/en/latest/services/object-store/index.html diff --git a/docs/userguide/Orchestration/README.md b/docs/userguide/Orchestration/README.md new file mode 100644 index 000000000..3647da0c9 --- /dev/null +++ b/docs/userguide/Orchestration/README.md @@ -0,0 +1,5 @@ +# Orchestration + +Our docs have moved! Please visit the below link: + +http://docs.php-opencloud.com/en/latest/services/orchestration/index.html diff --git a/docs/userguide/Orchestration/USERGUIDE.md b/docs/userguide/Orchestration/USERGUIDE.md new file mode 100644 index 000000000..4a5b9a135 --- /dev/null +++ b/docs/userguide/Orchestration/USERGUIDE.md @@ -0,0 +1,5 @@ +# Complete User Guide for the Orchestration Service + +Our docs have moved! Please visit the below link: + +http://docs.php-opencloud.com/en/latest/services/orchestration/index.html diff --git a/docs/userguide/Queues/Claim.md b/docs/userguide/Queues/Claim.md old mode 100755 new mode 100644 index 13e12eac8..58b57d22f --- a/docs/userguide/Queues/Claim.md +++ b/docs/userguide/Queues/Claim.md @@ -1,123 +1,5 @@ ## 1. Introduction -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. +Our docs have moved! Please visit the below link: -## 2. Setup - -A Claim is initialized on its parent object, a Queue: - -```php -// To intialize an empty object: -$claim = $queue->getClaim(); - -// or retrieve a specific claim: -$claim = $queue->getClaim('51db7067821e727dc24df754'); -``` - -## 3. Claim messages - -### 3.1 Description - -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. - -### 3.2 Attributes - -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. - -### 3.3 Code - -```php -use OpenCloud\Common\Constants\Datetime; - -$queue->claimMessages(array( - 'limit' => 15, - 'grace' => 5 * Datetime::MINUTE, - 'ttl' => 5 * Datetime::MINUTE -)); -``` - -## 4. Query claim - -### 4.1 Description - -This operation queries the specified claim for the specified queue. Claims with malformed IDs or claims that are not -found by ID are ignored. - -### 4.2 Attributes - -Claim ID. - -### 4.3 Code - -```php -$claim = $queue->getClaim('51db7067821e727dc24df754'); -``` - -## 5. Update claim - -### 5.1 Description - -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. - -### 5.2 Attributes - -See section 4.2. - -### 5.3 Code - -```php -use OpenCloud\Common\Constants\Datetime; - -$claim->update(array( - 'ttl' => 10 * Datetime::MINUTE -)); -``` - -## 6. Release claim - -### 6.1 Description - -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. - -### 6.2 Attributes - -See section 4.2. - -### 6.3 Code - -```php -$message->delete(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/queues/claims.html diff --git a/docs/userguide/Queues/Message.md b/docs/userguide/Queues/Message.md old mode 100755 new mode 100644 index d27f2fbbf..767bb0b1d --- a/docs/userguide/Queues/Message.md +++ b/docs/userguide/Queues/Message.md @@ -1,207 +1,5 @@ ## 1. Introduction -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. +Our docs have moved! Please visit the below link: -## 2. Setup - -A message is initialized from its parent object, a Queue: - -```php -// Setup an empty object -$message = $queue->getMessage(); - -// or retrieve an existing one -$message = $queue->getMessage(''); -``` - -## 3. Post message - -### 3.1 Description - -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. - -### 3.2 Parameters - -How you pass through the array structure depends on whether you are executing multiple (3.3.2) or single (3.3.3) 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. - -### 3.3 Code samples - -#### 3.3.1 Posting a single message - -``` -use OpenCloud\Common\Constants\Datetime; - -$queue->createMessage(array( - 'body' => (object) array( - 'event' => 'BackupStarted', - 'deadline' => '26.12.2013 - ), - 'ttl' => 2 * Datetime::DAY -)); -``` - -#### 3.3.2 Post a batch of messages - -Please note that the list of messages will be truncated at 10. For more, please execute another method call. - -```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); -``` - -## 4. Get messages - -### 4.1 Description - -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. - -### 4.2 Parameters - -A hash of 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. - -### 4.3 Code sample - -```php -$messages = $queue->listMessages(array( - 'marker' => '51db6f78c508f17ddc924357', - 'limit' => 20, - 'echo' => true -)); - -while ($message = $messages->next()) { - echo $message->getId() . PHP_EOL; -} -``` - -## 5. Get a set of messages by ID - -### 5.1 Description - -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. - -### 5.2 Parameters - -A hash of options. - -|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|​String|Specifies the claim ID with which the message is associated. Optional.| -|----|-----|----|-----------| - -### 5.3 Code sample - -```php -$ids = array('51db6f78c508f17ddc924357', 'f5b8c8a7c62b0150b68a50d6'); - -$messages = $queue->listMessages(array('ids' => $ids)); - -while ($message = $messages->next()) { - echo $message->getId() . PHP_EOL; -} -``` - -## 6. Delete a set of messages by ID - -### 6.1 Description - -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. - -### 6.2 Parameters - -An array of IDs. - -### 6.3 Code sample - -```php -$ids = array('51db6f78c508f17ddc924357', 'f5b8c8a7c62b0150b68a50d6'); - -$response = $queue->deleteMessages($ids); -``` - -## 7. Get a specific message - -### 7.1 Description - -This operation gets the specified message from the specified queue. - -### 7.2 Parameters - -Message ID. - -### 7.3 Object properties - -`href` is an opaque relative URI that the client can use to uniquely identify a message resource and interact with it. - -`ttl` is the TTL that was set on the message when it was posted. The message expires after (ttl - age) seconds. - -`age` is the number of seconds relative to the server's clock. - -`body` is the arbitrary document that was submitted with the original request to post the message. - -### 7.4 Code sample - -```php -$message = $queue->getMessage('51db6f78c508f17ddc924357'); -``` - -## 8. Delete message - -### 8.1 Description - -This operation immediately deletes the specified message. - -### 8.2 Parameters - -None. - -### 8.3 Code sample - -```php -$message->delete(); -``` +http://docs.php-opencloud.com/en/latest/services/queues/messages.html diff --git a/docs/userguide/Queues/Queue.md b/docs/userguide/Queues/Queue.md old mode 100755 new mode 100644 index 16290f445..2299a72e2 --- a/docs/userguide/Queues/Queue.md +++ b/docs/userguide/Queues/Queue.md @@ -1,156 +1,5 @@ ## 1. Introduction -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. +Our docs have moved! Please visit the below link: -## 2. Setup - -```php -$service = $client->queuesService('cloudQueues', 'ORD'); -``` - -## 3. Client IDs - -With most of Marconi's operation, 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. - -```php -$service->setClientId(); - -echo $service->getClientId(); -``` - -If you call `setClientId` without any parameters, a UUID is automatically generated for you. - -## 4. List queues - -### 4.1 Description - -This operation lists queues for the project. The queues are sorted alphabetically by name. - -### 4.2 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.| - |----|-----|----|-----------| - -### 4.3 Code sample - -```php -$queues = $service->listQueues(); - -while ($queue = $queues->next()) { - echo $queue->getName() . PHP_EOL; -} -``` - -## 5. Create queue - -### 5.1 Description - -This operation creates a new queue. - -### 5.2 Parameters - -A string representation of the name for your new Queue. The name must not exceed 64 bytes in length, and it is limited -to US-ASCII letters, digits, underscores, and hyphens. - -### 5.3 Code sample - -```php -$queue = $service->createQueue('new_queue'); -``` - -## 6. Retrieve queue - -### 6.1 Description - -Returns a `Queue` object for use. - -### 6.2 Parameters - -Queue name. - -### 6.3 Code sample - -```php -$queue = $service->getQueue('new_queue'); -``` - -## 7. Check queue existence - -### 7.1 Description - -This operation verifies whether the specified queue exists by returning `TRUE` or `FALSE`. - -### 7.2 Parameters - -### 7.3 Code sample - -```php -if ($service->hasQueue('new_queue')) { - // do something -} -``` - -## 8. Update queue metadata (permanently to the API) - -### 4.1 Description - -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. - -### 4.2 Parameters - -Hash of key pairs. - -### 4.3 Code sample - -```php -$queue->saveMetadata(array( - 'foo' => 'bar' -)); -``` - -## 9. Retrieve the queue metadata (fresh from the API) - -### 4.1 Description - -This operation returns metadata, such as message TTL, for the queue. - -### 4.2 Parameters - -None. - -### 4.3 Code sample - -```php -$metadata = $queue->retrieveMetadata(); - -print_r($metadata->toArray()); -``` - -## 10. Get queue stats - -### 4.1 Description - -This operation returns queue statistics, including how many messages are in the queue, categorized by status. - -### 4.2 Parameters - -None. - -### 4.3 Code sample - -```php -$queue->getStats(); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/queues/queues.html diff --git a/docs/userguide/README.md b/docs/userguide/README.md new file mode 100644 index 000000000..b49b4e67c --- /dev/null +++ b/docs/userguide/README.md @@ -0,0 +1,5 @@ +# Table of contents + +Our docs have moved! Please visit the below link: + +http://docs.php-opencloud.com/en/latest/index.html diff --git a/docs/userguide/Services.md b/docs/userguide/Services.md index 6f67222a2..6973130eb 100644 --- a/docs/userguide/Services.md +++ b/docs/userguide/Services.md @@ -1,47 +1,5 @@ # Services -Both OpenStack and Rackspace are comprised of different services: Compute (Nova), -Object Storage (Swift), Queues (Marconi), etc. Each of these services is -encapsulated in its own class which implements the -`OpenCloud\Common\Service\ServiceInterface` interface. +Our docs have moved! Please visit the below link: -Each service class is nested in its own namespace: - -Service|OpenStack codename|FQCN ----|---|--- -Compute|Nova|`OpenCloud\Compute\Service` -Object Storage|Swift|`OpenCloud\ObjectStore\Service` -Identity|Keystone|`OpenCloud\Identity\Service` -Queues|Marconi|`OpenCloud\Queues\Service` - -## Instantiating a service - -The easiest way to instantiate a service, is using the convenient factory -methods of the client class. For more information about clients, see the -[client documentation](Clients.md). - -To create a Compute service, for example: - -```php -$service = $client->computeService('cloudServersOpenStack', 'DFW'); -``` - -### Method arguments - -As you will notice, each factory method accepts three arguments: - -Position|Name|Required?|Type|Description ----|---|---|---|--- -1|Service name|Yes|string|The name of the service as it appears in the [Service Catalog](https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/Clients.md#service-catalog) -2|Region|Yes|string|The region you want your service to operate in -3|URL type|No|enum|Each service has two different URL types for API transactions: a public URL (i.e. over the Internet) and a private URL (through Rackspace's private network). Private URL's are beneficial because they have lower latency and incur no bandwidth charges; the only condition is that you are communicating to the API from the **same geographic region** (i.e. from a Cloud Serve in the same region).

      The accepted options you may pass in are either `OpenCloud\Common\Constants\Service::INTERNAL_URL` or `OpenCloud\Common\Constants\Service::PUBLIC_URL`. - - -## Differences between OpenStack and Rackspace - -Not all of Rackspace's services are supported by OpenStack; examples include: -Cloud Databases, Auto Scale, Load Balancers, DNS, etc. - -For this reason, if you want to use or interact with these Rackspace-only -services, you must do so by using the methods of the `OpenCloud\Rackspace` -client object and **not** the `OpenCloud\OpenStack` client. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/index.html diff --git a/docs/userguide/accessip.md b/docs/userguide/accessip.md old mode 100755 new mode 100644 index 60c89b606..9d343de11 --- a/docs/userguide/accessip.md +++ b/docs/userguide/accessip.md @@ -1,51 +1,6 @@ About the Access IP Addresses ============================= -OpenStack deployments generally provide new [servers](servers.md) with one -or two network interfaces, each with its own address(es). Usually, one of -these will be a public interface, with its addresses available on the Internet. +Our docs have moved! Please visit the below link: -However, in some cases, the servers are created on an internal network -(this is especially common in a hybrid solution where physical and virtual -servers are intermixed). The servers may be behind a NAT device, firewall, -or other network device that prohibits direct access to the server itself. - -The `OpenCloud\Compute\Resource\Server` object provides two attributes that are -used to instruct applications what IP address to use. These are called the -*access IP* addresses, and they are, in essence, documentation strings used to -direct applications to the correct network address. They can be changed at will -by the server's owner, and OpenStack Nova does not perform any validation on -them: - -* `accessIPv4` holds the IPv4 access address, and -* `accessIPv6` holds the IPv6 access address. - -### Updating the access IP address(es) - -For example, you may have a private cloud with internal addresses in the -10.1.x range. However, you can access a server via a firewall device at -address 50.57.94.244. In this case, you can change the `accessIPv4` attribute -to point to the firewall: - -```php -$server->update(array('accessIPv4' => '50.57.94.244')); -``` - -When a client application retrieves the server's information, it will know -that it needs to use the `accessIPv4` address to connect to the server, and -*not* the IP address assigned to one of the network interfaces. - -### Retrieving the server's IP address - -The `Server::ip()` method is used to retrieve the server's IP address. -It has one optional parameter: the format (either IPv4 or IPv6) of the address -to return (by default, it returns the IPv4 address): - -```php -// IPv4 -echo $server->ip(); -echo $server->ip(4); - -// IPv6 -echo $server->ip(6); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/compute/servers.html diff --git a/docs/userguide/caching-credentials.md b/docs/userguide/caching-credentials.md index d38d69937..949dcad53 100644 --- a/docs/userguide/caching-credentials.md +++ b/docs/userguide/caching-credentials.md @@ -1,39 +1,5 @@ # 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. +Our docs have moved! Please visit the below link: -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. - -```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. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/caching-creds.html diff --git a/docs/userguide/dbaas.md b/docs/userguide/dbaas.md old mode 100755 new mode 100644 index 8a8a05176..fe0327861 --- a/docs/userguide/dbaas.md +++ b/docs/userguide/dbaas.md @@ -1,319 +1,6 @@ Working with Cloud Databases ============================ -Cloud Databases is a "database-as-a-service" product offered by Rackspace. Since it is -not an official OpenStack project, it is only available via Rackspace connections, -and *not* through an OpenStack connection. +Our docs have moved! Please visit the below link: -## Setup - -```php -$service = $client->databaseService('cloudDatabases', 'ORD'); -``` - -For more information about setting up client objects, see the -[client documentation](Clients.md). For more information about service objects, -including a full list of expected arguments, see the -[service documentation](Services.md). - -## Instances - -A database instance is an isolated MySQL instance in a single tenant environment -on a shared physical host machine. Also referred to as instance. - -### Create a new Instance - -```php -// Create an empty OpenCloud\Database\Resource\Instance object -$instance = $service->instance(); - -// Send to the API -$instance->create(array( - // Pass in a name for your database instance - 'name' => '', - // Pass in a particular flavor object - 'flavor' => $service->flavor(''), - // Specify a 4GB volume - 'volume' => array('size' => 4) -)); -``` -[ [Get the executable PHP script for this example](/samples/Database/create-instance.php) ] - -### Retrieving an instance - -```php -$instance = $service->instance(''); -``` -[ [Get the executable PHP script for this example](/samples/Database/get-instance.php) ] - -### Updating an instance -An instance can be updated to use a specific [configuration](#configurations) as shown below. - -```php -$instance->update(array( - 'configuration' => '' -)); -``` - -**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 - -```php -$instance->delete(); -``` - -### Restarting an instance - -```php -$instance->restart(); -``` - -### Resizing an instance - -There are two methods for resizing an instance. The first, `resize()`, changes the amount -of RAM allocated to the instance: - -```php -$flavor = $service->flavor(''); -$instance->resize($flavor); -``` - -You can also independently change the volume size to increase the disk space: - -```php -// Increase to 8GB disk -$instance->resizeVolume(8); -``` - -## Databases - -Instances can have multiple databases; the `OpenCloud\Database\Resource\Database` -class corresponds to a single MySQL database. - -### 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: - -```php -// Create a new OpenCloud\Database\Resource\Database 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](http://dev.mysql.com/doc/refman/5.0/en/charset-mysql.html). - -### Deleting a database - -```php -$database->delete(); -``` - -Note that this is destructive; all your data will be wiped away and will not be -retrievable. - -### Listing databases - -```php -$databases = $service->databaseList(); - -foreach ($databases as $database) { - /** @param $database OpenCloud\Database\Resource\Database */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](Iterators.md). - -### 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. - -Users cannot be altered after they are created, so they must be assigned to -databases when they are created: - -```php -// New instance of OpenCloud\Database\Resource\User -$user = $instance->user(); - -// Send to API -$user->create(array( - 'name' => 'Alice', - 'password' => 'fooBar' - 'databases' => array('production') -)); -``` - -If you need to add a new database to a user after it's been created, you must -delete the user and then re-add it. - -### Deleting users - -```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 want to enable access to the root user, the `enableRootUser()` method is -available: - -```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. - -To check if the root user is enabled, use the `isRootEnabled()` method. - -## Configurations - -Configurations are groups of settings that can be [applied to instances](#updating-an-instance). - -### Creating a configuration -You can create a new configuration as shown below: - -```php -$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' - ) -)); -/** @var $configuration OpenCloud\Database\Resource\Configuration **/ -``` -[ [Get the executable PHP script for this example](/samples/Database/create-configuration.php) ] - -### Listing configurations -You can list out all the configurations you have created as shown below: - -```php -$configurations = $service->configurationList(); -foreach ($configurations as $configuration) { - /** @var $configuration OpenCloud\Database\Resource\Configuration **/ -} -``` -[ [Get the executable PHP script for this example](/samples/Database/list-configurations.php) ] - -### Retrieving a configuration -You can retrieve a specific configuration, using its ID, as shown below: - -```php -$configuration = $service->configuration(getenv('OS_DB_CONFIGURATION_ID')); -/** @var OpenCloud\Database\Resource\Configuration **/ -``` -[ [Get the executable PHP script for this example](/samples/Database/get-configuration.php) ] - -### Updating a configuration -You have two choices when updating a configuration: -* You could [patch a configuration](#patching-a-configuration) to change only some configuration parameters, _or_ -* You could [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: - -```php -$configuration->patch(array( - 'values' => array( - 'connect_timeout' => 30 - ) -)); -``` -[ [Get the executable PHP script for this example](/samples/Database/patch-configuration.php) ] - -#### Replacing a configuration -You can replace a configuration as shown below: - -```php -$configuration->update(array( - 'values' => array( - 'collation_server' => 'utf8_general_ci', - 'connect_timeout' => 60 - ) -)); -``` -[ [Get the executable PHP script for this example](/samples/Database/replace-configuration.php) ] - -### Deleting a configuration -You can delete a configuration as shown below: - -```php -$configuration->delete(); -``` -[ [Get the executable PHP script for this example](/samples/Database/delete-configuration.php) ] - -**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: - -```php -$instances = $configuration->instanceList(); -foreach ($instances as $instance) { - /** @var $instance OpenCloud\Database\Resource\Instance **/ -} -``` -[ [Get the executable PHP script for this example](/samples/Database/list-configuration-instances.php) ] - -## Datastores - -Datastores are technologies avaialable to persist data. - -### Listing datastores -You can list out all the datastores available as shown below: - -```php -$datastores = $service->datastoreList(); -foreach ($datastores as $datastore) { - /** @var $datastore OpenCloud\Database\Resource\Datastore **/ -} -``` -[ [Get the executable PHP script for this example](/samples/Database/list-datastores.php) ] - -### Retrieving a datastore -You can retrieve a specific datastore's information, using its ID, as shown below: - -```php -$datastore = $service->datastore(''); -/** @var OpenCloud\Database\Resource\Datastore **/ -``` -[ [Get the executable PHP script for this example](/samples/Database/get-datastore.php) ] - -### Listing datastore versions -You can list out all the versions available for a specific datastore, as shown below: - -```php -$versions = $datastore->versionList(); -foreach ($versions as $version) { - /** @var $version OpenCloud\Database\Resource\DatastoreVersion **/ -} -``` -[ [Get the executable PHP script for this example](/samples/Database/list-datastore-versions.php) ] - -### Retrieving a datastore version -You a retrieve a specific datastore version, using its ID, as shown below: - -```php -$datastoreVersion = $datastore->version(''); -/** @var OpenCloud\Database\Resource\DatastoreVersion **/ -[ [Get the executable PHP script for this example](/samples/Database/get-datastore-version.php) ] +http://docs.php-opencloud.com/en/latest/services/database/index.html diff --git a/docs/userguide/flavors.md b/docs/userguide/flavors.md old mode 100755 new mode 100644 index 41e3fa8d4..4bf978b52 --- a/docs/userguide/flavors.md +++ b/docs/userguide/flavors.md @@ -1,60 +1,6 @@ Working with Flavors ==================== -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.) +Our docs have moved! Please visit the below link: -## Get a flavor - -A `Flavor` object is generated from the `flavor()` method on an -`OpenCloud\Compute\Service` object: - -```php -$flavor = $service->flavor(''); -``` - -## List flavors - -```php -$flavors = $service->flavorList(); - -foreach ($flavors as $flavor) { - /** @param $flavor OpenCloud\Common\Resource\FlavorInterface */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](Iterators.md). - -### Details - -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 expected. You can supply an optional -boolean parameter to the `flavorList()` method to determine whether or not -the flavor details are included: - -```php -// Name and ID only -$compute->flavorList(false); - -// All details -$compute->flavorList(true); -``` - -### Filters - -The optional second parameter to the `flavorList()` method is an -associative array of filter parameters. See the -[List Flavors operation](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/List_Flavors-d1e4188.html) - for a list of the available parameters. - -For example, you may be only interested in flavors that have at least 4GB of -memory: - -```php -$fourGbFlavors = $compute->FlavorList(true, array('minRam' => 4096)); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/compute/flavors.html diff --git a/docs/userguide/networks.md b/docs/userguide/networks.md old mode 100755 new mode 100644 index f24752fc4..f6a153508 --- a/docs/userguide/networks.md +++ b/docs/userguide/networks.md @@ -1,103 +1,6 @@ Working with Cloud Networks =========================== -Rackspace Cloud Networks is a virtual "isolated network" product -based upon (though not strictly identical to) the [OpenStack -Quantum](http://quantum.openstack.org) project. With Cloud Networks, -you can create multiple isolated networks and associate them with -new Cloud Servers. (You cannot add an isolated network to an -existing Cloud Server at this time, although that feature may be -available in the future.) +Our docs have moved! Please visit the below link: -Since the network is a feature of the Cloud Servers product, you -use the `Compute::network()` method to create a new network, and -the `Compute::networkList()` method to retrieve information about -existing networks. - -### Pseudo-networks - -Rackspace has two *pseudo-networks* called `public` and `private`. -The `public` network represents the Internet, while the `private` -network represents the Rackspace internal ServiceNet (an infrastructure -network used to facilitate communication within a Rackspace data -center). These are called "pseudo-networks" because they are not -actually represented in the Quantum component, but have a special -representation that you must use if you want to associate your -server with them. - -The `public` network is represented by the special UUID -`00000000-0000-0000-0000-000000000000` and the `private` network -by `11111111-1111-1111-1111-111111111111`. php-opencloud -provides the special constants `RAX_PUBLIC` and `RAX_PRIVATE` to -make using these networks easier (see [Create a server with an -isolated network](#server) below). - - -### Create a network - -A Cloud Network is identified by a *label* and must be defined with -a network *CIDR* address range. For example, we can create a network -used by our backend servers on the 192.168.0.0 network like this: - -```php -// Create instance of OpenCloud\Compute\Resource\Network -$network = $compute->network(); - -// Send to API -$network->create(array( - 'label' => 'Backend Network', - 'cidr' => '192.168.0.0/16' -)); -``` - -### Delete a network - -```php -$network->delete(); -``` - -Note that you cannot delete a network if there are still servers attached to it. - -### Listing networks - -``` -$networks = $service->networkList(); - -foreach ($networks as $network) { - /** @param $network OpenCloud\Compute\Resource\Network */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](Iterators.md). - -## Create a server with an isolated network - -When you create a new server, you can specify the networks to which -it is attached via the `networks` attribute in the `Server::create()` -method: - -use OpenCloud\Compute\Constants\Network; - -// Create instance of OpenCloud\Compute\Resource\Server -$server = $compute->server(); - -// Send to API -$server->create(array( - 'name' => 'My Server', - 'flavor' => $compute->flavor(''), - 'image' => $compute->image(''), - 'networks' => array( - $network, - $compute->network(Network::RAX_PUBLIC) - ) -)); -``` - -In this example, the server `$server` is attached to the network that we -created in the previous example. It is also attached to the Rackspace `public` -network (the Internet). However, it is *not* attached to the Rackspace `private` -network (ServiceNet). - -Note that the `networks` attribute is an array of `OpenCloud\Compute\Resource\Network` -objects. \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/networking/index.html diff --git a/docs/userguide/servers.md b/docs/userguide/servers.md old mode 100755 new mode 100644 index 8f58adea0..1ff28fd30 --- a/docs/userguide/servers.md +++ b/docs/userguide/servers.md @@ -1,188 +1,6 @@ Working with Servers ==================== -A server is a virtual machine instance that is managed by OpenStack Nova. It is -represented by the `OpenCloud\Compute\Resource\Server` class. - -## Setup - -In order to use a `Server` object, you must create the Compute service first: - -```php -$service = $client->computeService('cloudServersOpenStack', 'ORD'); -``` - -For more information about setting up client objects, see the -[client documentation](Clients.md). For more information about service objects, -including a full list of expected arguments, see the -[service documentation](Services.md). - -## Get an existing server - -To retrieve an existing server, all you need is its unique ID: - -```php -/** @param $server OpenCloud\Compute\Resource\Server */ -$server = $server->server(''); -``` - -## Create a new server - -A server requires both a [Flavor object](flavors.md) and an -[Image object](images.md) to be created. In addition, a server requires a name: - -```php -// New instance of OpenCloud\Compute\Resource\Server -$server = $service->server(); - -/** @param $server OpenCloud\Image\Resource\ImageInterface */ -$image = $service->image(''); - -/** @param $server OpenCloud\Compute\Resource\Flavor */ -$flavor = $service->flavor(''); - -// Send to API -$server->create(array( - 'name' => 'New server', - 'flavor' => $flavor, - 'image' => $image -)); -``` - -Server builds typically take under 5 minutes to complete (depending upon the size -of the server). However, the initial response will return the server's ID as -well as the assigned root password: - -```php -echo $server->adminPass; -``` - -(Note: it is not recommended that you print out the root password because of -security risks. This is only provided as an example.) - -When you create a new server on the Rackspace public cloud, you can also -associate it with one or more isolated networks. For more information, see -[Working with Cloud Networks](networks.md). - -### Rebuilding an existing server - -"Rebuilding" a server is nearly identical to creating one; you must supply -an Image object. You can also change the server's name as part of the rebuild. -The primary difference between a create and a rebuild is that, in the rebuild, -the server's IP address(es) are retained (when the server is created, new IP -addresses are assigned). - -To rebuild a server: - -```php -$server->rebuild(array( - 'adminPass' => 'rootPassword', - 'name' => 'A Bigger Server', - 'image' => $compute->image('') -)); -``` - -### Updating a server - -The `update()` method is very similar to `create()` except that the only -attributes of a server that you are permitted to update are its name and -the [access IP addresses](accessip.md). - -```php -$server->update(array('accessIPv4' => '50.57.94.244')); -``` - -### Deleting a server - -```php -$server->delete(); -``` - -## Server actions - -You can perform various actions on a server, such as rebooting it, resizing -it, or changing the root password. - -### Setting the root password - -Use the `setPassword()` method to change the root user's password: - -```php -$server->setPassword('new password'); -``` - -Note that it may take a few second for the new password to take effect. Also, -password restrictions (such as the minimum number of characters, numbers of -punctuation characters, and so forth) are enforced by the operating system and are -not always detectable by the Compute service. This means that, even though -the `setPassword()` method succeeds, the password may not be changed, and -there may not be any feedback to that effect. - -### To reboot the server - -You can perform either a *hard* reboot (this is like pulling the power cord -and then restarting) or a *soft* reboot (initiated by the operating system -and generally less disruptive than a hard reboot). A hard reboot is -performed by default: - -```php -$server->reboot(); // hard reboot -$server->reboot(ServerState::REBOOT_STATE_HARD); // also a hard reboot -$server->reboot(ServerState::REBOOT_STATE_SOFT); // a soft reboot -``` - -If the server is "hung," or unresponsive, a hard reboot may sometimes be -the only way to access the server. - -### To resize the server - -A server can be resized by providing a new [Flavor object](flavors.md): - -```php -$server->resize($compute->flavor(5)); -``` - -Once the resize completes (check the `$server->status`), you can either -confirm it: - -```php -$server->resizeConfirm(); -``` - -or revert it back to the original size: - -```php -$server->resizeRevert(); -``` - -### To rescue/unrescue a server - -In rescue mode, a server is rebuilt to a pristine state and the existing -filesystem is mounted so that you can edit files and diagnose issues. -See [this document](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/rescue_mode.html) -for more details. - -Put server into rescue mode: - -```php -$password = $server->rescue(); -``` - -The `$password` is the assigned root password of the rescue server. - -Take server out of rescue mode: - -```php -$server->unrescue(); -``` - -This restores the server to its original state (plus any changes you may have -made while it was in rescue mode). - -## What next? - -* See also [Working with Networks](networks.md). -* To learn about dynamic - volume creation and assignment, see - [Working with Volumes](volumes.md). +Our docs have moved! Please visit the below link: +http://docs.php-opencloud.com/en/latest/services/compute/index.html diff --git a/docs/userguide/volumes.md b/docs/userguide/volumes.md old mode 100755 new mode 100644 index bd2f13a9d..bc161e5b3 --- a/docs/userguide/volumes.md +++ b/docs/userguide/volumes.md @@ -1,173 +1,6 @@ Working with Volumes ---------------------------------------------- -Cloud Block Storage (CBS) is a dynamic volume creation and management service -built upon the OpenStack Cinder project. See http://cinder.openstack.org for -complete details about the available features and functionality. -## Setup +Our docs have moved! Please visit the below link: -```php -$service = $client->volumeService('cloudBlockStorage', 'DFW'); -``` - -For more information about setting up client objects, see the -[client documentation](Clients.md). For more information about service objects, -including a full list of expected arguments, see the -[service documentation](Services.md). - -## Volume Types - -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). - -### List volume types - -```php -$volumeTypes = $service->volumeTypeList(); - -foreach ($volumeTypes as $volumeType) { - /** @param $volumeType OpenCloud\Volume\Resource\VolumeType */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](Iterators.md). - -### Describe a volume type - -If you know the ID of a volume type, use the `volumeType` method to retrieve -information on it: - -```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 - -## Volumes - -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. - -A volume is represented by the `OpenCloud\Volume\Resource\Volume` class. - -### To create a volume - -To create a volume, you must specify its size (in gigabytes). All other -parameters are optional: - -```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 - -```php -$volumes = $service->volumeList(); - -foreach ($volumes as $volume) { - /** @param $volumeType OpenCloud\Volume\Resource\Volume */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](Iterators.md). - -### Get details on a single volume - -If you specify an ID on the `volume()` method, it retrieves information on -the specified volume: - -```php -$volume = $dallas->volume(''); -echo $volume->size; -``` - -### To delete a volume - -```php -$volume->delete(); -``` - -## Snapshots - -A snapshot is a point-in-time copy of the data contained in a volume. It is -represented by the `OpenCloud\Volume\Resource\Snapshot` class. - -### 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: - -```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 - -```php -$snapshots = $service->snapshotList(); - -foreach ($snapshots as $snapshot) { - /** @param $snapshot OpenCloud\Volume\Resource\Snapshot */ -} -``` - -For more information about working with iterators, please see the -[iterators documentation](Iterators.md). - -### To get details on a single snapshot - -```php -$snapshot = $dallas->snapshot(''); -``` - -#### To delete a snapshot - -```php -$snapshot->delete(); -``` - -### Volumes and Servers - -A volume by itself is useful when it is attached to a server so that the -server can use the volume. - -### To attach a volume to a server - -```php -$server->attachVolume($volume, '') -``` - -The `` 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 -`{mount-point}`, so you do not actually need to supply anything for that -parameter. - -### To detach a volume from a server - -```php -$server->detachVolume($volume); -``` \ No newline at end of file +http://docs.php-opencloud.com/en/latest/services/volume/index.html diff --git a/lib/OpenCloud/Autoscale/Resource/LaunchConfiguration.php b/lib/OpenCloud/Autoscale/Resource/LaunchConfiguration.php index f4f683f7a..29951254c 100644 --- a/lib/OpenCloud/Autoscale/Resource/LaunchConfiguration.php +++ b/lib/OpenCloud/Autoscale/Resource/LaunchConfiguration.php @@ -38,7 +38,6 @@ */ class LaunchConfiguration extends AbstractResource { - public $type; public $args; diff --git a/lib/OpenCloud/CDN/Resource/Flavor.php b/lib/OpenCloud/CDN/Resource/Flavor.php new file mode 100644 index 000000000..de13eb9f2 --- /dev/null +++ b/lib/OpenCloud/CDN/Resource/Flavor.php @@ -0,0 +1,51 @@ +noUpdate(); + } + + protected function createJson() + { + $createJson = parent::createJson(); + return $createJson->{self::$json_name}; + } +} diff --git a/lib/OpenCloud/CDN/Resource/Service.php b/lib/OpenCloud/CDN/Resource/Service.php new file mode 100644 index 000000000..5e3a2ff48 --- /dev/null +++ b/lib/OpenCloud/CDN/Resource/Service.php @@ -0,0 +1,115 @@ + 'flavorId', + 'http_host' => 'httpHost', + 'request_url' => 'requestUrl' + ); + + protected $createKeys = array( + 'name', + 'domains', + 'origins', + 'caching', + 'restrictions', + 'flavorId' + ); + + protected $updateKeys = array( + 'name', + 'domains', + 'origins', + 'caching', + 'restrictions', + 'flavorId' + ); + + public function purgeAssets($assetUrl = null) + { + $assetsUrl = $this->assetsUrl(); + if (null === $assetUrl) { + $assetsUrl->setQuery(array('all' => 'true')); + } else { + $assetsUrl->setQuery(array('url' => $assetUrl)); + } + + $request = $this->getClient()->delete($assetsUrl); + + // This is necessary because the response does not include a body + // and fails with a 406 Not Acceptable if the default + // 'Accept: application/json' header is used in the request. + $request->removeHeader('Accept'); + + return $request->send(); + } + + protected function assetsUrl() + { + $url = clone $this->getUrl(); + $url->addPath('assets'); + + return $url; + } + + protected function createJson() + { + $createJson = parent::createJson(); + return $createJson->{self::$json_name}; + } + + /** + * Update this resource + * + * @param array $params + * @return \Guzzle\Http\Message\Response + */ + public function update($params = array()) + { + $json = $this->generateJsonPatch($params); + + return $this->getClient() + ->patch($this->getUrl(), $this->getPatchHeaders(), $json) + ->send(); + } +} diff --git a/lib/OpenCloud/CDN/Service.php b/lib/OpenCloud/CDN/Service.php new file mode 100644 index 000000000..57c880052 --- /dev/null +++ b/lib/OpenCloud/CDN/Service.php @@ -0,0 +1,188 @@ +resource('Service', $id); + } + + /** + * Creates a new Service and returns it. + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/CDN/USERGUIDE.md#create-a-service + * @param array $params Service creation parameters. + * @return \OpenCloud\CDN\Resource\Service Object representing created service + */ + public function createService(array $params = array()) + { + $service = $this->service(); + $service->create($params); + return $service; + } + + /** + * Returns a Service object associated with this CDN service + * + * @param string $id ID of service to retrieve + * @return \OpenCloud\CDN\Resource\Service object + */ + public function getService($id) + { + return $this->service($id); + } + + /** + * Returns a list of services you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listServices(array $params = array()) + { + $params['limit'] = isset($params['limit']) && $params['limit'] <= self::MAX_LIMIT ?: self::MAX_LIMIT; + + $url = clone $this->getUrl(); + $url->addPath(ServiceResource::resourceName())->setQuery($params); + + return $this->resourceList('Service', $url); + } + + /** + * Returns a Flavor object associated with this CDN service + * + * @param string $id ID of flavor to retrieve + * @return \OpenCloud\CDN\Resource\Flavor object + */ + public function flavor($id = null) + { + return $this->resource('Flavor', $id); + } + + /** + * Creates a new Flavor and returns it. + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/CDN/USERGUIDE.md#create-a-flavor + * @param array $params Flavor creation parameters. + * @return \OpenCloud\CDN\Resource\Flavor Object representing created flavor + */ + public function createFlavor(array $params = array()) + { + $flavor = $this->flavor(); + $flavor->create($params); + return $flavor; + } + + /** + * Returns a Flavor object associated with this CDN service + * + * @param string $id ID of flavor to retrieve + * @return \OpenCloud\CDN\Resource\Flavor object + */ + public function getFlavor($id) + { + return $this->flavor($id); + } + + /** + * Returns a list of flavors you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listFlavors(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Flavor::resourceName())->setQuery($params); + + return $this->resourceList('Flavor', $url); + } + + /** + * Returns the home document for the CDN service + * + * @return \stdClass home document response + */ + public function getHomeDocument() + { + $url = clone $this->getUrl(); + + // This hack is necessary otherwise Guzzle will remove the trailing + // slash from the URL and the request will fail because the service + // expects the trailing slash :( + $url->setPath($url->getPath() . '/'); + + $response = $this->getClient()->get($url)->send(); + return Formatter::decode($response); + } + + /** + * Returns the ping (status) response for the CDN service + * + * @return Guzzle\Http\Message\Response + */ + public function getPing() + { + $url = clone $this->getUrl(); + $url->addPath('ping'); + + $request = $this->getClient()->get($url); + + // This is necessary because the response does not include a body + // and fails with a 406 Not Acceptable if the default + // 'Accept: application/json' header is used in the request. + $request->removeHeader('Accept'); + + return $request->send(); + } + + /** + * Return namespaces. + * + * @return array + */ + public function namespaces() + { + return array(); + } +} diff --git a/lib/OpenCloud/CloudMonitoring/Collection/MonitoringIterator.php b/lib/OpenCloud/CloudMonitoring/Collection/MonitoringIterator.php index 3f348e2f4..0f629bf39 100644 --- a/lib/OpenCloud/CloudMonitoring/Collection/MonitoringIterator.php +++ b/lib/OpenCloud/CloudMonitoring/Collection/MonitoringIterator.php @@ -32,4 +32,4 @@ public function parseResponseBody($body) return $parsed; } -} \ No newline at end of file +} diff --git a/lib/OpenCloud/CloudMonitoring/Resource/Agent.php b/lib/OpenCloud/CloudMonitoring/Resource/Agent.php index a566dc83f..eead7c6f4 100644 --- a/lib/OpenCloud/CloudMonitoring/Resource/Agent.php +++ b/lib/OpenCloud/CloudMonitoring/Resource/Agent.php @@ -89,4 +89,4 @@ public function getAgentHost() { return $this->getService()->resource('AgentHost', null, $this); } -} \ No newline at end of file +} diff --git a/lib/OpenCloud/CloudMonitoring/Resource/AgentHost.php b/lib/OpenCloud/CloudMonitoring/Resource/AgentHost.php index 3e71c8a9f..b056c60c3 100644 --- a/lib/OpenCloud/CloudMonitoring/Resource/AgentHost.php +++ b/lib/OpenCloud/CloudMonitoring/Resource/AgentHost.php @@ -57,4 +57,4 @@ public function info($type) 'resourceClass' => 'AgentHostInfo' )); } -} \ No newline at end of file +} diff --git a/lib/OpenCloud/CloudMonitoring/Resource/AgentTarget.php b/lib/OpenCloud/CloudMonitoring/Resource/AgentTarget.php index 795bd4a1c..b5b85025b 100644 --- a/lib/OpenCloud/CloudMonitoring/Resource/AgentTarget.php +++ b/lib/OpenCloud/CloudMonitoring/Resource/AgentTarget.php @@ -24,7 +24,6 @@ */ class AgentTarget extends ReadOnlyResource { - private $type = 'agent.filesystem'; protected static $json_name = 'targets'; diff --git a/lib/OpenCloud/CloudMonitoring/Resource/ReadOnlyResource.php b/lib/OpenCloud/CloudMonitoring/Resource/ReadOnlyResource.php index 48f2c0329..4fd3681f3 100644 --- a/lib/OpenCloud/CloudMonitoring/Resource/ReadOnlyResource.php +++ b/lib/OpenCloud/CloudMonitoring/Resource/ReadOnlyResource.php @@ -24,7 +24,6 @@ */ class ReadOnlyResource extends AbstractResource { - public function create($params = array()) { return $this->noCreate(); diff --git a/lib/OpenCloud/Common/Base.php b/lib/OpenCloud/Common/Base.php index f0b0986ad..82bf0061b 100644 --- a/lib/OpenCloud/Common/Base.php +++ b/lib/OpenCloud/Common/Base.php @@ -32,6 +32,8 @@ */ abstract class Base { + const PATCH_CONTENT_TYPE = MimeConst::JSON_PATCH; + /** * Holds all the properties added by overloading. * @@ -110,7 +112,6 @@ protected function setProperty($property, $value) if (method_exists($this, $setter)) { return call_user_func(array($this, $setter), $value); } elseif (false !== ($propertyVal = $this->propertyExists($property))) { - // Are we setting a public or private property? if ($this->isAccessible($propertyVal)) { $this->$propertyVal = $value; @@ -120,7 +121,6 @@ protected function setProperty($property, $value) return $this; } else { - $this->getLogger()->warning( 'Attempted to set {property} with value {value}, but the' . ' property has not been defined. Please define first.', @@ -266,6 +266,14 @@ public function getLogger() return $this->logger; } + /** + * @return bool + */ + public function hasLogger() + { + return (null !== $this->logger); + } + /** * @deprecated */ @@ -284,15 +292,11 @@ public function url($path = null, array $query = array()) public function populate($info, $setObjects = true) { if (is_string($info) || is_integer($info)) { - $this->setProperty($this->primaryKeyField(), $info); $this->refresh($info); } elseif (is_object($info) || is_array($info)) { - foreach ($info as $key => $value) { - if ($key == 'metadata' || $key == 'meta') { - // Try retrieving existing value if (null === ($metadata = $this->getProperty($key))) { // If none exists, create new object @@ -305,10 +309,8 @@ public function populate($info, $setObjects = true) // Set object property $this->setProperty($key, $metadata); } elseif (!empty($this->associatedResources[$key]) && $setObjects === true) { - // Associated resource try { - $resource = $this->getService()->resource($this->associatedResources[$key], $value); $resource->setParent($this); @@ -316,10 +318,8 @@ public function populate($info, $setObjects = true) } catch (Exception\ServiceException $e) { } } elseif (!empty($this->associatedCollections[$key]) && $setObjects === true) { - // Associated collection try { - $className = $this->associatedCollections[$key]; $options = $this->makeResourceIteratorOptions($className); $iterator = ResourceIterator::factory($this, $options, $value); @@ -328,7 +328,6 @@ public function populate($info, $setObjects = true) } catch (Exception\ServiceException $e) { } } elseif (!empty($this->aliases[$key])) { - // Sometimes we might want to preserve camelCase // or covert `rax-bandwidth:bandwidth` to `raxBandwidth` $this->setProperty($this->aliases[$key], $value); @@ -430,4 +429,9 @@ protected static function getJsonHeader() { return array(HeaderConst::CONTENT_TYPE => MimeConst::JSON); } + + protected static function getPatchHeaders() + { + return array(HeaderConst::CONTENT_TYPE => static::PATCH_CONTENT_TYPE); + } } diff --git a/lib/OpenCloud/Common/Collection.php b/lib/OpenCloud/Common/Collection.php index 7d4990c55..f15e83c47 100644 --- a/lib/OpenCloud/Common/Collection.php +++ b/lib/OpenCloud/Common/Collection.php @@ -17,13 +17,14 @@ namespace OpenCloud\Common; +use OpenCloud\Common\Log\Logger; + /** * @deprecated * @codeCoverageIgnore */ class Collection extends Base { - private $service; private $itemClass; private $itemList = array(); @@ -51,7 +52,7 @@ class Collection extends Base */ public function __construct($service, $class, array $array = array()) { - $service->getLogger()->deprecated(__METHOD__, 'OpenCloud\Common\Collection\CollectionBuilder'); + $service->getLogger()->warning(Logger::deprecated(__METHOD__, 'OpenCloud\Common\Collection\CollectionBuilder')); $this->setService($service); diff --git a/lib/OpenCloud/Common/Collection/PaginatedIterator.php b/lib/OpenCloud/Common/Collection/PaginatedIterator.php index 7c202f0fb..ef827ac80 100644 --- a/lib/OpenCloud/Common/Collection/PaginatedIterator.php +++ b/lib/OpenCloud/Common/Collection/PaginatedIterator.php @@ -145,7 +145,11 @@ public function updateMarkerToCurrent() } $element = $this->elements[$this->position]; + $this->setMarkerFromElement($element); + } + protected function setMarkerFromElement($element) + { $key = $this->getOption('key.marker'); if (isset($element->$key)) { @@ -265,7 +269,6 @@ public function extractNextLink($body) public function constructNextUrl() { if (!$url = $this->nextUrl) { - $url = clone $this->getOption('baseUrl'); $query = $url->getQuery(); diff --git a/lib/OpenCloud/Common/Collection/ResourceIterator.php b/lib/OpenCloud/Common/Collection/ResourceIterator.php index 627ed78eb..c0054b8d1 100644 --- a/lib/OpenCloud/Common/Collection/ResourceIterator.php +++ b/lib/OpenCloud/Common/Collection/ResourceIterator.php @@ -223,7 +223,7 @@ public function getElement($offset) */ public function first() { - Logger::newInstance()->deprecated(__METHOD__, 'getElement'); + Logger::newInstance()->warning(Logger::deprecated(__METHOD__, 'getElement')); return $this->getElement(0); } diff --git a/lib/OpenCloud/Common/Constants/Header.php b/lib/OpenCloud/Common/Constants/Header.php index c0246f71f..5de04bc2a 100644 --- a/lib/OpenCloud/Common/Constants/Header.php +++ b/lib/OpenCloud/Common/Constants/Header.php @@ -70,4 +70,5 @@ class Header const USER_AGENT = 'User-Agent'; const VARY = 'Vary'; const VIA = 'Via'; + const X_OBJECT_MANIFEST = 'X-Object-Manifest'; } diff --git a/lib/OpenCloud/Common/Constants/Mime.php b/lib/OpenCloud/Common/Constants/Mime.php index 23df6cfe9..4e2942ebb 100644 --- a/lib/OpenCloud/Common/Constants/Mime.php +++ b/lib/OpenCloud/Common/Constants/Mime.php @@ -21,4 +21,5 @@ class Mime { const JSON = 'application/json'; const TEXT = 'text/plain'; + const JSON_PATCH = 'application/json-patch+json'; } diff --git a/lib/OpenCloud/Common/Constants/Service.php b/lib/OpenCloud/Common/Constants/Service.php index c61992fc7..636e535b5 100644 --- a/lib/OpenCloud/Common/Constants/Service.php +++ b/lib/OpenCloud/Common/Constants/Service.php @@ -19,6 +19,6 @@ class Service { - const INTERNAL_URL = 'publicUrl'; - const PUBLIC_URL = 'internalUrl'; + const INTERNAL_URL = 'internalUrl'; + const PUBLIC_URL = 'publicUrl'; } diff --git a/lib/OpenCloud/Common/Exceptions/BackupInstanceError.php b/lib/OpenCloud/Common/Exceptions/BackupInstanceError.php new file mode 100644 index 000000000..612d1fa2e --- /dev/null +++ b/lib/OpenCloud/Common/Exceptions/BackupInstanceError.php @@ -0,0 +1,22 @@ += %s installed.', - self::MINIMUM_PHP_VERSION - )); - } - // @codeCoverageIgnoreEnd - - parent::__construct($baseUrl, $config); - } - public function getDefaultUserAgent() { - return 'OpenCloud/' . self::VERSION - . ' cURL/' . CurlVersion::getInstance()->get('version') - . ' PHP/' . PHP_VERSION; + return 'OpenCloud/' . Version::getVersion() + . ' Guzzle/' . Version::getGuzzleVersion() + . ' cURL/' . Version::getCurlVersion() + . ' PHP/' . PHP_VERSION; } public function getUserAgent() diff --git a/lib/OpenCloud/Common/Http/Message/Formatter.php b/lib/OpenCloud/Common/Http/Message/Formatter.php index 0c6864029..1f2b8c2a4 100644 --- a/lib/OpenCloud/Common/Http/Message/Formatter.php +++ b/lib/OpenCloud/Common/Http/Message/Formatter.php @@ -24,7 +24,6 @@ class Formatter { - public static function decode(Response $response) { if (strpos($response->getHeader(Header::CONTENT_TYPE), Mime::JSON) !== false) { diff --git a/lib/OpenCloud/Common/Lang.php b/lib/OpenCloud/Common/Lang.php index bffdbffb0..7c124e5bc 100644 --- a/lib/OpenCloud/Common/Lang.php +++ b/lib/OpenCloud/Common/Lang.php @@ -19,7 +19,6 @@ class Lang { - public static function translate($word = null) { return $word; diff --git a/lib/OpenCloud/Common/Log/Logger.php b/lib/OpenCloud/Common/Log/Logger.php index c9de3ea3c..b054fc004 100644 --- a/lib/OpenCloud/Common/Log/Logger.php +++ b/lib/OpenCloud/Common/Log/Logger.php @@ -235,15 +235,16 @@ private function dispatch($message, $context) // Output to file file_put_contents($file, $this->formatFileLine($output), FILE_APPEND); } else { - echo $output; } } - public function deprecated($method, $new) + /** + * Helper method, use PSR-3 warning function for deprecation warnings + * @see http://www.php-fig.org/psr/psr-3/ + */ + public static function deprecated($method, $new) { - $string = sprintf('The %s method is deprecated, please use %s instead', $method, $new); - - return $this->warning($string); + return sprintf('The %s method is deprecated, please use %s instead', $method, $new); } -} \ No newline at end of file +} diff --git a/lib/OpenCloud/Common/Resource/BaseResource.php b/lib/OpenCloud/Common/Resource/BaseResource.php index 1a9c5e80e..76c48cf10 100644 --- a/lib/OpenCloud/Common/Resource/BaseResource.php +++ b/lib/OpenCloud/Common/Resource/BaseResource.php @@ -148,7 +148,6 @@ public function getMetadata() public function getUrl($path = null, array $query = array()) { if (!$url = $this->findLink('self')) { - // ...otherwise construct a URL from parent and this resource's // "URL name". If no name is set, resourceName() throws an error. $url = $this->getParent()->getUrl($this->resourceName()); diff --git a/lib/OpenCloud/Common/Resource/PersistentResource.php b/lib/OpenCloud/Common/Resource/PersistentResource.php index cb0ed8dc2..33aa1c398 100644 --- a/lib/OpenCloud/Common/Resource/PersistentResource.php +++ b/lib/OpenCloud/Common/Resource/PersistentResource.php @@ -25,6 +25,7 @@ use OpenCloud\Common\Exceptions\NameError; use OpenCloud\Common\Exceptions\UnsupportedExtensionError; use OpenCloud\Common\Exceptions\UpdateError; +use mikemccabe\JsonPatch\JsonPatch; abstract class PersistentResource extends BaseResource { @@ -132,6 +133,22 @@ public function refresh($id = null, $url = null) return $response; } + + /** + * Causes resource to refresh based on parent's URL + */ + protected function refreshFromParent() + { + $url = clone $this->getParent()->getUrl(); + $url->addPath($this->resourceName()); + + $response = $this->getClient()->get($url)->send(); + + if (null !== ($decoded = $this->parseResponse($response))) { + $this->populate($decoded); + } + } + /** * Given a `location` URL, refresh this resource * @@ -168,7 +185,6 @@ public function waitFor($state = null, $timeout = null, $callback = null, $inter $states = array('ERROR', $state); while (true) { - $this->refresh($this->getProperty($this->primaryKeyField())); if ($callback) { @@ -202,7 +218,7 @@ protected function createJson() foreach ($this->createKeys as $key) { if (null !== ($property = $this->getProperty($key))) { - $element->{$this->getAlias($key)} = $property; + $element->{$this->getAlias($key)} = $this->recursivelyAliasPropertyValue($property); } } @@ -229,12 +245,57 @@ protected function getAlias($key) return $key; } + /** + * Returns the given property value's alias, if configured; Else, the + * unchanged property value is returned. If the given property value + * is an array or an instance of \stdClass, it is aliases recursively. + * + * @param mixed $propertyValue Array or \stdClass instance to alias + * @return mixed Property value, aliased recursively + */ + protected function recursivelyAliasPropertyValue($propertyValue) + { + if (is_array($propertyValue)) { + foreach ($propertyValue as $key => $subValue) { + $aliasedSubValue = $this->recursivelyAliasPropertyValue($subValue); + if (is_numeric($key)) { + $propertyValue[$key] = $aliasedSubValue; + } else { + unset($propertyValue[$key]); + $propertyValue[$this->getAlias($key)] = $aliasedSubValue; + } + } + } elseif (is_object($propertyValue) && ($propertyValue instanceof \stdClass)) { + foreach (get_object_vars($propertyValue) as $key => $subValue) { + unset($propertyValue->$key); + $propertyValue->{$this->getAlias($key)} = $this->recursivelyAliasPropertyValue($subValue); + } + } + + return $propertyValue; + } + /** * Provides JSON for update request body */ protected function updateJson($params = array()) { - throw new UpdateError('updateJson() must be overriden in order for an update to happen'); + if (!isset($this->updateKeys)) { + throw new \RuntimeException(sprintf( + 'This resource object [%s] must have a visible updateKeys array', + get_class($this) + )); + } + + $element = (object) array(); + + foreach ($this->updateKeys as $key) { + if (null !== ($property = $this->getProperty($key))) { + $element->{$this->getAlias($key)} = $this->recursivelyAliasPropertyValue($property); + } + } + + return (object) array($this->jsonName() => (object) $element); } /** @@ -258,7 +319,7 @@ protected function noDelete() */ protected function noUpdate() { - throw new UpdateError('his resource does not support the update operation'); + throw new UpdateError('This resource does not support the update operation'); } /** @@ -277,6 +338,54 @@ public function checkExtension($alias) return true; } + /** + * Returns the object's properties as an array + */ + protected function getUpdateablePropertiesAsArray() + { + $properties = get_object_vars($this); + + $propertiesToKeep = array(); + foreach ($this->updateKeys as $key) { + if (isset($properties[$key])) { + $propertiesToKeep[$key] = $properties[$key]; + } + } + + return $propertiesToKeep; + } + + /** + * Generates a JSON Patch representation and return its + * + * @param mixed $updatedProperties Properties of the resource to update + * @return String JSON Patch representation for updates + */ + protected function generateJsonPatch($updatedProperties) + { + // Normalize current and updated properties into nested arrays + $currentProperties = json_decode(json_encode($this->getUpdateablePropertiesAsArray()), true); + $updatedProperties = json_decode(json_encode($updatedProperties), true); + + // Add any properties that haven't changed to generate the correct patch + // (otherwise unchanging properties are marked as removed in the patch) + foreach ($currentProperties as $key => $value) { + if (!array_key_exists($key, $updatedProperties)) { + $updatedProperties[$key] = $value; + } + } + + // Recursively alias current and updated properties + $currentProperties = $this->recursivelyAliasPropertyValue($currentProperties); + $updatedProperties = $this->recursivelyAliasPropertyValue($updatedProperties); + + // Generate JSON Patch representation + $json = json_encode(JsonPatch::diff($currentProperties, $updatedProperties)); + $this->checkJsonError(); + + return $json; + } + /******** DEPRECATED METHODS ********/ /** diff --git a/lib/OpenCloud/Common/Resource/ReadOnlyResource.php b/lib/OpenCloud/Common/Resource/ReadOnlyResource.php new file mode 100644 index 000000000..132136a2e --- /dev/null +++ b/lib/OpenCloud/Common/Resource/ReadOnlyResource.php @@ -0,0 +1,42 @@ +noCreate(); + } + + public function update($params = array()) + { + return $this->noUpdate(); + } + + public function delete() + { + return $this->noDelete(); + } +} diff --git a/lib/OpenCloud/Common/Service/CatalogItem.php b/lib/OpenCloud/Common/Service/CatalogItem.php index b55274762..d6bf956ee 100644 --- a/lib/OpenCloud/Common/Service/CatalogItem.php +++ b/lib/OpenCloud/Common/Service/CatalogItem.php @@ -134,14 +134,18 @@ public function getEndpoints() /** * Using a standard data object, extract its endpoint. * - * @param $region + * @param string $region + * @param bool $isRegionless + * * @return mixed * @throws \OpenCloud\Common\Exceptions\EndpointError */ - public function getEndpointFromRegion($region) + public function getEndpointFromRegion($region, $isRegionless = false) { foreach ($this->endpoints as $endpoint) { - if (!isset($endpoint->region) || $endpoint->region == $region) { + // Return the endpoint if it is regionless OR if the endpoint's + // region matches the $region supplied by the caller. + if ($isRegionless || !isset($endpoint->region) || $endpoint->region == $region) { return $endpoint; } } diff --git a/lib/OpenCloud/Common/Service/CatalogService.php b/lib/OpenCloud/Common/Service/CatalogService.php index f7baa6977..0e26405c5 100644 --- a/lib/OpenCloud/Common/Service/CatalogService.php +++ b/lib/OpenCloud/Common/Service/CatalogService.php @@ -20,13 +20,16 @@ use Guzzle\Http\ClientInterface; use Guzzle\Http\Exception\BadResponseException; use Guzzle\Http\Url; +use OpenCloud\Common\Base; use OpenCloud\Common\Exceptions; use OpenCloud\Common\Http\Message\Formatter; +use OpenCloud\OpenStack; use Symfony\Component\EventDispatcher\EventSubscriberInterface; abstract class CatalogService extends AbstractService { const DEFAULT_URL_TYPE = 'publicURL'; + const SUPPORTED_VERSION = null; /** * @var string The type of this service, as set in Catalog. @@ -44,7 +47,7 @@ abstract class CatalogService extends AbstractService private $region; /** - * @var string Either 'publicURL' or 'privateURL'. + * @var string Either 'publicURL' or 'internalURL'. */ private $urlType; @@ -66,10 +69,14 @@ abstract class CatalogService extends AbstractService * @param string $type Service type (e.g. 'compute') * @param string $name Service name (e.g. 'cloudServersOpenStack') * @param string $region Service region (e.g. 'DFW', 'ORD', 'IAD', 'LON', 'SYD' or 'HKG') - * @param string $urlType Either 'publicURL' or 'privateURL' + * @param string $urlType Either 'publicURL' or 'internalURL' */ public function __construct(ClientInterface $client, $type = null, $name = null, $region = null, $urlType = null) { + if (($client instanceof Base || $client instanceof OpenStack) && $client->hasLogger()) { + $this->setLogger($client->getLogger()); + } + $this->setClient($client); $this->name = $name ? : static::DEFAULT_NAME; @@ -208,7 +215,8 @@ private function findEndpoint() // Search each service to find The One foreach ($catalog->getItems() as $service) { if ($service->hasType($this->type) && $service->hasName($this->name)) { - return Endpoint::factory($service->getEndpointFromRegion($this->region)); + $endpoint = $service->getEndpointFromRegion($this->region, $this->regionless); + return Endpoint::factory($endpoint, static::SUPPORTED_VERSION, $this->getClient()); } } diff --git a/lib/OpenCloud/Common/Service/Endpoint.php b/lib/OpenCloud/Common/Service/Endpoint.php index e331ce334..2388dc258 100644 --- a/lib/OpenCloud/Common/Service/Endpoint.php +++ b/lib/OpenCloud/Common/Service/Endpoint.php @@ -18,6 +18,9 @@ namespace OpenCloud\Common\Service; use Guzzle\Http\Url; +use OpenCloud\OpenStack; +use OpenCloud\Common\Http\Message\Formatter; +use OpenCloud\Common\Exceptions\UnsupportedVersionError; /** * An endpoint serves as a location which receives and emits API interactions. It will therefore also host @@ -44,17 +47,19 @@ class Endpoint /** * @param $object + * @param string $supportedServiceVersion Service version supported by the SDK + * @param OpenCloud\OpenStack $client OpenStack client * @return Endpoint */ - public static function factory($object) + public static function factory($object, $supportedServiceVersion, OpenStack $client) { $endpoint = new self(); if (isset($object->publicURL)) { - $endpoint->setPublicUrl($object->publicURL); + $endpoint->setPublicUrl($endpoint->getVersionedUrl($object->publicURL, $supportedServiceVersion, $client)); } if (isset($object->internalURL)) { - $endpoint->setPrivateUrl($object->internalURL); + $endpoint->setPrivateUrl($endpoint->getVersionedUrl($object->internalURL, $supportedServiceVersion, $client)); } if (isset($object->region)) { $endpoint->setRegion($object->region); @@ -67,9 +72,9 @@ public static function factory($object) * @param $publicUrl * @return $this */ - public function setPublicUrl($publicUrl) + public function setPublicUrl(Url $publicUrl) { - $this->publicUrl = Url::factory($publicUrl); + $this->publicUrl = $publicUrl; return $this; } @@ -86,9 +91,9 @@ public function getPublicUrl() * @param $privateUrl * @return $this */ - public function setPrivateUrl($privateUrl) + public function setPrivateUrl(Url $privateUrl) { - $this->privateUrl = Url::factory($privateUrl); + $this->privateUrl = $privateUrl; return $this; } @@ -119,4 +124,54 @@ public function getRegion() { return $this->region; } + + /** + * Returns the endpoint URL with a version in it + * + * @param string $url Endpoint URL + * @param string $supportedServiceVersion Service version supported by the SDK + * @param OpenCloud\OpenStack $client OpenStack client + * @return Guzzle/Http/Url Endpoint URL with version in it + */ + private function getVersionedUrl($url, $supportedServiceVersion, OpenStack $client) + { + $versionRegex = '/\/[vV][0-9][0-9\.]*/'; + if (1 === preg_match($versionRegex, $url)) { + // URL has version in it; use it as-is + return Url::factory($url); + } + + // If there is no version in $url but no $supportedServiceVersion + // is specified, just return $url as-is but log a warning + if (is_null($supportedServiceVersion)) { + $client->getLogger()->warning('Service version supported by SDK not specified. Using versionless service URL as-is, without negotiating version.'); + return Url::factory($url); + } + + // Make GET request to URL + $response = Formatter::decode($client->get($url)->send()); + + // Attempt to parse response and determine URL for given $version + if (!isset($response->versions) || !is_array($response->versions)) { + throw new UnsupportedVersionError('Could not negotiate version with service.'); + } + + foreach ($response->versions as $version) { + if (($version->status == 'CURRENT' || $version->status == 'SUPPORTED') + && $version->id == $supportedServiceVersion) { + foreach ($version->links as $link) { + if ($link->rel == 'self') { + return Url::factory($link->href); + } + } + } + } + + // If we've reached this point, we could not find a versioned + // URL in the response; throw an error + throw new UnsupportedVersionError(sprintf( + 'SDK supports version %s which is not currently provided by service.', + $supportedServiceVersion + )); + } } diff --git a/lib/OpenCloud/Common/Service/NovaService.php b/lib/OpenCloud/Common/Service/NovaService.php index e3fb1a894..e03508ad4 100644 --- a/lib/OpenCloud/Common/Service/NovaService.php +++ b/lib/OpenCloud/Common/Service/NovaService.php @@ -24,7 +24,6 @@ */ abstract class NovaService extends CatalogService { - /** * Returns a flavor from the service * diff --git a/lib/OpenCloud/Common/Service/ServiceBuilder.php b/lib/OpenCloud/Common/Service/ServiceBuilder.php index 3fa394ea9..99747e900 100644 --- a/lib/OpenCloud/Common/Service/ServiceBuilder.php +++ b/lib/OpenCloud/Common/Service/ServiceBuilder.php @@ -25,7 +25,6 @@ */ class ServiceBuilder { - /** * Simple factory method for creating services. * @@ -38,6 +37,7 @@ class ServiceBuilder public static function factory(ClientInterface $client, $class, array $options = array()) { $name = isset($options['name']) ? $options['name'] : null; + $type = isset($options['type']) ? $options['type'] : null; $urlType = isset($options['urlType']) ? $options['urlType'] : null; if (isset($options['region'])) { @@ -48,6 +48,6 @@ public static function factory(ClientInterface $client, $class, array $options = $region = null; } - return new $class($client, null, $name, $region, $urlType); + return new $class($client, $type, $name, $region, $urlType); } } diff --git a/lib/OpenCloud/Compute/Resource/Flavor.php b/lib/OpenCloud/Compute/Resource/Flavor.php index 13c55bbb5..b21a1fe97 100644 --- a/lib/OpenCloud/Compute/Resource/Flavor.php +++ b/lib/OpenCloud/Compute/Resource/Flavor.php @@ -25,7 +25,6 @@ */ class Flavor extends PersistentObject { - public $status; public $updated; public $vcpus; diff --git a/lib/OpenCloud/Compute/Resource/Network.php b/lib/OpenCloud/Compute/Resource/Network.php index c2fefd016..8b041df97 100644 --- a/lib/OpenCloud/Compute/Resource/Network.php +++ b/lib/OpenCloud/Compute/Resource/Network.php @@ -19,16 +19,16 @@ use Guzzle\Http\Url; use OpenCloud\Common\Exceptions; -use OpenCloud\Common\PersistentObject; +use OpenCloud\Common\Resource\PersistentResource; use OpenCloud\Compute\Constants\Network as NetworkConst; use OpenCloud\Compute\Service; +use OpenCloud\Networking\Resource\NetworkInterface; /** * The Network class represents a single virtual network */ -class Network extends PersistentObject +class Network extends PersistentResource implements NetworkInterface { - public $id; public $label; public $cidr; @@ -128,7 +128,6 @@ protected function createJson() public function getUrl($path = null, array $query = array()) { if (!$url = $this->findLink('self')) { - $url = $this->getParent()->getUrl($this->getResourcePath()); if (null !== ($primaryKey = $this->getProperty($this->primaryKeyField()))) { @@ -156,4 +155,9 @@ public function getResourcePath() return self::$openStackResourcePath; } } + + public function getId() + { + return $this->id; + } } diff --git a/lib/OpenCloud/Compute/Resource/Server.php b/lib/OpenCloud/Compute/Resource/Server.php index c1bce2a18..9038c291d 100644 --- a/lib/OpenCloud/Compute/Resource/Server.php +++ b/lib/OpenCloud/Compute/Resource/Server.php @@ -20,6 +20,9 @@ use OpenCloud\Common\Resource\NovaResource; use OpenCloud\DNS\Resource\HasPtrRecordsInterface; use OpenCloud\Image\Resource\ImageInterface; +use OpenCloud\Networking\Resource\NetworkInterface; +use OpenCloud\Networking\Resource\SecurityGroup; +use OpenCloud\Networking\Resource\Port; use OpenCloud\Volume\Resource\Volume; use OpenCloud\Common\Exceptions; use OpenCloud\Common\Http\Message\Formatter; @@ -31,7 +34,7 @@ * A virtual machine (VM) instance in the Cloud Servers environment. * * @note This implementation supports extension attributes OS-DCF:diskConfig, - * RAX-SERVER:bandwidth, rax-bandwidth:bandwith. + * RAX-SERVER:bandwidth, rax-bandwidth:bandwidth. */ class Server extends NovaResource implements HasPtrRecordsInterface { @@ -102,6 +105,12 @@ class Server extends NovaResource implements HasPtrRecordsInterface */ public $networks = array(); + /** + * Security groups for this server. An array of either the names or SecurityGroup objects. + * @var (string|SecurityGroup)[] + */ + public $security_groups = array(); + /** * @var string The server ID. */ @@ -171,6 +180,12 @@ class Server extends NovaResource implements HasPtrRecordsInterface */ public $powerStatus; + /** + * @link http://developer.openstack.org/api-ref-compute-v2-ext.html#ext-os-ext-az + * @var string Availability zone of the VM + */ + public $availabilityZone; + protected static $json_name = 'server'; protected static $url_resource = 'servers'; @@ -205,6 +220,7 @@ class Server extends NovaResource implements HasPtrRecordsInterface 'OS-EXT-STS:vm_state' => 'extendedStatus', 'OS-EXT-STS:task_state' => 'taskStatus', 'OS-EXT-STS:power_state' => 'powerStatus', + 'OS-EXT-AZ:availability_zone' => 'availabilityZone' ); /** @@ -664,7 +680,6 @@ protected function createJson() // Boot from volume if ($this->volume instanceof Volume) { - $this->checkExtension('os-block-device-mapping-v2-boot'); $server->block_device_mapping_v2 = array(); @@ -675,31 +690,46 @@ protected function createJson() 'boot_index' => 0, 'delete_on_termination' => (boolean) $this->volumeDeleteOnTermination ); - } // Networks if (is_array($this->networks) && count($this->networks)) { - $server->networks = array(); foreach ($this->networks as $network) { - if (!$network instanceof Network) { + if ($network instanceof NetworkInterface) { + $server->networks[] = (object) array('uuid' => $network->getId()); + } elseif ($network instanceof Port) { + $server->networks[] = (object) array('port' => $network->getId()); + } else { throw new Exceptions\InvalidParameterError(sprintf( 'When creating a server, the "networks" key must be an ' . - 'array of OpenCloud\Compute\Network objects with valid ' . - 'IDs; variable passed in was a [%s]', + 'array of objects which implement either OpenCloud\Networking\Resource\NetworkInterface ' . + 'or OpenCloud\Networking\Resource\Port. The variable you passed in was a [%s]', gettype($network) )); } - if (empty($network->id)) { - $this->getLogger()->warning('When creating a server, the ' - . 'network objects passed in must have an ID' - ); - continue; + } + } + + // Security groups + if (is_array($this->security_groups) && count($this->security_groups)) { + $server->security_groups = array(); + + foreach ($this->security_groups as $security_group) { + if ($security_group instanceof SecurityGroup) { + $securityGroupName = $security_group->name(); + } elseif (is_string($security_group)) { + $securityGroupName = $security_group; + } else { + throw new Exceptions\InvalidParameterError(sprintf( + 'When creating a server, the "security_groups" key must be an ' . + 'array of strings or objects of type OpenCloud\Networking\Resource\SecurityGroup;' . + 'variable passed in was a [%s]', + gettype($security_group) + )); } - // Stock networks array - $server->networks[] = (object) array('uuid' => $network->id); + $server->security_groups[] = (object) array('name' => $securityGroupName); } } @@ -731,6 +761,12 @@ protected function createJson() $server->user_data = $this->user_data; } + // Availability zone + if (!empty($this->availabilityZone)) { + $this->checkExtension('OS-EXT-AZ'); + $server->availability_zone = $this->availabilityZone; + } + return (object) array('server' => $server); } @@ -738,4 +774,101 @@ protected function updateJson($params = array()) { return (object) array('server' => (object) $params); } + + /** + * Suspend a server + * + * A suspend request suspend an instance, its VM state is stored on disk, all memory is written + * to disk, and the virtual machine is stopped. Suspending an instance is similar to placing a + * device in hibernation; memory and vCPUs become available to create other instances. + * + * @api + * @return \Guzzle\Http\Message\Response + */ + public function suspend() + { + // The suspend action is only available when the os-admin-actions extension is installed. + $this->checkExtension('os-admin-actions'); + + $object = (object) array('suspend' => 'none'); + + return $this->action($object); + } + + /** + * Resume a server + * + * A resume request resumes a suspended instance, its VM state was stored on disk, all memory was written + * to disk, and the virtual machine was stopped. Resuming a suspended instance is similar to resuming a + * device from hibernation. + * + * @api + * @return \Guzzle\Http\Message\Response + */ + public function resume() + { + // The resume action is only available when the os-admin-actions extension is installed. + $this->checkExtension('os-admin-actions'); + + $object = (object) array('resume' => 'none'); + + return $this->action($object); + } + + /** + * Get server diagnostics + * + * Gets basic usage data for a specified server. + * + * @api + * @return object + */ + public function diagnostics() + { + // The diagnostics is only available when the os-server-diagnostics extension is installed. + $this->checkExtension('os-server-diagnostics'); + + $url = $this->getUrl('diagnostics'); + + $response = $this->getClient()->get($url)->send(); + $body = Formatter::decode($response); + + return $body ?: (object) array(); + } + + /** + * Start a server + * + * Starts a stopped server and changes its status to ACTIVE. + * + * @api + * @return \Guzzle\Http\Message\Response + */ + public function start() + { + // The start action is only available when the os-server-start-stop extension is installed. + $this->checkExtension('os-server-start-stop'); + + $object = (object) array('os-start' => null); + + return $this->action($object); + } + + /** + * Stop a server + * + * Stops a running server and changes its status to STOPPED. + * + * @api + * @return \Guzzle\Http\Message\Response + */ + public function stop() + { + // The stop action is only available when the os-server-start-stop extension is installed. + $this->checkExtension('os-server-start-stop'); + + $object = (object) array('os-stop' => null); + + return $this->action($object); + } } diff --git a/lib/OpenCloud/Compute/Resource/ServerMetadata.php b/lib/OpenCloud/Compute/Resource/ServerMetadata.php index 11d851f99..203e2d63a 100644 --- a/lib/OpenCloud/Compute/Resource/ServerMetadata.php +++ b/lib/OpenCloud/Compute/Resource/ServerMetadata.php @@ -38,7 +38,7 @@ class ServerMetadata extends Metadata private $url; // the URL of this particular metadata item or block /** - * Contructs a Metadata object associated with a Server or Image object + * Constructs a Metadata object associated with a Server or Image object * * @param object $parent either a Server or an Image object * @param string $key the (optional) key for the metadata item @@ -51,7 +51,6 @@ public function __construct(Server $parent, $key = null) // set the URL according to whether or not we have a key if ($this->getParent()->getId()) { - $this->url = $this->getParent()->url('metadata'); $this->key = $key; @@ -180,10 +179,7 @@ private function getMetadataJson() if ($name = $this->key) { $object->meta->$name = $this->$name; } else { - $object->metadata = new \stdClass(); - foreach ($this->keylist() as $key) { - $object->metadata->$key = (string) $this->$key; - } + $object->metadata = $this->keylist(); } $json = json_encode($object); diff --git a/lib/OpenCloud/Compute/Resource/VolumeAttachment.php b/lib/OpenCloud/Compute/Resource/VolumeAttachment.php index 3caa28867..07892942c 100644 --- a/lib/OpenCloud/Compute/Resource/VolumeAttachment.php +++ b/lib/OpenCloud/Compute/Resource/VolumeAttachment.php @@ -26,7 +26,6 @@ */ class VolumeAttachment extends PersistentObject { - public $id; public $device; public $serverId; diff --git a/lib/OpenCloud/Compute/Service.php b/lib/OpenCloud/Compute/Service.php index d34f6101a..37d66a036 100644 --- a/lib/OpenCloud/Compute/Service.php +++ b/lib/OpenCloud/Compute/Service.php @@ -81,7 +81,7 @@ public function __construct(Client $client, $type = null, $name = null, $region * * @api * @param string $id - if specified, the server with the ID is retrieved - * @returns Resource\Server object + * @return Resource\Server object */ public function server($id = null) { @@ -102,7 +102,7 @@ public function server($id = null) * not having all the information you need. * @param array $filter - a set of key/value pairs that is passed to the * servers list for filtering - * @returns \OpenCloud\Common\Collection + * @return \OpenCloud\Common\Collection\PaginatedIterator */ public function serverList($details = true, array $filter = array()) { @@ -128,7 +128,7 @@ public function network($id = null) * * @api * @param array $filter array of filter key/value pairs - * @return \OpenCloud\Common\Collection + * @return \OpenCloud\Common\Collection\PaginatedIterator */ public function networkList($filter = array()) { diff --git a/lib/OpenCloud/DNS/Resource/AsyncResponse.php b/lib/OpenCloud/DNS/Resource/AsyncResponse.php index 97e04808a..952aa1642 100644 --- a/lib/OpenCloud/DNS/Resource/AsyncResponse.php +++ b/lib/OpenCloud/DNS/Resource/AsyncResponse.php @@ -118,7 +118,6 @@ public function waitFor($state = null, $timeout = null, $callback = null, $inter $states = array('ERROR', $state); while ($continue) { - $body = $this->getClient()->get($jobUrl)->send()->json(); if ($callback) { diff --git a/lib/OpenCloud/DNS/Resource/Domain.php b/lib/OpenCloud/DNS/Resource/Domain.php index 9a3f7e004..a103677f5 100644 --- a/lib/OpenCloud/DNS/Resource/Domain.php +++ b/lib/OpenCloud/DNS/Resource/Domain.php @@ -76,7 +76,7 @@ public function record($info = null) * returns a Collection of Record objects * * @param array $filter query-string parameters - * @return \OpenCloud\Collection + * @return OpenCloud\DNS\Collection\DnsIterator */ public function recordList($filter = array()) { @@ -107,6 +107,7 @@ public function subdomain($info = array()) * * @param array $filter key/value pairs for query string parameters * return \OpenCloud\Collection + * @return OpenCloud\DNS\Collection\DnsIterator */ public function subdomainList($filter = array()) { @@ -224,7 +225,6 @@ protected function createJson() // add records, if any if (count($this->records)) { - $recordsObject = (object) array('records' => array()); foreach ($this->records as $record) { @@ -241,7 +241,6 @@ protected function createJson() // add subdomains, if any if (count($this->subdomains)) { - $subdomainsObject = (object) array('domains' => array()); foreach ($this->subdomains as $subdomain) { diff --git a/lib/OpenCloud/DNS/Service.php b/lib/OpenCloud/DNS/Service.php index cafb4ad94..651353e14 100644 --- a/lib/OpenCloud/DNS/Service.php +++ b/lib/OpenCloud/DNS/Service.php @@ -19,6 +19,7 @@ use OpenCloud\Common\Http\Message\Formatter; use OpenCloud\Common\Service\CatalogService; +use OpenCloud\Common\Exceptions\DomainNotFoundException; use OpenCloud\DNS\Collection\DnsIterator; use OpenCloud\DNS\Resource\AsyncResponse; use OpenCloud\DNS\Resource\Domain; @@ -55,11 +56,29 @@ public function domain($info = null) return $this->resource('Domain', $info); } + /** + * Returns a domain, given a domain name + * + * @param string $domainName Domain name + * @return Domain the domain object + */ + public function domainByName($domainName) + { + $domainList = $this->domainList(array("name" => $domainName)); + + if (count($domainList) != 1) { + throw new DomainNotFoundException(); + } + + return $this->resource('Domain', $domainList[0]); + } + + /** * Returns a collection of domains * * @param array $filter key/value pairs to use as query strings - * @return \OpenCloud\Common\Collection + * @return OpenCloud\DNS\Collection\DnsIterator */ public function domainList($filter = array()) { @@ -85,7 +104,7 @@ public function ptrRecord($info = null) * * @param \OpenCloud\Compute\Resource\Server $server the server for which to * retrieve the PTR records - * @return \OpenCloud\Common\Collection + * @return OpenCloud\DNS\Collection\DnsIterator */ public function ptrRecordList(HasPtrRecordsInterface $parent) { @@ -181,6 +200,13 @@ public function limitTypes() return $body->limitTypes; } + /** + * List asynchronous responses' statuses. + * @see http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/viewing_status_all_asynch_jobs.html + * + * @param array $query Any query parameters. Optional. + * @return OpenCloud\DNS\Collection\DnsIterator + */ public function listAsyncJobs(array $query = array()) { $url = clone $this->getUrl(); diff --git a/lib/OpenCloud/Database/Resource/Backup.php b/lib/OpenCloud/Database/Resource/Backup.php new file mode 100644 index 000000000..97b015398 --- /dev/null +++ b/lib/OpenCloud/Database/Resource/Backup.php @@ -0,0 +1,92 @@ + 'Instance' + ); + + protected $aliases = array( + 'instance_id' => 'instanceId' + ); + + public function __construct(Service $service, $info = null) + { + $this->instance = new \stdClass; + return parent::__construct($service, $info); + } + + /** + * Returns the JSON object for creating the backup + */ + protected function createJson() + { + if (!isset($this->instanceId)) { + throw new Exceptions\BackupInstanceError( + Lang::translate('The `instanceId` attribute is required and must be a string') + ); + } + + if (!isset($this->name)) { + throw new Exceptions\BackupNameError( + Lang::translate('Backup name is required') + ); + } + + $out = [ + 'backup' => [ + 'name' => $this->name, + 'instance' => $this->instanceId + ] + ]; + + if (isset($this->description)) { + $out['backup']['description'] = $this->description; + } + return (object) $out; + } +} diff --git a/lib/OpenCloud/Database/Resource/Datastore.php b/lib/OpenCloud/Database/Resource/Datastore.php index dadfe2915..3123fc740 100644 --- a/lib/OpenCloud/Database/Resource/Datastore.php +++ b/lib/OpenCloud/Database/Resource/Datastore.php @@ -36,7 +36,7 @@ class Datastore extends PersistentResource protected static $url_resource = 'datastores'; protected $associatedCollections = array( - 'version' => 'DatastoreVersion' + 'version' => 'DatastoreVersion' ); /** diff --git a/lib/OpenCloud/Database/Resource/Instance.php b/lib/OpenCloud/Database/Resource/Instance.php index 83262ddd6..e7f09fddf 100644 --- a/lib/OpenCloud/Database/Resource/Instance.php +++ b/lib/OpenCloud/Database/Resource/Instance.php @@ -39,6 +39,7 @@ class Instance extends NovaResource public $created; public $updated; public $flavor; + public $backupRef; protected static $json_name = 'instance'; protected static $url_resource = 'instances'; @@ -171,6 +172,49 @@ public function userList() return $this->getService()->resourceList('User', $this->getUrl('users'), $this); } + /** + * Returns a Collection of all backups for the instance + * + * @return OpenCloud\Common\Collection\PaginatedIterator + */ + public function backupList() + { + return $this->getService()->resourceList('Backup', $this->getUrl('backups'), $this); + } + + /** + * Creates a backup for the given instance + * + * @api + * @param array $params - an associate array of key/value pairs + * name is required + * description is optional + * @return Backup + */ + public function createBackup($params = array()) + { + if (!isset($params['instanceId'])) { + $params['instanceId'] = $this->id; + } + + $backup = new Backup($this->getService(), $params); + $backup->create($params); + return $backup; + } + + public function populate($info, $setObjects = true) + { + parent::populate($info, $setObjects); + + if (is_object($info)) { + $info = (array) $info; + } + + if (isset($info['restorePoint']['backupRef'])) { + $this->backupRef = $info['restorePoint']['backupRef']; + } + } + /** * Generates the JSON string for Create() * @@ -190,13 +234,21 @@ protected function createJson() ); } - return (object) array( - 'instance' => (object) array( + $out = [ + 'instance' => [ 'flavorRef' => $this->flavor->links[0]->href, 'name' => $this->name, 'volume' => $this->volume - ) - ); + ] + ]; + + if (isset($this->backupRef)) { + $out['instance']['restorePoint'] = [ + 'backupRef' => $this->backupRef + ]; + } + + return (object) $out; } /** diff --git a/lib/OpenCloud/Database/Resource/User.php b/lib/OpenCloud/Database/Resource/User.php index d1f66b181..8939fa003 100644 --- a/lib/OpenCloud/Database/Resource/User.php +++ b/lib/OpenCloud/Database/Resource/User.php @@ -152,4 +152,29 @@ protected function createJson() 'users' => array($user) ); } + + /** + * Grant access to a set of one or more databases to a user. + * + * @param []string $databases An array of one or more database names that this user will be granted access to. For + * example, ['foo', 'bar'] or ['baz'] are valid inputs. + * + * @return \Guzzle\Http\Message\Response + */ + public function grantDbAccess(array $databases) + { + $json = []; + + foreach ($databases as $database) { + $json[] = ['name' => $database]; + } + + $json = ['databases' => $json]; + + $url = $this->getUrl('databases'); + $headers = self::getJsonHeader(); + $body = json_encode($json); + + return $this->getClient()->put($url, $headers, $body)->send(); + } } diff --git a/lib/OpenCloud/Database/Service.php b/lib/OpenCloud/Database/Service.php index dd63a60f1..31504d208 100644 --- a/lib/OpenCloud/Database/Service.php +++ b/lib/OpenCloud/Database/Service.php @@ -17,10 +17,12 @@ namespace OpenCloud\Database; +use Guzzle\Http\ClientInterface; use OpenCloud\Common\Service\NovaService; use OpenCloud\Database\Resource\Instance; use OpenCloud\Database\Resource\Configuration; use OpenCloud\Database\Resource\Datastore; +use OpenCloud\Database\Resource\Backup; /** * The Rackspace Database service @@ -104,4 +106,29 @@ public function datastoreList($params = array()) return $this->resourceList('Datastore', $url); } + + /** + * Returns a Backup + * + * @param string $id the ID of the backup to retrieve + * @return \OpenCloud\Database\Resource\Backup + */ + public function backup($id = null) + { + return $this->resource('Backup', $id); + } + + /** + * Returns a Collection of Backup objects + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function backupList($params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Backup::resourceName())->setQuery($params); + + return $this->resourceList('Backup', $url); + } } diff --git a/lib/OpenCloud/Identity/Constants/User.php b/lib/OpenCloud/Identity/Constants/User.php index efa58f085..2d944d4ab 100644 --- a/lib/OpenCloud/Identity/Constants/User.php +++ b/lib/OpenCloud/Identity/Constants/User.php @@ -19,7 +19,6 @@ class User { - const MODE_NAME = 'name'; const MODE_EMAIL = 'email'; const MODE_ID = 'id'; diff --git a/lib/OpenCloud/Identity/Resource/User.php b/lib/OpenCloud/Identity/Resource/User.php index 404496652..736fbd09f 100644 --- a/lib/OpenCloud/Identity/Resource/User.php +++ b/lib/OpenCloud/Identity/Resource/User.php @@ -20,6 +20,7 @@ use OpenCloud\Common\Collection\PaginatedIterator; use OpenCloud\Common\Http\Message\Formatter; use OpenCloud\Common\PersistentObject; +use OpenCloud\Rackspace; /** * User class which encapsulates functionality for a user. @@ -68,6 +69,18 @@ class User extends PersistentObject protected static $url_resource = 'users'; protected static $json_name = 'user'; + public function createJson() + { + $json = parent::createJson(); + + if ($this->getClient() instanceof Rackspace) { + $json->user->username = $json->user->name; + unset($json->user->name); + } + + return $json; + } + /** * @param $region Set the default region */ diff --git a/lib/OpenCloud/Identity/Service.php b/lib/OpenCloud/Identity/Service.php index d0f3064e4..4e34f1e24 100644 --- a/lib/OpenCloud/Identity/Service.php +++ b/lib/OpenCloud/Identity/Service.php @@ -18,11 +18,13 @@ namespace OpenCloud\Identity; use Guzzle\Http\ClientInterface; +use OpenCloud\Common\Base; use OpenCloud\Common\Collection\PaginatedIterator; use OpenCloud\Common\Collection\ResourceIterator; use OpenCloud\Common\Http\Message\Formatter; use OpenCloud\Common\Service\AbstractService; use OpenCloud\Identity\Constants\User as UserConst; +use OpenCloud\OpenStack; /** * Class responsible for working with Rackspace's Cloud Identity service. @@ -31,7 +33,6 @@ */ class Service extends AbstractService { - /** * Factory method which allows for easy service creation * @@ -41,6 +42,11 @@ class Service extends AbstractService public static function factory(ClientInterface $client) { $identity = new self(); + + if (($client instanceof Base || $client instanceof OpenStack) && $client->hasLogger()) { + $identity->setLogger($client->getLogger()); + } + $identity->setClient($client); $identity->setEndpoint(clone $client->getAuthUrl()); diff --git a/lib/OpenCloud/Image/Resource/Image.php b/lib/OpenCloud/Image/Resource/Image.php index a10a4e12e..f24eb510b 100644 --- a/lib/OpenCloud/Image/Resource/Image.php +++ b/lib/OpenCloud/Image/Resource/Image.php @@ -35,6 +35,8 @@ class Image extends AbstractSchemaResource implements ImageInterface protected static $json_name = ''; protected static $json_collection_name = 'images'; + const PATCH_CONTENT_TYPE = 'application/openstack-images-v2.1-json-patch'; + /** * Update this resource * @@ -50,7 +52,6 @@ public function update(array $params, Schema $schema = null) $document = new JsonDocument(); foreach ($params as $propertyName => $value) { - // find property object if (!($property = $schema->getProperty($propertyName))) { // check whether additional properties are found @@ -86,7 +87,7 @@ public function update(array $params, Schema $schema = null) $body = $document->toString(); return $this->getClient() - ->patch($this->getUrl(), $this->getService()->getPatchHeaders(), $body) + ->patch($this->getUrl(), $this->getPatchHeaders(), $body) ->send(); } diff --git a/lib/OpenCloud/Image/Resource/JsonPatch/Operation.php b/lib/OpenCloud/Image/Resource/JsonPatch/Operation.php index e5845c46c..583e4ee9f 100644 --- a/lib/OpenCloud/Image/Resource/JsonPatch/Operation.php +++ b/lib/OpenCloud/Image/Resource/JsonPatch/Operation.php @@ -75,7 +75,7 @@ public static function factory(Schema $schema, Property $property, $operationTyp */ public function setType($type) { - $this->type = $type; + $this->type = $type; } /** diff --git a/lib/OpenCloud/Image/Service.php b/lib/OpenCloud/Image/Service.php index 86462c8d6..f0ed4d72a 100644 --- a/lib/OpenCloud/Image/Service.php +++ b/lib/OpenCloud/Image/Service.php @@ -17,7 +17,6 @@ namespace OpenCloud\Image; -use OpenCloud\Common\Constants\Header; use OpenCloud\Common\Service\CatalogService; use OpenCloud\Image\Resource\Image; use OpenCloud\Image\Resource\Schema\Schema; @@ -32,18 +31,6 @@ class Service extends CatalogService const DEFAULT_TYPE = 'image'; const DEFAULT_NAME = 'cloudImages'; - const PATCH_CONTENT_TYPE = 'application/openstack-images-v2.1-json-patch'; - - /** - * Get the default headers to send for PATCH requests - * - * @return array - */ - public function getPatchHeaders() - { - return array(Header::CONTENT_TYPE => self::PATCH_CONTENT_TYPE); - } - /** * This operation returns images you created, shared images that you accepted, and standard images. * diff --git a/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php new file mode 100644 index 000000000..7febf1af3 --- /dev/null +++ b/lib/OpenCloud/LoadBalancer/Collection/LoadBalancerIterator.php @@ -0,0 +1,39 @@ +getQuery(); + $query['limit'] = $query['limit'] + 1; + $url->setQuery($query); + + return $url; + } + + public function updateMarkerToCurrent() + { + $this->setMarkerFromElement($this->nextElement); + } + + public function parseResponseBody($body) + { + $response = parent::parseResponseBody($body); + + if (count($response) >= $this->getOption('limit.page')) { + // Pop last element and save (we will need it for the next marker) + $this->nextElement = array_pop($response); + } + + return $response; + } +} diff --git a/lib/OpenCloud/LoadBalancer/Resource/AbstractResource.php b/lib/OpenCloud/LoadBalancer/Resource/AbstractResource.php index feb1c446f..42521326f 100644 --- a/lib/OpenCloud/LoadBalancer/Resource/AbstractResource.php +++ b/lib/OpenCloud/LoadBalancer/Resource/AbstractResource.php @@ -40,21 +40,6 @@ public function refresh($id = null, $url = null) } } - /** - * Causes resource to refresh based on parent's URL - */ - protected function refreshFromParent() - { - $url = clone $this->getParent()->getUrl(); - $url->addPath($this->resourceName()); - - $response = $this->getClient()->get($url)->send(); - - if (null !== ($decoded = $this->parseResponse($response))) { - $this->populate($decoded); - } - } - protected function createJson() { $object = new \stdClass; diff --git a/lib/OpenCloud/LoadBalancer/Resource/CertificateMapping.php b/lib/OpenCloud/LoadBalancer/Resource/CertificateMapping.php new file mode 100644 index 000000000..834bfd4a6 --- /dev/null +++ b/lib/OpenCloud/LoadBalancer/Resource/CertificateMapping.php @@ -0,0 +1,109 @@ +certificateMapping = new \stdClass(); + foreach ($params as $name => $value) { + if (!in_array($name, $updateFields)) { + throw new InvalidArgumentError("You cannot update ${name}."); + } + $object->certificateMapping->$name = $this->$name; + } + + return $object; + } + + /** + * Sets properties from array || object of $values + * + * Used by LoadBalancer::certificateMappingList's paginated iterator + * to return CertificateMappings with a valid id and hostname + * + * @var array|object $values + */ + protected function setCertificateMapping($values) + { + $this->populate($values); + } +} diff --git a/lib/OpenCloud/LoadBalancer/Resource/LoadBalancer.php b/lib/OpenCloud/LoadBalancer/Resource/LoadBalancer.php index 3c6454cee..551198c1b 100644 --- a/lib/OpenCloud/LoadBalancer/Resource/LoadBalancer.php +++ b/lib/OpenCloud/LoadBalancer/Resource/LoadBalancer.php @@ -18,6 +18,7 @@ namespace OpenCloud\LoadBalancer\Resource; use OpenCloud\Common\Exceptions; +use OpenCloud\Common\Log\Logger; use OpenCloud\Common\Resource\PersistentResource; use OpenCloud\DNS\Resource\HasPtrRecordsInterface; use OpenCloud\LoadBalancer\Enum\NodeCondition; @@ -150,6 +151,7 @@ class LoadBalancer extends PersistentResource implements HasPtrRecordsInterface protected static $url_resource = 'loadbalancers'; protected $associatedResources = array( + 'certificateMapping' => 'CertificateMapping', 'node' => 'Node', 'virtualIp' => 'VirtualIp', 'connectionLogging' => 'ConnectionLogging', @@ -158,9 +160,10 @@ class LoadBalancer extends PersistentResource implements HasPtrRecordsInterface ); protected $associatedCollections = array( - 'nodes' => 'Node', - 'virtualIps' => 'VirtualIp', - 'accessList' => 'Access' + 'certificateMappings' => 'CertificateMapping', + 'nodes' => 'Node', + 'virtualIps' => 'VirtualIp', + 'accessList' => 'Access' ); protected $createKeys = array( @@ -174,7 +177,8 @@ class LoadBalancer extends PersistentResource implements HasPtrRecordsInterface 'connectionLogging', 'connectionThrottle', 'healthMonitor', - 'sessionPersistence' + 'sessionPersistence', + 'httpsRedirect' ); /** @@ -251,17 +255,20 @@ public function addNodes() ); } - $requests = array(); + $requestData = array('nodes' => array()); + /** @var Node $node */ foreach ($this->nodes as $node) { // Only add the node if it is new if (null === $node->getId()) { - $json = json_encode($node->createJson()); - $requests[] = $this->getClient()->post($node->getUrl(), self::getJsonHeader(), $json); + $nodeJson = $node->createJson(); + $requestData['nodes'][] = $nodeJson['nodes'][0]; } } - return $this->getClient()->send($requests); + $request = $this->getClient()->post($node->getUrl(), self::getJsonHeader(), json_encode($requestData)); + + return $this->getClient()->send($request); } /** @@ -391,6 +398,99 @@ public function virtualIpList() return $this->getService()->resourceList('VirtualIp', null, $this); } + /** + * Returns a Certificate Mapping. + * + * @param int|array $id (Optional) Either a particular Certificate mapping ID, or an array of data about the + * mapping. An array can include these keys: hostName, privateKey, certificate, + * intermediateCertificate. + * @return \OpenCloud\LoadBalancer\Resource\CertificateMapping + */ + public function certificateMapping($id = null) + { + return $this->getService()->resource('CertificateMapping', $id, $this); + } + + /** + * Returns a Collection of Certificate Mappings. + * + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function certificateMappingList() + { + return $this->getService()->resourceList('CertificateMapping', null, $this); + } + + /** + * Creates a certificate mapping. + * + * @throws \OpenCloud\Common\Exceptions\MissingValueError + * + * @param string $hostName The domain name for the certificate. + * @param string $privateKey The private key for the certificate + * @param string $certificate The certificate itself. + * @param string $intermediateCertificate The intermediate certificate chain. + * @return array An array of \Guzzle\Http\Message\Response objects. + */ + public function addCertificateMapping( + $hostName, + $privateKey, + $certificate, + $intermediateCertificate = null + ) { + $certificateMapping = $this->certificateMapping( + array( + 'hostName' => $hostName, + 'privateKey' => $privateKey, + 'certificate' => $certificate, + 'intermediateCertificate' => $intermediateCertificate + ) + ); + $json = json_encode($certificateMapping->createJson()); + $request = $this->getClient()->post($certificateMapping->getUrl(), self::getJsonHeader(), $json); + + return $this->getClient()->send($request); + } + + /** + * Updates a certificate mapping. + * + * @param int $id ID of the certificate mapping. + * @param string $hostName (Optional) The domain name of the certificate. + * @param string $privateKey (Optional) The private key for the certificate. + * @param string $certificate The certificate itself. + * @param string $intermediateCertificate The intermediate certificate chain. + * @return array An array of \Guzzle\Http\Message\Response objects. + */ + public function updateCertificateMapping( + $id, + $hostName = null, + $privateKey = null, + $certificate = null, + $intermediateCertificate = null + ) { + $certificateMapping = $this->certificateMapping($id); + return $certificateMapping->update( + array( + 'hostName' => $hostName, + 'privateKey' => $privateKey, + 'certificate' => $certificate, + 'intermediateCertificate' => $intermediateCertificate + ) + ); + } + + /** + * Remove a certificate mapping. + * + * @param int $id ID of the certificate mapping. + * @return \Guzzle\Http\Message\Response + */ + public function removeCertificateMapping($id) + { + return $this->certificateMapping($id)->delete(); + } + /** * Return the session persistence resource * @@ -525,7 +625,7 @@ public function enableConnectionLogging($bool) */ public function connectionLogging() { - $this->getLogger()->deprecated(__METHOD__, 'hasConnectionLogging or enableConnectionLogging'); + $this->getLogger()->warning(Logger::deprecated(__METHOD__, 'hasConnectionLogging or enableConnectionLogging')); } /** @@ -567,7 +667,8 @@ public function enableContentCaching($bool) */ public function contentCaching() { - $this->getLogger()->deprecated(__METHOD__, 'hasContentCaching or setContentCaching'); + $this->getLogger()->warning(sprintf( + 'The %s method is deprecated, please use %s instead', __METHOD__, 'hasContentCaching or setContentCaching')); } /** diff --git a/lib/OpenCloud/LoadBalancer/Service.php b/lib/OpenCloud/LoadBalancer/Service.php index b4bd6d414..7f8d01f74 100644 --- a/lib/OpenCloud/LoadBalancer/Service.php +++ b/lib/OpenCloud/LoadBalancer/Service.php @@ -17,7 +17,9 @@ namespace OpenCloud\LoadBalancer; +use OpenCloud\Common\Log\Logger; use OpenCloud\Common\Service\NovaService; +use OpenCloud\LoadBalancer\Collection\LoadBalancerIterator; /** * Class that encapsulates the Rackspace Cloud Load Balancers service @@ -44,20 +46,26 @@ public function loadBalancer($id = null) * Return a paginated collection of load balancers * * @param bool $detail If TRUE, all details are returned; otherwise, a - * minimal set (ID, name) is retrieved + * minimal set (ID, name) is retrieved [DEPRECATED] * @param array $filter Optional query params used for search * @return \OpenCloud\Common\Collection\PaginatedIterator */ public function loadBalancerList($detail = true, array $filter = array()) { + $options = $this->makeResourceIteratorOptions($this->resolveResourceClass('LoadBalancer')); + + if (isset($filter['limit'])) { + $options['limit.page'] = $filter['limit']; + unset($filter['limit']); + } + $url = $this->getUrl(); $url->addPath(Resource\LoadBalancer::resourceName()); - if ($detail) { - $url->addPath('detail'); - } $url->setQuery($filter); - return $this->resourceList('LoadBalancer', $url); + $options = array_merge($options, array('baseUrl' => $url, 'key.marker' => 'id')); + + return LoadBalancerIterator::factory($this, $options); } /** @@ -65,7 +73,7 @@ public function loadBalancerList($detail = true, array $filter = array()) */ public function billableLoadBalancer($id = null) { - $this->getLogger()->deprecated(__METHOD__, 'loadBalancer'); + $this->getLogger()->warning(Logger::deprecated(__METHOD__, 'loadBalancer')); return $this->resource('LoadBalancer', $id); } diff --git a/lib/OpenCloud/Networking/Resource/Network.php b/lib/OpenCloud/Networking/Resource/Network.php new file mode 100644 index 000000000..19454445e --- /dev/null +++ b/lib/OpenCloud/Networking/Resource/Network.php @@ -0,0 +1,77 @@ + 'adminStateUp', + 'tenant_id' => 'tenantId' + ); + + protected $createKeys = array( + 'adminStateUp', + 'name', + 'shared', + 'tenantId' + ); + + protected $updateKeys = array( + 'name' + ); + + /** + * This method is inherited. The inherited method has protected scope + * but we are widening the scope to public so this method may be called + * from other classes such as {@see OpenCloud\Networking\Service}. + */ + public function createJson() + { + return parent::createJson(); + } + + public function getId() + { + return $this->id; + } +} diff --git a/lib/OpenCloud/Networking/Resource/NetworkInterface.php b/lib/OpenCloud/Networking/Resource/NetworkInterface.php new file mode 100644 index 000000000..30fe10de2 --- /dev/null +++ b/lib/OpenCloud/Networking/Resource/NetworkInterface.php @@ -0,0 +1,31 @@ + 'adminStateUp', + 'network_id' => 'networkId', + 'device_id' => 'deviceId', + 'device_owner' => 'deviceOwner', + 'fixed_ips' => 'fixedIps', + 'mac_address' => 'macAddress', + 'security_groups' => 'securityGroups', + 'tenant_id' => 'tenantId', + 'subnet_id' => 'subnetId', + 'ip_address' => 'ipAddress' + ); + + protected $createKeys = array( + 'name', + 'adminStateUp', + 'networkId', + 'deviceId', + 'deviceOwner', + 'fixedIps', + 'macAddress', + 'securityGroups', + 'tenantId' + ); + + protected $updateKeys = array( + 'name', + 'deviceId', + 'securityGroups' + ); + + /** + * This method is inherited. The inherited method has protected scope + * but we are widening the scope to public so this method may be called + * from other classes such as {@see OpenCloud\Networking\Service}. + */ + public function createJson() + { + return parent::createJson(); + } +} diff --git a/lib/OpenCloud/Networking/Resource/SecurityGroup.php b/lib/OpenCloud/Networking/Resource/SecurityGroup.php new file mode 100644 index 000000000..4b2f85efd --- /dev/null +++ b/lib/OpenCloud/Networking/Resource/SecurityGroup.php @@ -0,0 +1,69 @@ + 'securityGroupRules', + 'tenant_id' => 'tenantId' + ); + + protected $createKeys = array( + 'name', + 'description' + ); + + /** + * This method is inherited. The inherited method has protected scope + * but we are widening the scope to public so this method may be called + * from other classes such as {@see OpenCloud\Networking\Service}. + */ + public function createJson() + { + return parent::createJson(); + } + + /** + * {@inheritDoc} + */ + public function update($params = array()) + { + return $this->noUpdate(); + } +} diff --git a/lib/OpenCloud/Networking/Resource/SecurityGroupRule.php b/lib/OpenCloud/Networking/Resource/SecurityGroupRule.php new file mode 100644 index 000000000..06ad028b2 --- /dev/null +++ b/lib/OpenCloud/Networking/Resource/SecurityGroupRule.php @@ -0,0 +1,86 @@ + 'portRangeMin', + 'port_range_max' => 'portRangeMax', + 'remote_group_id' => 'remoteGroupId', + 'remote_ip_prefix' => 'remoteIpPrefix', + 'security_group_id' => 'securityGroupId', + 'tenant_id' => 'tenantId' + ); + + protected $createKeys = array( + 'direction', + 'ethertype', + 'securityGroupId', + 'portRangeMin', + 'portRangeMax', + 'protocol', + 'remoteGroupId', + 'remoteIpPrefix' + ); + + /** + * This method is inherited. The inherited method has protected scope + * but we are widening the scope to public so this method may be called + * from other classes such as {@see OpenCloud\Networking\Service}. + */ + public function createJson() + { + return parent::createJson(); + } + + /** + * {@inheritDoc} + */ + public function update($params = array()) + { + return $this->noUpdate(); + } +} diff --git a/lib/OpenCloud/Networking/Resource/Subnet.php b/lib/OpenCloud/Networking/Resource/Subnet.php new file mode 100644 index 000000000..5b15220f9 --- /dev/null +++ b/lib/OpenCloud/Networking/Resource/Subnet.php @@ -0,0 +1,89 @@ + 'enableDhcp', + 'network_id' => 'networkId', + 'dns_nameservers' => 'dnsNameservers', + 'allocation_pools' => 'allocationPools', + 'host_routes' => 'hostRoutes', + 'ip_version' => 'ipVersion', + 'gateway_ip' => 'gatewayIp', + 'tenant_id' => 'tenantId' + ); + + protected $createKeys = array( + 'name', + 'enableDhcp', + 'networkId', + 'allocationPools', + 'hostRoutes', + 'ipVersion', + 'gatewayIp', + 'cidr', + 'tenantId' + ); + + protected $updateKeys = array( + 'name', + 'enableDhcp', + 'hostRoutes', + 'gatewayIp' + ); + + /** + * This method is inherited. The inherited method has protected scope + * but we are widening the scope to public so this method may be called + * from other classes such as {@see OpenCloud\Networking\Service}. + */ + public function createJson() + { + return parent::createJson(); + } +} diff --git a/lib/OpenCloud/Networking/Service.php b/lib/OpenCloud/Networking/Service.php new file mode 100644 index 000000000..e3fcc879e --- /dev/null +++ b/lib/OpenCloud/Networking/Service.php @@ -0,0 +1,412 @@ +resource('Network', $id); + } + + /** + * Creates a new Network and returns it. + * + * @param array $params Network creation parameters. + * @return \OpenCloud\Networking\Resource\Network Object representing created network + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/Networking/USERGUIDE.md#create-a-network + */ + public function createNetwork(array $params = array()) + { + $network = $this->network(); + $network->create($params); + return $network; + } + + /** + * Creates multiple new Networks and returns their list. + * + * @param array $networksParams Array of network creation parameters' arrays + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function createNetworks(array $networksParams = array()) + { + // Form URL + $url = clone $this->getUrl(); + $url->addPath(Network::resourceName()); + + // Form JSON + $singleNetworkJsonName = Network::jsonName(); + $networksJsonCollectionName = Network::jsonCollectionName(); + $networks = array(); + foreach ($networksParams as $networkParams) { + $network = $this->network(); + $network->populate($networkParams); + $networks[] = $network->createJson()->{$singleNetworkJsonName}; + } + $json = json_encode(array( + $networksJsonCollectionName => $networks + )); + + // Call the API + $response = $this->getClient()->post($url, self::getJsonHeader(), $json)->send(); + + // Parse the response into a collection of created networks + $responseJson = Formatter::decode($response); + $createdNetworksJson = $responseJson->{$networksJsonCollectionName}; + + // Return collection of created networks + return $this->collection('Network', $url, $this, $createdNetworksJson); + } + + /** + * Returns a Network object associated with this Networking service + * + * @param string $id ID of network to retrieve + * @return \OpenCloud\Networking\Resource\Network object + */ + public function getNetwork($id) + { + return $this->network($id); + } + + /** + * Returns a list of networks you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listNetworks(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Network::resourceName())->setQuery($params); + + return $this->resourceList('Network', $url); + } + + /** + * Returns a Subnet object associated with this Networking service + * + * @param string $id ID of subnet to retrieve + * @return \OpenCloud\Networking\Resource\Subnet object + */ + public function subnet($id = null) + { + return $this->resource('Subnet', $id); + } + + /** + * Creates a new Subnet and returns it. + * + * @param array $params Subnet creation parameters. + * @return \OpenCloud\Networking\Resource\Subnet Object representing created subnet + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/Networking/USERGUIDE.md#create-a-subnet + */ + public function createSubnet(array $params = array()) + { + $subnet = $this->subnet(); + $subnet->create($params); + return $subnet; + } + + /** + * Creates multiple new Subnets and returns their list. + * + * @param array $subnetsParams Array of subnet creation parameters' arrays + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function createSubnets(array $subnetsParams = array()) + { + // Form URL + $url = clone $this->getUrl(); + $url->addPath(Subnet::resourceName()); + + // Form JSON + $singleSubnetJsonName = Subnet::jsonName(); + $subnetsJsonCollectionName = Subnet::jsonCollectionName(); + $subnets = array(); + foreach ($subnetsParams as $subnetParams) { + $subnet = $this->subnet(); + $subnet->populate($subnetParams); + $subnets[] = $subnet->createJson()->{$singleSubnetJsonName}; + } + $json = json_encode(array( + $subnetsJsonCollectionName => $subnets + )); + + // Call the API + $response = $this->getClient()->post($url, self::getJsonHeader(), $json)->send(); + + // Parse the response into a collection of created subnets + $responseJson = Formatter::decode($response); + $createdSubnetsJson = $responseJson->{$subnetsJsonCollectionName}; + + // Return collection of created subnets + return $this->collection('Subnet', $url, $this, $createdSubnetsJson); + } + + /** + * Returns a Subnet object associated with this Networking service + * + * @param string $id ID of subnet to retrieve + * @return \OpenCloud\Networking\Resource\Subnet object + */ + public function getSubnet($id) + { + return $this->subnet($id); + } + + /** + * Returns a list of subnets you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listSubnets(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Subnet::resourceName())->setQuery($params); + + return $this->resourceList('Subnet', $url); + } + + /** + * Returns a Port object associated with this Networking service + * + * @param string $id ID of port to retrieve + * @return \OpenCloud\Networking\Resource\Port object + */ + public function port($id = null) + { + return $this->resource('Port', $id); + } + + /** + * Creates a new Port and returns it. + * + * @param array $params Port creation parameters. + * @return \OpenCloud\Networking\Resource\Port Object representing created port + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/Networking/USERGUIDE.md#create-a-port + */ + public function createPort(array $params = array()) + { + $port = $this->port(); + $port->create($params); + return $port; + } + + /** + * Creates multiple new Ports and returns their list. + * + * @param array $portsParams Array of port creation parameters' arrays + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function createPorts(array $portsParams = array()) + { + // Form URL + $url = clone $this->getUrl(); + $url->addPath(Port::resourceName()); + + // Form JSON + $singlePortJsonName = Port::jsonName(); + $portsJsonCollectionName = Port::jsonCollectionName(); + $ports = array(); + foreach ($portsParams as $portParams) { + $port = $this->port(); + $port->populate($portParams); + $ports[] = $port->createJson()->{$singlePortJsonName}; + } + $json = json_encode(array( + $portsJsonCollectionName => $ports + )); + + // Call the API + $response = $this->getClient()->post($url, self::getJsonHeader(), $json)->send(); + + // Parse the response into a collection of created ports + $responseJson = Formatter::decode($response); + $createdPortsJson = $responseJson->{$portsJsonCollectionName}; + + // Return collection of created ports + return $this->collection('Port', $url, $this, $createdPortsJson); + } + + /** + * Returns a Port object associated with this Networking service + * + * @param string $id ID of port to retrieve + * @return \OpenCloud\Networking\Resource\Port object + */ + public function getPort($id) + { + return $this->port($id); + } + + /** + * Returns a list of ports you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listPorts(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Port::resourceName())->setQuery($params); + + return $this->resourceList('Port', $url); + } + + /** + * Returns a SecurityGroup object associated with this Networking service + * + * @param string $id ID of security group to retrieve + * @return \OpenCloud\Networking\Resource\SecurityGroup object + */ + public function securityGroup($id = null) + { + return $this->resource('SecurityGroup', $id); + } + + /** + * Creates a new SecurityGroup and returns it. + * + * @param array $params SecurityGroup creation parameters. + * @return \OpenCloud\Networking\Resource\SecurityGroup Object representing created security group + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/Networking/USERGUIDE.md#create-a-security-group + */ + public function createSecurityGroup(array $params = array()) + { + $securityGroup = $this->securityGroup(); + $securityGroup->create($params); + return $securityGroup; + } + + /** + * Returns a SecurityGroup object associated with this Networking service + * + * @param string $id ID of security group to retrieve + * @return \OpenCloud\Networking\Resource\SecurityGroup object + */ + public function getSecurityGroup($id) + { + return $this->securityGroup($id); + } + + /** + * Returns a list of security groups you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listSecurityGroups(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(SecurityGroup::resourceName())->setQuery($params); + + return $this->resourceList('SecurityGroup', $url); + } + + /** + * Returns a SecurityGroupRule object associated with this Networking service + * + * @param string $id ID of security group rule to retrieve + * @return \OpenCloud\Networking\Resource\SecurityGroupRule object + */ + public function securityGroupRule($id = null) + { + return $this->resource('SecurityGroupRule', $id); + } + + /** + * Creates a new SecurityGroupRule and returns it. + * + * @param array $params SecurityGroupRule creation parameters. + * @return \OpenCloud\Networking\Resource\SecurityGroupRule Object representing created security group rule + * + * @see https://github.com/rackspace/php-opencloud/blob/master/docs/userguide/Networking/USERGUIDE.md#create-a-security-group-rule + */ + public function createSecurityGroupRule(array $params = array()) + { + $securityGroupRule = $this->securityGroupRule(); + $securityGroupRule->create($params); + return $securityGroupRule; + } + + /** + * Returns a SecurityGroupRule object associated with this Networking service + * + * @param string $id ID of security group rule to retrieve + * @return \OpenCloud\Networking\Resource\SecurityGroupRule object + */ + public function getSecurityGroupRule($id) + { + return $this->securityGroupRule($id); + } + + /** + * Returns a list of security group rules you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listSecurityGroupRules(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(SecurityGroupRule::resourceName())->setQuery($params); + + return $this->resourceList('SecurityGroupRule', $url); + } + + /** + * Return namespaces. + * + * @return array + */ + public function namespaces() + { + return array(); + } +} diff --git a/lib/OpenCloud/ObjectStore/AbstractService.php b/lib/OpenCloud/ObjectStore/AbstractService.php index 8e24c0b96..6094d7780 100644 --- a/lib/OpenCloud/ObjectStore/AbstractService.php +++ b/lib/OpenCloud/ObjectStore/AbstractService.php @@ -30,23 +30,9 @@ abstract class AbstractService extends CatalogService const MAX_OBJECT_SIZE = 5102410241025; /** - * List all available containers. If called by a CDN service, it returns CDN-enabled; if called by a regular - * service, normal containers are returned. + * Returns the Object Store account associated with the service. * - * @param array $filter - * @return Collection - */ - public function listContainers(array $filter = array()) - { - $filter['format'] = 'json'; - - $class = ($this instanceof Service) ? 'Container' : 'CDNContainer'; - - return $this->resourceList($class, $this->getUrl(null, $filter), $this); - } - - /** - * @return Resource\Account + * @return Resource\Account Object Store account */ public function getAccount() { diff --git a/lib/OpenCloud/ObjectStore/CDNService.php b/lib/OpenCloud/ObjectStore/CDNService.php index e6b20cd5c..6a13a8ee0 100644 --- a/lib/OpenCloud/ObjectStore/CDNService.php +++ b/lib/OpenCloud/ObjectStore/CDNService.php @@ -17,6 +17,9 @@ namespace OpenCloud\ObjectStore; +use OpenCloud\ObjectStore\Resource\CDNContainer; +use OpenCloud\ObjectStore\Resource\ContainerMetadata; + /** * This is the CDN version of the ObjectStore service. */ @@ -24,4 +27,47 @@ class CDNService extends AbstractService { const DEFAULT_NAME = 'cloudFilesCDN'; const DEFAULT_TYPE = 'rax:object-cdn'; + + /** + * List CDN-enabled containers. + * + * @param array $filter Array of filter options such as: + * + * * `limit`: number of results to limit the list to. Optional. + * * `marker`: name of container after which to start the list. Optional. + * * `end_marker`: name of container before which to end the list. Optional. + * @return \OpenCloud\Common\Collection\PaginatedIterator Iterator to list of CDN-enabled containers + */ + public function listContainers(array $filter = array()) + { + $filter['format'] = 'json'; + return $this->resourceList('CDNContainer', $this->getUrl(null, $filter), $this); + } + + /** + * Return an existing CDN-enabled container. + * + * @param \stdClass $data Data to initialize container. + * @return CDNContainer CDN-enabled Container + */ + public function cdnContainer($data) + { + $container = new CDNContainer($this, $data); + + if (is_object($data)) { + $metadata = new ContainerMetadata(); + $metadata->setArray(array( + 'Streaming-Uri' => $data->cdn_streaming_uri, + 'Ios-Uri' => $data->cdn_ios_uri, + 'Ssl-Uri' => $data->cdn_ssl_uri, + 'Enabled' => $data->cdn_enabled, + 'Ttl' => $data->ttl, + 'Log-Retention' => $data->log_retention, + 'Uri' => $data->cdn_uri, + )); + $container->setMetadata($metadata); + } + + return $container; + } } diff --git a/lib/OpenCloud/ObjectStore/Enum/ReturnType.php b/lib/OpenCloud/ObjectStore/Enum/ReturnType.php new file mode 100644 index 000000000..ac9193ed4 --- /dev/null +++ b/lib/OpenCloud/ObjectStore/Enum/ReturnType.php @@ -0,0 +1,29 @@ +name = $name; + + return $e; + } +} diff --git a/lib/OpenCloud/ObjectStore/Resource/AbstractContainer.php b/lib/OpenCloud/ObjectStore/Resource/AbstractContainer.php index a36320652..56cd1c2fa 100644 --- a/lib/OpenCloud/ObjectStore/Resource/AbstractContainer.php +++ b/lib/OpenCloud/ObjectStore/Resource/AbstractContainer.php @@ -50,13 +50,28 @@ public function __construct(ServiceInterface $service, $data = null) $this->populate($data); } + /** + * Return the transaction ID for an HTTP API operation. Useful for debugging. + * + * @return string Transaction ID + */ public function getTransId() { return $this->metadata->getProperty(HeaderConst::TRANS_ID); } + /** + * Returns whether this container is CDN-enabled or not. + * + * @return boolean true if this container is CDN-enabled; false, otherwise. + */ abstract public function isCdnEnabled(); + /** + * Returns whether this container has log retention enabled or not. + * + * @return boolean true if this container has log retention enabled; false, otherwise. + */ public function hasLogRetention() { if ($this instanceof CDNContainer) { @@ -66,11 +81,23 @@ public function hasLogRetention() } } + /** + * For internal use only + * + * @return string Name of the primary key field for this resource + */ public function primaryKeyField() { return 'name'; } + /** + * For internal use only + * + * @param string $path Path to add to URL. Optional. + * @param array $params Query parameters to add to URL. Optional. + * @return Url URL of this container + path + query parameters. + */ public function getUrl($path = null, array $params = array()) { if (strlen($this->getName()) == 0) { @@ -91,7 +118,7 @@ protected function createRefreshRequest() * This method will enable your CDN-enabled container to serve out HTML content like a website. * * @param $indexPage The data object name (i.e. a .html file) that will serve as the main index page. - * @return \Guzzle\Http\Message\Response + * @return \Guzzle\Http\Message\Response The HTTP response for this API operation. */ public function setStaticIndexPage($page) { @@ -110,7 +137,7 @@ public function setStaticIndexPage($page) * Set the default error page for your static site. * * @param $name The data object name (i.e. a .html file) that will serve as the main error page. - * @return \Guzzle\Http\Message\Response + * @return \Guzzle\Http\Message\Response The HTTP response for this operation. */ public function setStaticErrorPage($page) { diff --git a/lib/OpenCloud/ObjectStore/Resource/AbstractResource.php b/lib/OpenCloud/ObjectStore/Resource/AbstractResource.php index e2d494ede..17dd4f0f9 100644 --- a/lib/OpenCloud/ObjectStore/Resource/AbstractResource.php +++ b/lib/OpenCloud/ObjectStore/Resource/AbstractResource.php @@ -19,7 +19,9 @@ use Guzzle\Http\Message\Response; use OpenCloud\Common\Base; +use OpenCloud\Common\Http\Client; use OpenCloud\Common\Service\ServiceInterface; +use OpenCloud\ObjectStore\Service; /** * Abstract base class which implements shared functionality of ObjectStore @@ -36,7 +38,7 @@ abstract class AbstractResource extends Base /** @var string The FQCN of the metadata object used for the container. */ protected $metadataClass = 'OpenCloud\\Common\\Metadata'; - /** @var \OpenCloud\Common\Service\ServiceInterface The service object. */ + /** @var Service The service object. */ protected $service; public function __construct(ServiceInterface $service) @@ -45,16 +47,31 @@ public function __construct(ServiceInterface $service) $this->metadata = new $this->metadataClass; } + /** + * For internal use only. + * + * @return Service The ObjectStore service associated with this ObjectStore resource. + */ public function getService() { return $this->service; } + /** + * For internal use only. + * + * @return Service The CDN version of the ObjectStore service associated with this ObjectStore resource. + */ public function getCdnService() { return $this->service->getCDNService(); } + /** + * For internal use only. + * + * @return Client The HTTP client associated with the associated ObjectStore service. + */ public function getClient() { return $this->service->getClient(); @@ -63,9 +80,11 @@ public function getClient() /** * Factory method that allows for easy instantiation from a Response object. * - * @param Response $response - * @param ServiceInterface $service - * @return static + * For internal use only. + * + * @param Response $response HTTP response from an API operation. + * @param ServiceInterface $service The ObjectStore service to associate with this ObjectStore resource object. + * @return AbstractResource A concrete sub-class of `AbstractResource`. */ public static function fromResponse(Response $response, ServiceInterface $service) { @@ -81,8 +100,10 @@ public static function fromResponse(Response $response, ServiceInterface $servic /** * Trim headers of their resource-specific prefixes. * - * @param $headers - * @return array + * For internal use only. + * + * @param array $headers Headers as returned from an HTTP response + * @return array Trimmed headers */ public static function trimHeaders($headers) { @@ -121,8 +142,8 @@ protected static function stripPrefix($header) /** * Prepend/stock the header names with a resource-specific prefix. * - * @param array $headers - * @return array + * @param array $headers Headers to use on ObjectStore resource. + * @return array Headers returned with appropriate prefix as expected by ObjectStore service. */ public static function stockHeaders(array $headers) { @@ -147,11 +168,12 @@ public static function stockHeaders(array $headers) } /** - * Set the metadata (local-only) for this object. + * Set the metadata (local-only) for this object. You must call saveMetadata + * to actually persist the metadata using the ObjectStore service. * - * @param $data - * @param bool $constructFromResponse - * @return $this + * @param array $data Object/container metadata key/value pair array. + * @param bool $constructFromResponse Whether the metadata key/value pairs were obtiained from an HTTP response of an ObjectStore API operation. + * @return AbstractResource This object, with metadata set. */ public function setMetadata($data, $constructFromResponse = false) { @@ -167,7 +189,9 @@ public function setMetadata($data, $constructFromResponse = false) } /** - * @return \OpenCloud\Common\Metadata + * Returns metadata for this object. + * + * @return \OpenCloud\Common\Metadata Metadata set on this object. */ public function getMetadata() { @@ -180,7 +204,7 @@ public function getMetadata() * @param array $metadata The array of values you want to set as metadata * @param bool $stockPrefix Whether to prepend each array key with the metadata-specific prefix. For objects, this * would be X-Object-Meta-Foo => Bar - * @return mixed + * @return Response HTTP response from API operation. */ public function saveMetadata(array $metadata, $stockPrefix = true) { @@ -192,7 +216,7 @@ public function saveMetadata(array $metadata, $stockPrefix = true) /** * Retrieve metadata from the API. This method will then set and return this value. * - * @return \OpenCloud\Common\Metadata + * @return \OpenCloud\Common\Metadata Metadata returned from the ObjectStore service for this object/container. */ public function retrieveMetadata() { @@ -208,8 +232,8 @@ public function retrieveMetadata() /** * To delete or unset a particular metadata item. * - * @param $key - * @return mixed + * @param string $key Metadata key to unset + * @return Response HTTP response returned from API operation to unset metadata item. */ public function unsetMetadataItem($key) { @@ -224,10 +248,12 @@ public function unsetMetadataItem($key) } /** - * Append a particular array of values to the existing metadata. Analogous to a merge. + * Append a particular array of values to the existing metadata. Analogous + * to a merge. You must call to actually persist the metadata using the + * ObjectStore service. * - * @param array $values - * @return array + * @param array $values The array of values you want to append to metadata. + * @return array Metadata, after `$values` are appended. */ public function appendToMetadata(array $values) { diff --git a/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php b/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php index 44422bf00..80e547349 100644 --- a/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php +++ b/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php @@ -106,4 +106,17 @@ public function isCdnEnabled() { return $this->metadata->getProperty(HeaderConst::ENABLED) == 'True'; } + + /** + * Set the TTL. + * + * @param $ttl The time-to-live in seconds. + * @return \Guzzle\Http\Message\Response + */ + public function setTtl($ttl) + { + $headers = array('X-Ttl' => $ttl); + + return $this->getClient()->post($this->getUrl(), $headers)->send(); + } } diff --git a/lib/OpenCloud/ObjectStore/Resource/Container.php b/lib/OpenCloud/ObjectStore/Resource/Container.php index 8049a2c3c..474d9134b 100644 --- a/lib/OpenCloud/ObjectStore/Resource/Container.php +++ b/lib/OpenCloud/ObjectStore/Resource/Container.php @@ -30,6 +30,7 @@ use OpenCloud\ObjectStore\Exception\ObjectNotFoundException; use OpenCloud\ObjectStore\Upload\DirectorySync; use OpenCloud\ObjectStore\Upload\TransferBuilder; +use OpenCloud\ObjectStore\Enum\ReturnType; /** * A container is a storage compartment for your data and provides a way for you @@ -159,7 +160,8 @@ public function getBytesQuota() public function delete($deleteObjects = false) { if ($deleteObjects === true) { - $this->deleteAllObjects(); + // Delegate to auxiliary method + return $this->deleteWithObjects(); } try { @@ -176,6 +178,47 @@ public function delete($deleteObjects = false) } } + public function deleteWithObjects($secondsToWait = null) + { + // If container is empty, just delete it + $numObjects = (int) $this->retrieveMetadata()->getProperty('Object-Count'); + if (0 === $numObjects) { + return $this->delete(); + } + + // If timeout ($secondsToWait) is not specified by caller, + // try to estimate it based on number of objects in container + if (null === $secondsToWait) { + $secondsToWait = round($numObjects / 2); + } + + // Attempt to delete all objects and container + $endTime = time() + $secondsToWait; + $containerDeleted = false; + while ((time() < $endTime) && !$containerDeleted) { + $this->deleteAllObjects(); + try { + $response = $this->delete(); + $containerDeleted = true; + } catch (ContainerException $e) { + // Ignore exception and try again + } catch (ClientErrorResponseException $e) { + if ($e->getResponse()->getStatusCode() == 404) { + // Container has been deleted + $containerDeleted = true; + } else { + throw $e; + } + } + } + + if (!$containerDeleted) { + throw new ContainerException('Container and all its objects could not be deleted.'); + } + + return $response; + } + /** * Deletes all objects that this container currently contains. Useful when doing operations (like a delete) that * require an empty container first. @@ -184,15 +227,25 @@ public function delete($deleteObjects = false) */ public function deleteAllObjects() { - $requests = array(); - - $list = $this->objectList(); - - foreach ($list as $object) { - $requests[] = $this->getClient()->delete($object->getUrl()); + $paths = array(); + $objects = $this->objectList(); + foreach ($objects as $object) { + $paths[] = sprintf('/%s/%s', $this->getName(), $object->getName()); } + return $this->getService()->batchDelete($paths); + } - return $this->getClient()->send($requests); + /** + * Delete an object from the API. + * + * @param string $name The name of object you want to delete + * @throws \Guzzle\Http\Exception\BadResponseException When an error occurred + */ + public function deleteObject($name) + { + $this->getClient() + ->delete($this->getUrl($name)) + ->send(); } /** @@ -214,7 +267,7 @@ public function deleteAllObjects() * names nested in the container are returned. * @link http://api.openstack.org for a list of possible parameter * names and values - * @return 'OpenCloud\Common\Collection + * @return \OpenCloud\Common\Collection * @throws ObjFetchError */ public function objectList(array $params = array()) @@ -283,23 +336,6 @@ public function refresh($id = null, $url = null) { $headers = $this->createRefreshRequest()->send()->getHeaders(); $this->setMetadata($headers, true); - - try { - if (null !== ($cdnService = $this->getService()->getCDNService())) { - $cdn = new CDNContainer($cdnService); - $cdn->setName($this->name); - - $response = $cdn->createRefreshRequest()->send(); - - if ($response->isSuccessful()) { - $this->cdn = $cdn; - $this->cdn->setMetadata($response->getHeaders(), true); - } - } else { - $this->cdn = null; - } - } catch (ClientErrorResponseException $e) { - } } /** @@ -432,16 +468,18 @@ public function uploadObject($name, $data, array $headers = array()) * `path' Path to an existing file, OR * `body' Either a string or stream representation of the file contents to be uploaded. * @param array $headers Optional headers that will be sent with the request (useful for object metadata). + * @param string $returnType One of OpenCloud\ObjectStore\Enum\ReturnType::RESPONSE_ARRAY (to return an array of + * Guzzle\Http\Message\Response objects) or OpenCloud\ObjectStore\Enum\ReturnType::DATA_OBJECT_ARRAY + * (to return an array of OpenCloud\ObjectStore\Resource\DataObject objects). * * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError - * @return \Guzzle\Http\Message\Response + * @return Guzzle\Http\Message\Response[] or OpenCloud\ObjectStore\Resource\DataObject[] depending on $returnType */ - public function uploadObjects(array $files, array $commonHeaders = array()) + public function uploadObjects(array $files, array $commonHeaders = array(), $returnType = ReturnType::RESPONSE_ARRAY) { $requests = $entities = array(); foreach ($files as $entity) { - if (empty($entity['name'])) { throw new Exceptions\InvalidArgumentError('You must provide a name.'); } @@ -476,11 +514,22 @@ public function uploadObjects(array $files, array $commonHeaders = array()) $responses = $this->getClient()->send($requests); - foreach ($entities as $entity) { - $entity->close(); + if (ReturnType::RESPONSE_ARRAY === $returnType) { + foreach ($entities as $entity) { + $entity->close(); + } + return $responses; + } else { + // Convert responses to DataObjects before returning + $dataObjects = array(); + foreach ($responses as $index => $response) { + $dataObjects[] = $this->dataObject() + ->populateFromResponse($response) + ->setName($files[$index]['name']) + ->setContent($entities[$index]); + } + return $dataObjects; } - - return $responses; } /** @@ -534,16 +583,41 @@ public function setupObjectTransfer(array $options = array()) /** * Upload the contents of a local directory to a remote container, effectively syncing them. * - * @param $path The local path to the directory. + * @param string $path The local path to the directory. + * @param string $targetDir The path (or pseudo-directory) that all files will be nested in. */ - public function uploadDirectory($path) + public function uploadDirectory($path, $targetDir = null) { - $sync = DirectorySync::factory($path, $this); + $sync = DirectorySync::factory($path, $this, $targetDir); $sync->execute(); } public function isCdnEnabled() { + // If CDN object is not already populated, try to populate it. + if (null === $this->cdn) { + $this->refreshCdnObject(); + } return ($this->cdn instanceof CDNContainer) && $this->cdn->isCdnEnabled(); } + + protected function refreshCdnObject() + { + try { + if (null !== ($cdnService = $this->getService()->getCDNService())) { + $cdn = new CDNContainer($cdnService); + $cdn->setName($this->name); + + $response = $cdn->createRefreshRequest()->send(); + + if ($response->isSuccessful()) { + $this->cdn = $cdn; + $this->cdn->setMetadata($response->getHeaders(), true); + } + } else { + $this->cdn = null; + } + } catch (ClientErrorResponseException $e) { + } + } } diff --git a/lib/OpenCloud/ObjectStore/Resource/DataObject.php b/lib/OpenCloud/ObjectStore/Resource/DataObject.php index 5877431b8..5eb3c085e 100644 --- a/lib/OpenCloud/ObjectStore/Resource/DataObject.php +++ b/lib/OpenCloud/ObjectStore/Resource/DataObject.php @@ -24,6 +24,7 @@ use OpenCloud\Common\Exceptions; use OpenCloud\Common\Lang; use OpenCloud\ObjectStore\Constants\UrlType; +use OpenCloud\ObjectStore\Exception\ObjectNotEmptyException; /** * Objects are the basic storage entities in Cloud Files. They represent the @@ -76,6 +77,11 @@ class DataObject extends AbstractResource * @var string Etag. */ protected $etag; + + /** + * @var string Manifest. Can be null so we use false to mean unset. + */ + protected $manifest = false; /** * Also need to set Container parent and handle pseudo-directories. @@ -139,7 +145,9 @@ public function populateFromResponse(Response $response) ->setContentType((string) $headers[HeaderConst::CONTENT_TYPE]) ->setLastModified((string) $headers[HeaderConst::LAST_MODIFIED]) ->setContentLength((string) $headers[HeaderConst::CONTENT_LENGTH]) - ->setEtag((string) $headers[HeaderConst::ETAG]); + ->setEtag((string) $headers[HeaderConst::ETAG]) + // do not cast to a string to allow for null (i.e. no header) + ->setManifest($headers[HeaderConst::X_OBJECT_MANIFEST]); } public function refresh() @@ -257,7 +265,7 @@ public function getContentType() } /** - * @param $contentType int + * @param $contentLength mixed * @return $this */ public function setContentLength($contentLength) @@ -268,7 +276,7 @@ public function setContentLength($contentLength) } /** - * @return int + * @return mixed */ public function getContentLength() { @@ -293,6 +301,26 @@ public function getEtag() { return $this->etag ? : $this->content->getContentMd5(); } + + /** + * @param string $manifest Path (`container/object') to set as the value to X-Object-Manifest + * @return $this + */ + protected function setManifest($manifest) + { + $this->manifest = $manifest; + + return $this; + } + + /** + * @return null|string Path (`container/object') from X-Object-Manifest header or null if the header does not exist + */ + public function getManifest() + { + // only make a request if manifest has not been set (is false) + return $this->manifest !== false ? $this->manifest : $this->getManifestHeader(); + } public function setLastModified($lastModified) { @@ -327,10 +355,11 @@ public function update($params = array()) // merge specific properties with metadata $metadata += array( - HeaderConst::CONTENT_TYPE => $this->contentType, - HeaderConst::LAST_MODIFIED => $this->lastModified, - HeaderConst::CONTENT_LENGTH => $this->contentLength, - HeaderConst::ETAG => $this->etag + HeaderConst::CONTENT_TYPE => $this->contentType, + HeaderConst::LAST_MODIFIED => $this->lastModified, + HeaderConst::CONTENT_LENGTH => $this->contentLength, + HeaderConst::ETAG => $this->etag, + HeaderConst::X_OBJECT_MANIFEST => $this->manifest ); return $this->container->uploadObject($this->name, $this->content, $metadata); @@ -354,20 +383,86 @@ public function delete($params = array()) { return $this->getService()->getClient()->delete($this->getUrl())->send(); } + + /** + * Create a symlink to another named object from this object. Requires this object to be empty. + * + * @param string $destination Path (`container/object') of other object to symlink this object to + * @return \Guzzle\Http\Message\Response The response + * @throws \OpenCloud\Common\Exceptions\NoNameError if a destination name is not provided + * @throws \OpenCloud\ObjectStore\Exception\ObjectNotEmptyException if $this is not an empty object + */ + public function createSymlinkTo($destination) + { + if (!$this->name) { + throw new Exceptions\NoNameError(Lang::translate('Object has no name')); + } + + if ($this->getContentLength()) { + throw new ObjectNotEmptyException($this->getContainer()->getName() . '/' . $this->getName()); + } + + $response = $this->getService() + ->getClient() + ->createRequest('PUT', $this->getUrl(), array( + HeaderConst::X_OBJECT_MANIFEST => (string) $destination + )) + ->send(); + + if ($response->getStatusCode() == 201) { + $this->setManifest($source); + } + + return $response; + } + + /** + * Create a symlink to this object from another named object. Requires the other object to either not exist or be empty. + * + * @param string $source Path (`container/object') of other object to symlink this object from + * @return DataObject The symlinked object + * @throws \OpenCloud\Common\Exceptions\NoNameError if a source name is not provided + * @throws \OpenCloud\ObjectStore\Exception\ObjectNotEmptyException if object already exists and is not empty + */ + public function createSymlinkFrom($source) + { + if (!strlen($source)) { + throw new Exceptions\NoNameError(Lang::translate('Object has no name')); + } + + // Use ltrim to remove leading slash from source + list($containerName, $resourceName) = explode("/", ltrim($source, '/'), 2); + $container = $this->getService()->getContainer($containerName); + + if ($container->objectExists($resourceName)) { + $object = $container->getPartialObject($source); + if ($object->getContentLength() > 0) { + throw new ObjectNotEmptyException($source); + } + } + + return $container->uploadObject($resourceName, 'data', array( + HeaderConst::X_OBJECT_MANIFEST => (string) $this->getUrl() + )); + } /** * Get a temporary URL for this object. * * @link http://docs.rackspace.com/files/api/v1/cf-devguide/content/TempURL-d1a4450.html * - * @param $expires Expiration time in seconds - * @param $method What method can use this URL? (`GET' or `PUT') + * @param int $expires Expiration time in seconds + * @param string $method What method can use this URL? (`GET' or `PUT') + * @param bool $forcePublicUrl If set to TRUE, a public URL will always be used. The default is to use whatever + * URL type the user has set for the main service. + * * @return string + * * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError * @throws \OpenCloud\Common\Exceptions\ObjectError * */ - public function getTemporaryUrl($expires, $method) + public function getTemporaryUrl($expires, $method, $forcePublicUrl = false) { $method = strtoupper($method); $expiry = time() + (int) $expires; @@ -387,6 +482,10 @@ public function getTemporaryUrl($expires, $method) // @codeCoverageIgnoreEnd $url = $this->getUrl(); + if ($forcePublicUrl === true) { + $url->setHost($this->getService()->getEndpoint()->getPublicUrl()->getHost()); + } + $urlPath = urldecode($url->getPath()); $body = sprintf("%s\n%d\n%s", $method, $expiry, $urlPath); $hash = hash_hmac('sha1', $body, $secret); @@ -449,4 +548,21 @@ protected static function headerIsValidMetadata($header) return preg_match($pattern, $header); } + + /** + * @return null|string + */ + protected function getManifestHeader() + { + $response = $this->getService() + ->getClient() + ->head($this->getUrl()) + ->send(); + + $manifest = $response->getHeader(HeaderConst::X_OBJECT_MANIFEST); + + $this->setManifest($manifest); + + return $manifest; + } } diff --git a/lib/OpenCloud/ObjectStore/Service.php b/lib/OpenCloud/ObjectStore/Service.php index b35cb3c31..0079027b0 100644 --- a/lib/OpenCloud/ObjectStore/Service.php +++ b/lib/OpenCloud/ObjectStore/Service.php @@ -24,6 +24,7 @@ use OpenCloud\Common\Exceptions\InvalidArgumentError; use OpenCloud\Common\Http\Client; use OpenCloud\Common\Http\Message\Formatter; +use OpenCloud\Common\Log\Logger; use OpenCloud\Common\Service\ServiceBuilder; use OpenCloud\ObjectStore\Constants\UrlType; use OpenCloud\ObjectStore\Resource\Container; @@ -36,6 +37,7 @@ class Service extends AbstractService { const DEFAULT_NAME = 'cloudFiles'; const DEFAULT_TYPE = 'object-store'; + const BATCH_DELETE_MAX = 10000; /** * This holds the associated CDN service (for Rackspace public cloud) @@ -57,7 +59,9 @@ public function __construct(Client $client, $type = null, $name = null, $region } /** - * @return CDNService + * Return the CDN version of the ObjectStore service. + * + * @return CDNService CDN version of the ObjectStore service */ public function getCdnService() { @@ -65,20 +69,42 @@ public function getCdnService() } /** - * @param $data - * @return Container + * List all available containers. + * + * @param array $filter Array of filter options such as: + * + * * `limit`: number of results to limit the list to. Optional. + * * `marker`: name of container after which to start the list. Optional. + * * `end_marker`: name of container before which to end the list. Optional. + * @return \OpenCloud\Common\Collection\PaginatedIterator Iterator to list of containers + */ + public function listContainers(array $filter = array()) + { + $filter['format'] = 'json'; + return $this->resourceList('Container', $this->getUrl(null, $filter), $this); + } + + /** + * Return a new or existing (if name is specified) container. + * + * @param \stdClass $data Data to initialize container. Optional. + * @return Container Container */ public function getContainer($data = null) { + if (is_string($data) || is_numeric($data)) { + $this->checkContainerName($data); + } + return new Container($this, $data); } /** * Create a container for this service. * - * @param $name The name of the container + * @param string $name The name of the container * @param array $metadata Additional (optional) metadata to associate with the container - * @return bool|static + * @return bool|Container Newly-created Container upon success; false, otherwise */ public function createContainer($name, array $metadata = array()) { @@ -100,9 +126,9 @@ public function createContainer($name, array $metadata = array()) /** * Check the validity of a potential container name. * - * @param $name - * @return bool - * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError + * @param string $name Name of container + * @return bool True if container name is valid + * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError if container name is invalid */ public function checkContainerName($name) { @@ -131,12 +157,12 @@ public function checkContainerName($name) * will be ignored. You can create up to 1,000 new containers per extraction request. Also note that only regular * files will be uploaded. Empty directories, symlinks, and so on, will not be uploaded. * - * @param $path The path to the archive being extracted - * @param $archive The contents of the archive (either string or stream) + * @param string $path The path to the archive being extracted + * @param string|stream $archive The contents of the archive (either string or stream) * @param string $archiveType The type of archive you're using {@see \OpenCloud\ObjectStore\Constants\UrlType} - * @return \Guzzle\Http\Message\Response - * @throws Exception\BulkOperationException - * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError + * @return \Guzzle\Http\Message\Response HTTP response from API + * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError if specifed `$archiveType` is invalid + * @throws Exception\BulkOperationException if there are errors with the bulk extract */ public function bulkExtract($path = '', $archive, $archiveType = UrlType::TAR_GZ) { @@ -169,14 +195,55 @@ public function bulkExtract($path = '', $archive, $archiveType = UrlType::TAR_GZ } /** - * This method will delete multiple objects or containers from their account with a single request. + * @deprecated Please use {@see batchDelete()} instead. + */ + public function bulkDelete(array $paths) + { + $this->getLogger()->warning(Logger::deprecated(__METHOD__, '::batchDelete()')); + + return $this->executeBatchDeleteRequest($paths); + } + + /** + * Batch delete will delete an array of object paths. By default, + * the API will only accept a maximum of 10,000 object deletions + * per request - so for arrays that exceed this size, it is chunked + * and sent as individual requests. + * + * @param array $paths The objects you want to delete. Each path needs + * be formatted as `/{containerName}/{objectName}`. If + * you are deleting `object_1` and `object_2` from the + * `photos_container`, the array will be: + * + * array( + * '/photos_container/object_1', + * '/photos_container/object_2' + * ) * - * @param array $paths A two-dimensional array of paths: - * array('container_a/file_1', 'container_b/file_78', 'container_c/file_40582') + * @return array[Guzzle\Http\Message\Response] HTTP responses from the API + * @throws Exception\BulkOperationException if the bulk delete operation fails + */ + public function batchDelete(array $paths) + { + $chunks = array_chunk($paths, self::BATCH_DELETE_MAX); + + $responses = array(); + + foreach ($chunks as $chunk) { + $responses[] = $this->executeBatchDeleteRequest($chunk); + } + + return $responses; + } + + /** + * Internal method for dispatching single batch delete requests. + * + * @param array $paths * @return \Guzzle\Http\Message\Response * @throws Exception\BulkOperationException */ - public function bulkDelete(array $paths) + private function executeBatchDeleteRequest(array $paths) { $entity = EntityBody::factory(implode(PHP_EOL, $paths)); @@ -202,7 +269,12 @@ public function bulkDelete(array $paths) * * @param Container $old Where you're moving files from * @param Container $new Where you're moving files to - * @return array Of PUT responses + * @param array $options Options to configure the migration. Optional. Available options are: + * + * * `read.batchLimit`: Number of files to read at a time from `$old` container. Optional; default = 1000. + * * `write.batchLimit`: Number of files to write at a time to `$new` container. Optional; default = 1000. + * * `read.pageLimit`: Number of filenames to read at a time from `$old` container. Optional; default = 10000. + * @return array[Guzzle\Http\Message\Response] HTTP responses from the API */ public function migrateContainer(Container $old, Container $new, array $options = array()) { diff --git a/lib/OpenCloud/ObjectStore/Upload/ConcurrentTransfer.php b/lib/OpenCloud/ObjectStore/Upload/ConcurrentTransfer.php index f011e4569..d0a58f736 100644 --- a/lib/OpenCloud/ObjectStore/Upload/ConcurrentTransfer.php +++ b/lib/OpenCloud/ObjectStore/Upload/ConcurrentTransfer.php @@ -36,13 +36,11 @@ public function transfer() $parts = $this->collectParts($workers); while ($this->transferState->count() < $totalParts) { - $completedParts = $this->transferState->count(); $requests = array(); // Iterate over number of workers until total completed parts is what we need it to be for ($i = 0; $i < $workers && ($completedParts + $i) < $totalParts; $i++) { - // Offset is the current pointer multiplied by the standard chunk length $offset = ($completedParts + $i) * $this->partSize; $parts[$i]->setOffset($offset); diff --git a/lib/OpenCloud/ObjectStore/Upload/ConsecutiveTransfer.php b/lib/OpenCloud/ObjectStore/Upload/ConsecutiveTransfer.php index acd13c519..50196802d 100644 --- a/lib/OpenCloud/ObjectStore/Upload/ConsecutiveTransfer.php +++ b/lib/OpenCloud/ObjectStore/Upload/ConsecutiveTransfer.php @@ -29,11 +29,9 @@ */ class ConsecutiveTransfer extends AbstractTransfer { - public function transfer() { while (!$this->entityBody->isConsumed()) { - if ($this->entityBody->getContentLength() && $this->entityBody->isSeekable()) { // Stream directly from the data $body = new ReadLimitEntityBody($this->entityBody, $this->partSize, $this->entityBody->ftell()); diff --git a/lib/OpenCloud/ObjectStore/Upload/DirectorySync.php b/lib/OpenCloud/ObjectStore/Upload/DirectorySync.php index 0e5a77e3e..fc30b9968 100644 --- a/lib/OpenCloud/ObjectStore/Upload/DirectorySync.php +++ b/lib/OpenCloud/ObjectStore/Upload/DirectorySync.php @@ -31,32 +31,34 @@ */ class DirectorySync { - /** - * @var string The path to the directory you're syncing. - */ + /** @var string The path to the directory you're syncing. */ private $basePath; - /** - * @var ResourceIterator A collection of remote files in Swift. - */ + + /** @var ResourceIterator A collection of remote files in Swift. */ private $remoteFiles; - /** - * @var AbstractContainer The Container object you are syncing. - */ + + /** @var AbstractContainer The Container object you are syncing. */ private $container; + /** @var string */ + private $targetDir; + /** * Basic factory method to instantiate a new DirectorySync object with all the appropriate properties. * - * @param $path The local path + * @param string $path The local path * @param Container $container The container you're syncing + * @param string $targetDir The path (or pseudo-directory) that the files will be nested in + * * @return DirectorySync */ - public static function factory($path, Container $container) + public static function factory($path, Container $container, $targetDir = null) { $transfer = new self(); $transfer->setBasePath($path); $transfer->setContainer($container); $transfer->setRemoteFiles($container->objectList()); + $transfer->setTargetDir($targetDir); return $transfer; } @@ -90,6 +92,14 @@ public function setContainer(Container $container) $this->container = $container; } + /** + * @param string $dir The target path that all files will be nested in. By default, the files will not be nested. + */ + public function setTargetDir($dir) + { + $this->targetDir = rtrim($dir, '/'); + } + /** * Execute the sync process. This will collect all the remote files from the API and do a comparison. There are * four scenarios that need to be dealt with: @@ -112,8 +122,9 @@ public function execute() // Handle PUT requests (create/update files) foreach ($localFiles as $filename) { + $remoteFilename = $this->targetDir ? $this->targetDir . '/' . $filename : $filename; - $callback = $this->getCallback($filename); + $callback = $this->getCallback($remoteFilename); $filePath = rtrim($this->basePath, '/') . '/' . $filename; if (!is_readable($filePath)) { @@ -134,7 +145,7 @@ public function execute() } else { // upload new file $url = clone $this->container->getUrl(); - $url->addPath($filename); + $url->addPath($remoteFilename); $requests[] = $this->container->getClient()->put($url, array(), $entityBody); } diff --git a/lib/OpenCloud/ObjectStore/Upload/TransferPart.php b/lib/OpenCloud/ObjectStore/Upload/TransferPart.php index 3da3f0162..a6de553c1 100644 --- a/lib/OpenCloud/ObjectStore/Upload/TransferPart.php +++ b/lib/OpenCloud/ObjectStore/Upload/TransferPart.php @@ -135,7 +135,7 @@ public function getPath() */ public static function createRequest($part, $number, $client, $options) { - $name = sprintf('%s/%s/%d', $options['objectName'], $options['prefix'], $number); + $name = sprintf('%s/%s/%05d', $options['objectName'], $options['prefix'], $number); $url = clone $options['containerUrl']; $url->addPath($name); diff --git a/lib/OpenCloud/OpenStack.php b/lib/OpenCloud/OpenStack.php index c0a415877..e970b9912 100644 --- a/lib/OpenCloud/OpenStack.php +++ b/lib/OpenCloud/OpenStack.php @@ -23,6 +23,7 @@ use OpenCloud\Common\Http\Message\Formatter; use OpenCloud\Common\Http\Message\RequestSubscriber; use OpenCloud\Common\Lang; +use OpenCloud\Common\Log\Logger; use OpenCloud\Common\Service\Catalog; use OpenCloud\Common\Service\ServiceBuilder; use OpenCloud\Identity\Resource\Tenant; @@ -78,6 +79,10 @@ class OpenStack extends Client public function __construct($url, array $secret, array $options = array()) { + if (isset($options['logger']) && $options['logger'] instanceof LoggerInterface) { + $this->setLogger($options['logger']); + } + $this->setSecret($secret); $this->setAuthUrl($url); @@ -123,7 +128,6 @@ public function setToken($token) $identity = IdentityService::factory($this); if (is_string($token)) { - if (!$this->token) { $this->setTokenObject($identity->resource('Token')); } @@ -146,7 +150,7 @@ public function getToken() } /** - * Set the full toke object + * Set the full token object */ public function setTokenObject(Token $token) { @@ -166,7 +170,7 @@ public function getTokenObject() */ public function setExpiration($expiration) { - $this->getLogger()->deprecated(__METHOD__, '::getTokenObject()->setExpires()'); + $this->getLogger()->warning(Logger::deprecated(__METHOD__, '::getTokenObject()->setExpires()')); if ($this->getTokenObject()) { $this->getTokenObject()->setExpires($expiration); } @@ -179,26 +183,25 @@ public function setExpiration($expiration) */ public function getExpiration() { - $this->getLogger()->deprecated(__METHOD__, '::getTokenObject()->getExpires()'); + $this->getLogger()->warning(Logger::deprecated(__METHOD__, '::getTokenObject()->getExpires()')); if ($this->getTokenObject()) { return $this->getTokenObject()->getExpires(); } } /** - * Set the tenant. If an integer is passed in, the SDK assumes you want to set the ID of the full Tenant object - * and sets this property accordingly. For any other data type, it assumes you want to populate the Tenant object. - * This ambiguity arises due to backwards compatibility. + * Set the tenant. If an integer or string is passed in, the SDK assumes you want to set the ID of the full + * Tenant object and sets this property accordingly. For any other data type, it assumes you want to populate + * the Tenant object. This ambiguity arises due to backwards compatibility. * - * @param string $tenant + * @param mixed $tenant * @return $this */ public function setTenant($tenant) { $identity = IdentityService::factory($this); - if (is_numeric($tenant)) { - + if (is_numeric($tenant) || is_string($tenant)) { if (!$this->tenant) { $this->setTenantObject($identity->resource('Tenant')); } @@ -287,12 +290,20 @@ public function getLogger() return $this->logger; } + /** + * @return bool + */ + public function hasLogger() + { + return (null !== $this->logger); + } + /** * @deprecated */ public function hasExpired() { - $this->getLogger()->deprecated(__METHOD__, 'getTokenObject()->hasExpired()'); + $this->getLogger()->warning(Logger::deprecated(__METHOD__, 'getTokenObject()->hasExpired()')); return $this->getTokenObject() && $this->getTokenObject()->hasExpired(); } @@ -306,7 +317,6 @@ public function hasExpired() public function getCredentials() { if (!empty($this->secret['username']) && !empty($this->secret['password'])) { - $credentials = array('auth' => array( 'passwordCredentials' => array( 'username' => $this->secret['username'], @@ -373,6 +383,10 @@ public function getUser() */ public function authenticate() { + // OpenStack APIs will return a 401 if an expired X-Auth-Token is sent, + // so we need to reset the value before authenticating for another one. + $this->updateTokenHeader(''); + $identity = IdentityService::factory($this); $response = $identity->generateToken($this->getCredentials()); @@ -387,7 +401,7 @@ public function authenticate() } // Set X-Auth-Token HTTP request header - $this->updateTokenHeader(); + $this->updateTokenHeader($this->getToken()); } /** @@ -425,7 +439,7 @@ public function importCredentials(array $values) { if (!empty($values['token'])) { $this->setToken($values['token']); - $this->updateTokenHeader(); + $this->updateTokenHeader($this->getToken()); } if (!empty($values['expiration'])) { $this->setExpiration($values['expiration']); @@ -441,13 +455,12 @@ public function importCredentials(array $values) /** * Sets the X-Auth-Token header. If no value is explicitly passed in, the current token is used. * - * @param string $token Optional value of token. + * @param string $token Value of header. * @return void */ - private function updateTokenHeader($token = null) + private function updateTokenHeader($token) { - $token = $token ? : $this->getToken(); - $this->setDefaultOption('headers/X-Auth-Token', (string)$token); + $this->setDefaultOption('headers/X-Auth-Token', (string) $token); } /** @@ -548,4 +561,40 @@ public function imageService($name = null, $region = null, $urltype = null) 'urlType' => $urltype )); } + + /** + * Creates a new Networking (Neutron) service object + * + * @param string $name The name of the service as it appears in the Catalog + * @param string $region The region (DFW, IAD, ORD, LON, SYD) + * @param string $urltype The URL type ("publicURL" or "internalURL") + * @return \OpenCloud\Networking\Service + * @codeCoverageIgnore + */ + public function networkingService($name = null, $region = null, $urltype = null) + { + return ServiceBuilder::factory($this, 'OpenCloud\Networking\Service', array( + 'name' => $name, + 'region' => $region, + 'urlType' => $urltype + )); + } + + /** + * Creates a new CDN (Poppy) service object + * + * @param string $name The name of the service as it appears in the Catalog + * @param string $region The region (DFW, IAD, ORD, LON, SYD) + * @param string $urltype The URL type ("publicURL" or "internalURL") + * @return \OpenCloud\Cdn\Service + * @codeCoverageIgnore + */ + public function cdnService($name = null, $region = null, $urltype = null) + { + return ServiceBuilder::factory($this, 'OpenCloud\CDN\Service', array( + 'name' => $name, + 'region' => $region, + 'urlType' => $urltype + )); + } } diff --git a/lib/OpenCloud/Orchestration/Resource.php b/lib/OpenCloud/Orchestration/Resource.php deleted file mode 100644 index 053b8e498..000000000 --- a/lib/OpenCloud/Orchestration/Resource.php +++ /dev/null @@ -1,87 +0,0 @@ -noCreate(); - } - - public function id() - { - return $this->physical_resource_id; - } - - protected function primaryKeyField() - { - return 'physical_resource_id'; - } - - public function name() - { - return $this->logical_resource_id; - } - - public function type() - { - return $this->resource_type; - } - - public function status() - { - return $this->resource_status; - } - - public function get() - { - $service = $this->getParent()->getService(); - - switch ($this->resource_type) { - case 'AWS::EC2::Instance': - $objSvc = 'Compute'; - $method = 'Server'; - $name = 'nova'; - break; - default: - throw new Exception(sprintf( - 'Unknown resource type: %s', - $this->resource_type - )); - } - - return $service->connection()->$objSvc($name, $service->region())->$method($this->id()); - } -} diff --git a/lib/OpenCloud/Orchestration/Resource/BuildInfo.php b/lib/OpenCloud/Orchestration/Resource/BuildInfo.php new file mode 100644 index 000000000..04152794c --- /dev/null +++ b/lib/OpenCloud/Orchestration/Resource/BuildInfo.php @@ -0,0 +1,40 @@ +refreshFromParent(); + } +} diff --git a/lib/OpenCloud/Orchestration/Resource/Event.php b/lib/OpenCloud/Orchestration/Resource/Event.php new file mode 100644 index 000000000..bf0da51a8 --- /dev/null +++ b/lib/OpenCloud/Orchestration/Resource/Event.php @@ -0,0 +1,54 @@ + 'time', + 'resource_name' => 'resourceName', + 'logical_resource_id' => 'resourceLogicalId', + 'physical_resource_id' => 'resourcePhysicalId', + 'resource_status' => 'resourceStatus', + 'resource_status_reason' => 'resourceStatusReason', + 'resource_type' => 'resourceType', + 'resource_properties' => 'resourceProperties' + ); +} diff --git a/lib/OpenCloud/Orchestration/Resource/Resource.php b/lib/OpenCloud/Orchestration/Resource/Resource.php new file mode 100644 index 000000000..431251e73 --- /dev/null +++ b/lib/OpenCloud/Orchestration/Resource/Resource.php @@ -0,0 +1,95 @@ + 'name', + 'resource_status' => 'status', + 'resource_status_reason' => 'statusReason', + 'logical_resource_id' => 'logicalId', + 'physical_resource_id' => 'physicalId', + 'required_by' => 'requiredBy', + 'updated_time' => 'updatedTime', + 'resource_type' => 'type' + ); + + public function primaryKeyField() + { + return 'name'; + } + + /** + * Returns metadata properties associated with this Resource + * + * @return \stdClass + */ + public function getMetadata() + { + $url = clone $this->getUrl(); + $url->addPath('metadata'); + + $response = $this->getClient()->get($url)->send(); + $json = Formatter::decode($response); + + return $json->metadata; + } + + /** + * Returns a list of Events associated with this Resource + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listEvents(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Event::resourceName())->setQuery($params); + + return $this->getService()->resourceList('Event', $url, $this); + } + + public function getEvent($id) + { + return $this->getService()->resource('Event', $id, $this); + } +} diff --git a/lib/OpenCloud/Orchestration/Resource/ResourceType.php b/lib/OpenCloud/Orchestration/Resource/ResourceType.php new file mode 100644 index 000000000..4f6a81bf9 --- /dev/null +++ b/lib/OpenCloud/Orchestration/Resource/ResourceType.php @@ -0,0 +1,61 @@ + 'resourceType', + 'properties' => 'resourceTypeProperties' + ); + + /** + * Returns the template representation for this resource type. + * + * @return String template representation + */ + public function getTemplate() + { + $url = clone $this->getUrl(); + $url->addPath('template'); + + $response = $this->getClient()->get($url)->send(); + return $response->getBody(true); + } + + protected function primaryKeyField() + { + return 'resourceType'; + } +} diff --git a/lib/OpenCloud/Orchestration/Resource/Stack.php b/lib/OpenCloud/Orchestration/Resource/Stack.php new file mode 100644 index 000000000..53162b1ec --- /dev/null +++ b/lib/OpenCloud/Orchestration/Resource/Stack.php @@ -0,0 +1,234 @@ + 'parentStack', + 'disable_rollback' => 'disableRollback', + 'stack_name' => 'name', + 'stack_status' => 'status', + 'stack_status_reason' => 'statusReason', + 'creation_time' => 'creationTime', + 'updated_time' => 'updatedTime', + 'timeout_mins' => 'timeoutMins', + 'template_url' => 'templateUrl', + 'adopt_stack_data' => 'adoptStackData' + ); + + protected $createKeys = array( + 'name', + 'templateUrl', + 'template', + 'environment', + 'files', + 'parameters', + 'timeoutMins', + 'adoptStackData' + ); + + protected $updateKeys = array( + 'templateUrl', + 'template', + 'environment', + 'files', + 'parameters', + 'timeoutMins' + ); + + protected function createJson() + { + $createJson = parent::createJson(); + return $createJson->{self::$json_name}; + } + + protected function updateJson($params = array()) + { + $updateJson = parent::updateJson($params); + return $updateJson->{self::$json_name}; + } + + /** + * Creates a new stack by adopting resources from an abandoned stack + * + * @param array $params Adopt stack parameters + * @return Guzzle\Http\Message\Response + */ + public function adopt($params) + { + // Validate that required parameters are provided + $requiredParameterName = 'adoptStackData'; + if (!array_key_exists($requiredParameterName, $params)) { + throw new \InvalidArgumentException($requiredParameterName . ' is a required option'); + } + + return $this->create($params); + } + + /** + * Previews the stack without actually creating it + * + * @param array $params Preview stack parameters + * @return Guzzle\Http\Message\Response + */ + public function preview($params = array()) + { + // set parameters + if (!empty($params)) { + $this->populate($params, false); + } + + // construct the JSON + $json = json_encode($this->createJson()); + $this->checkJsonError(); + + $previewUrl = $this->previewUrl(); + $response = $this->getClient()->post($previewUrl, self::getJsonHeader(), $json)->send(); + + $decoded = $this->parseResponse($response); + $this->populate($decoded); + + return $response; + } + + /** + * Abandons the stack and returns abandoned stack data. + * + * @return string Abandoned stack data (which could be passed to the adopt stack operation as adoptStackData). + */ + public function abandon() + { + $abandonUrl = $this->abandonUrl(); + $response = $this->getClient()->delete($abandonUrl)->send(); + return $response->getBody(true); + } + + /** + * Returns a Resource object associated with this Stack + * + * @param string $name Stack resource name + * @return Resource object + */ + public function getResource($name) + { + return $this->getService()->resource('Resource', $name, $this); + } + + /** + * Returns a list of Resources associated with this Stack + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listResources(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Resource::resourceName())->setQuery($params); + + return $this->getService()->resourceList('Resource', $url, $this); + } + + /** + * Returns a list of Events associated with this Stack + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listEvents(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Event::resourceName())->setQuery($params); + + return $this->getService()->resourceList('Event', $url, $this); + } + + /** + * Iterator use only + */ + public function event($id) + { + return $this->getService()->resource('Event', $id, $this); + } + + /** + * Returns the template for this stack. + * + * @return String template + */ + public function getStackTemplate() + { + $url = clone $this->getUrl(); + $url->addPath('template'); + + $response = $this->getClient()->get($url)->send(); + return $response->getBody(true); + } + + protected function previewUrl() + { + $url = clone $this->getParent()->getUrl(); + $url->addPath(self::resourceName()); + $url->addPath('preview'); + + return $url; + } + + protected function abandonUrl() + { + $url = clone $this->getUrl(); + $url->addPath('abandon'); + + return $url; + } + + protected function primaryKeyField() + { + return 'name'; + } +} diff --git a/lib/OpenCloud/Orchestration/Service.php b/lib/OpenCloud/Orchestration/Service.php index 14464e2c1..81c1a3e53 100644 --- a/lib/OpenCloud/Orchestration/Service.php +++ b/lib/OpenCloud/Orchestration/Service.php @@ -17,7 +17,12 @@ namespace OpenCloud\Orchestration; +use Guzzle\Http\Exception\ClientErrorResponseException; +use OpenCloud\Common\Exceptions\InvalidTemplateError; +use OpenCloud\Common\Http\Message\Formatter; use OpenCloud\Common\Service\CatalogService; +use OpenCloud\Orchestration\Resource\ResourceType; +use OpenCloud\Orchestration\Resource\Stack; /** * The Orchestration class represents the OpenStack Heat service. @@ -36,13 +41,138 @@ class Service extends CatalogService /** * Returns a Stack object associated with this Orchestration service * - * @api - * @param string $id - the stack with the ID is retrieved - * @returns Stack object + * @param string $name Name of stack to retrieve + * @return Stack object */ - public function stack($id = null) + public function stack($name = null) { - return new Stack($this, $id); + return $this->resource('Stack', $name); + } + + /** + * Previews a Stack from a template and returns it. + * + * @param array $params Stack preview parameters + * @return Stack Object representing previewed stack + */ + public function previewStack($params = array()) + { + $stack = $this->stack(); + $stack->preview($params); + return $stack; + } + + /** + * Creates a new Stack and returns it. + * + * @param array $params Stack creation parameters + * @return Stack Object representing created stack + */ + public function createStack($params = array()) + { + $stack = $this->stack(); + $stack->create($params); + return $stack; + } + + /** + * Adopts a Stack and returns it. + * + * @param array $params Stack adoption parameters + * @return Stack Object representing adopted stack + */ + public function adoptStack($params = array()) + { + $stack = $this->stack(); + $stack->adopt($params); + return $stack; + } + + /** + * Returns a Stack object associated with this Orchestration service + * + * @param string $name Name of stack to retrieve + * @return Stack object + */ + public function getStack($name) + { + return $this->stack($name); + } + + /** + * Returns a list of stacks you created + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listStacks(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(Stack::resourceName())->setQuery($params); + + return $this->resourceList('Stack', $url); + } + + /** + * Returns a list of resource types available + * + * @param array $params + * @return \OpenCloud\Common\Collection\PaginatedIterator + */ + public function listResourceTypes(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath(ResourceType::resourceName())->setQuery($params); + + return $this->resourceList('ResourceType', $url); + } + + /** + * Returns a ResourceType object associated with this Orchestration service + * + * @param string $id - the resource type with the ID is retrieved + * @return ResourceType object + */ + public function getResourceType($id) + { + return $this->resource('ResourceType', $id); + } + + /** + * Returns a BuildInfo object associated with this Orchestration service + * + * @return BuildInfo object + */ + public function getBuildInfo() + { + $buildInfo = $this->resource('BuildInfo'); + $buildInfo->refresh(); + return $buildInfo; + } + + /** + * Validates the given template + * + * @throws InvalidTemplateError if template is invalid + */ + public function validateTemplate(array $params = array()) + { + $url = clone $this->getUrl(); + $url->addPath('validate'); + + // Aliases + if (array_key_exists('templateUrl', $params)) { + $params['template_url'] = $params['templateUrl']; + } + + $json = json_encode($params); + + try { + $this->getClient()->post($url, self::getJsonHeader(), $json)->send(); + } catch (ClientErrorResponseException $e) { + $response = Formatter::decode($e->getResponse()); + throw new InvalidTemplateError($response->explanation, $response->code); + } } /** diff --git a/lib/OpenCloud/Orchestration/Stack.php b/lib/OpenCloud/Orchestration/Stack.php deleted file mode 100644 index 5452cd8fc..000000000 --- a/lib/OpenCloud/Orchestration/Stack.php +++ /dev/null @@ -1,205 +0,0 @@ -primaryKeyField(); - - if (!empty($this->{$pk})) { - throw new CreateError(sprintf( - 'Stack is already created and has ID of %s', - $this->$pk - )); - } - - $object = (object) array('disable_rollback' => false, 'timeout_mins' => 60); - - foreach ($this->createKeys as $property) { - if (empty($this->$property)) { - throw new CreateError(sprintf( - 'Cannot create Stack with null %s', - $property - )); - } else { - $object->$property = $this->$property; - } - } - - if (null !== $this->parameters) { - $object->parameters = $this->parameters; - } - - return $object; - } - - public function name() - { - return $this->stack_name; - } - - public function status() - { - return $this->stack_status; - } - - public function resource($id = null) - { - $resource = new Resource($this->getService()); - $resource->setParent($this); - $resource->populate($id); - - return $resource; - } - - public function resources() - { - return $this->getService()->collection( - 'OpenCloud\Orchestration\Resource', - $this->url('resources'), - $this - ); - } -} diff --git a/lib/OpenCloud/Queues/Collection/MessageIterator.php b/lib/OpenCloud/Queues/Collection/MessageIterator.php new file mode 100644 index 000000000..0f4140936 --- /dev/null +++ b/lib/OpenCloud/Queues/Collection/MessageIterator.php @@ -0,0 +1,29 @@ +nextUrl || + ($this->position % $this->getOption('limit.page') == 0); + } +} diff --git a/lib/OpenCloud/Queues/Resource/Claim.php b/lib/OpenCloud/Queues/Resource/Claim.php index fbc338467..5d4e2dc21 100644 --- a/lib/OpenCloud/Queues/Resource/Claim.php +++ b/lib/OpenCloud/Queues/Resource/Claim.php @@ -25,7 +25,6 @@ */ class Claim extends PersistentObject { - const LIMIT_DEFAULT = 10; const GRACE_DEFAULT = 43200; const TTL_DEFAULT = 43200; @@ -115,7 +114,7 @@ public function create($params = array()) /** * Updates the current Claim. It is recommended that you periodically renew - * claims during long-running batches of work to avoid loosing a claim in + * claims during long-running batches of work to avoid losing a claim in * the middle of processing a message. This is done by setting a new TTL for * the claim (which may be different from the original TTL). The server will * then reset the age of the claim and apply the new TTL. diff --git a/lib/OpenCloud/Queues/Resource/Message.php b/lib/OpenCloud/Queues/Resource/Message.php index 38ea3e775..f1164717f 100644 --- a/lib/OpenCloud/Queues/Resource/Message.php +++ b/lib/OpenCloud/Queues/Resource/Message.php @@ -28,7 +28,6 @@ */ class Message extends PersistentObject { - /** * @var string */ diff --git a/lib/OpenCloud/Queues/Resource/Queue.php b/lib/OpenCloud/Queues/Resource/Queue.php index ea367e682..b6817e0d6 100644 --- a/lib/OpenCloud/Queues/Resource/Queue.php +++ b/lib/OpenCloud/Queues/Resource/Queue.php @@ -22,6 +22,7 @@ use OpenCloud\Common\Http\Message\Formatter; use OpenCloud\Common\Resource\PersistentResource; use OpenCloud\Queues\Exception; +use OpenCloud\Queues\Collection\MessageIterator; use OpenCloud\Common\Metadata; /** @@ -211,7 +212,6 @@ public function createMessages(array $messages) ->send(); if (null !== ($location = $response->getHeader('Location'))) { - $parts = array_merge($this->getUrl()->getParts(), parse_url($location)); $url = Url::factory(Url::buildUrl($parts)); @@ -251,7 +251,7 @@ public function createMessages(array $messages) * messages as well as unclaimed messages. If not specified, defaults * to FALSE (i.e. only unclaimed messages are returned). * - * @return Collection + * @return \OpenCloud\Queues\Collection\MessageIterator */ public function listMessages(array $options = array()) { @@ -277,7 +277,7 @@ public function listMessages(array $options = array()) 'limit.page' => 10 ); - return PaginatedIterator::factory($this, $options); + return MessageIterator::factory($this, $options); } /** diff --git a/lib/OpenCloud/Queues/Service.php b/lib/OpenCloud/Queues/Service.php index 738e4eec4..506555b4e 100644 --- a/lib/OpenCloud/Queues/Service.php +++ b/lib/OpenCloud/Queues/Service.php @@ -21,6 +21,7 @@ use Guzzle\Http\Exception\BadResponseException; use OpenCloud\Common\Exceptions\InvalidArgumentError; use OpenCloud\Common\Service\CatalogService; +use OpenCloud\Queues\Resource\Queue; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -117,7 +118,10 @@ public function getClientId() /** * Create a new Queue. * - * @param $name Name of the new queue + * @param string $name Name of the new queue + * + * @throws InvalidArgumentError + * * @return Queue */ public function createQueue($name) diff --git a/lib/OpenCloud/Rackspace.php b/lib/OpenCloud/Rackspace.php index d657f37b1..40473a4b0 100644 --- a/lib/OpenCloud/Rackspace.php +++ b/lib/OpenCloud/Rackspace.php @@ -54,7 +54,6 @@ public function getCredentials() $secret = $this->getSecret(); if (!empty($secret['username']) && !empty($secret['apiKey'])) { - $credentials = array('auth' => array( 'RAX-KSKEY:apiKeyCredentials' => array( 'username' => $secret['username'], @@ -175,4 +174,23 @@ public function queuesService($name = null, $region = null, $urltype = null) 'urlType' => $urltype )); } + + /** + * Creates a new CDN (Rackspace CDN) service object + * + * @param string $name The name of the service as it appears in the Catalog + * @param string $region The region (DFW, IAD, ORD, LON, SYD) + * @param string $urltype The URL type ("publicURL" or "internalURL") + * @return \OpenCloud\Cdn\Service + * @codeCoverageIgnore + */ + public function cdnService($name = null, $region = null, $urltype = null) + { + return ServiceBuilder::factory($this, 'OpenCloud\CDN\Service', array( + 'name' => $name, + 'type' => 'rax:cdn', + 'region' => $region, + 'urlType' => $urltype + )); + } } diff --git a/lib/OpenCloud/Version.php b/lib/OpenCloud/Version.php index d882bd145..2072ec8ec 100644 --- a/lib/OpenCloud/Version.php +++ b/lib/OpenCloud/Version.php @@ -27,7 +27,7 @@ */ class Version { - const VERSION = '1.10.0'; + const VERSION = '1.14.2'; /** * @return string Indicate current SDK version. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cd44e77df..c2aeed2d4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -25,4 +25,9 @@ + + + + + diff --git a/samples/CDN/create-flavor.php b/samples/CDN/create-flavor.php new file mode 100644 index 000000000..5e2433ad7 --- /dev/null +++ b/samples/CDN/create-flavor.php @@ -0,0 +1,47 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Create flavor. +$flavor = $cdnFlavor->createFlavor(array( + 'id' => '{flavorId}', + 'providers' => array( + array( + 'provider' => 'akamai', + 'links' => array( + array( + 'rel' => 'provider_url', + 'href' => 'http://www.akamai.com' + ) + ) + ) + ) +)); +/** @var $flavor OpenCloud\CDN\Resource\Flavor **/ diff --git a/samples/CDN/create-service.php b/samples/CDN/create-service.php new file mode 100644 index 000000000..102fd1f18 --- /dev/null +++ b/samples/CDN/create-service.php @@ -0,0 +1,43 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Create service. +$service = $cdnService->createService(array( + 'name' => '{name}', + 'domains' => array( + array('domain' => '{domainName}') + ), + 'origins' => array( + array('origin' => '{originAddress}') + ), + 'flavorId' => '{flavorId}' +)); +/** @var $service OpenCloud\CDN\Resource\Service **/ diff --git a/samples/CDN/delete-flavor.php b/samples/CDN/delete-flavor.php new file mode 100644 index 000000000..28f901c50 --- /dev/null +++ b/samples/CDN/delete-flavor.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get flavor. +$flavor = $cdnFlavor->getFlavor('{flavorId}'); + +// 4. Delete it. +$flavor->delete(); diff --git a/samples/CDN/delete-service.php b/samples/CDN/delete-service.php new file mode 100644 index 000000000..2b223cdf7 --- /dev/null +++ b/samples/CDN/delete-service.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get service. +$service = $cdnService->getService('{serviceId}'); + +// 4. Delete it. +$service->delete(); diff --git a/samples/CDN/get-flavor.php b/samples/CDN/get-flavor.php new file mode 100644 index 000000000..90e605c21 --- /dev/null +++ b/samples/CDN/get-flavor.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get flavor. +$flavor = $cdnService->getFlavor('{flavorId}'); +/** @var $flavor OpenCloud\CDN\Resource\Flavor **/ diff --git a/samples/CDN/get-service.php b/samples/CDN/get-service.php new file mode 100644 index 000000000..113d4ae24 --- /dev/null +++ b/samples/CDN/get-service.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get service. +$service = $cdnService->getService('{serviceId}'); +/** @var $service OpenCloud\CDN\Resource\Service **/ diff --git a/samples/CDN/list-flavors.php b/samples/CDN/list-flavors.php new file mode 100644 index 000000000..8ddf9c4ce --- /dev/null +++ b/samples/CDN/list-flavors.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get flavor list. +$flavors = $cdnService->listFlavors(); +foreach ($flavors as $flavor) { + /** @var $flavor OpenCloud\CDN\Resource\Flavor **/ +} diff --git a/samples/CDN/list-services.php b/samples/CDN/list-services.php new file mode 100644 index 000000000..67f5d63a4 --- /dev/null +++ b/samples/CDN/list-services.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get service list. +$services = $cdnService->listServices(); +foreach ($services as $service) { + /** @var $service OpenCloud\CDN\Resource\Service **/ +} diff --git a/samples/CDN/purge-cached-service-asset.php b/samples/CDN/purge-cached-service-asset.php new file mode 100644 index 000000000..fdb2f97c4 --- /dev/null +++ b/samples/CDN/purge-cached-service-asset.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get service. +$service = $cdnService->getService('{serviceId}'); + +// 4. Purge a specific asset belonging to service. +$service->purgeAssets('{assetUrl}'); diff --git a/samples/CDN/purge-cached-service-assets.php b/samples/CDN/purge-cached-service-assets.php new file mode 100644 index 000000000..afc9cb1c6 --- /dev/null +++ b/samples/CDN/purge-cached-service-assets.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get service. +$service = $cdnService->getService('{serviceId}'); + +// 4. Purge all assets belonging to service. +$service->purgeAssets(); diff --git a/samples/CDN/update-service.php b/samples/CDN/update-service.php new file mode 100644 index 000000000..8f5c9db6f --- /dev/null +++ b/samples/CDN/update-service.php @@ -0,0 +1,44 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an CDN service object from the client. +$cdnService = $client->cdnService(); + +// 3. Get service. +$service = $cdnService->getService('{serviceId}'); + +// 4. Update it. +$service->update(array( + 'origins' => array( + array( + 'origin' => '44.33.22.11', + 'port' => 80, + 'ssl' => false + ) + ) +)); diff --git a/samples/Compute/attach_volume.php b/samples/Compute/attach_volume.php index 7353e3aa6..84b05b70e 100644 --- a/samples/Compute/attach_volume.php +++ b/samples/Compute/attach_volume.php @@ -1,5 +1,4 @@ getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Crete Compute and Volume service objects -$region = 'ORD'; - -$volumeService = $client->volumeService(null, $region); -$computeService = $client->computeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); +$computeService = $client->computeService(null, '{region}'); // 3. Get your volume -$volumeId = '{volumeId}'; -$myVolume = $volumeService->volume($volumeId); +$myVolume = $volumeService->volume('{volumeId}'); // 4. Get your server -$serverId = '{serverId}'; -$myServer = $computeService->server($serverId); - -// 5. Attach +$myServer = $computeService->server('{serverId}'); -// Specifying null will auto-assign the block. You also can be specific - '/dev/xvdb' +// 5. Attach. Specifying null will auto-assign the block. You also can be specific: '/dev/xvdb' $mountPoint = null; -$myServer->attachVolume($myVolume, $mountPoint); \ No newline at end of file +$myServer->attachVolume($myVolume, $mountPoint); diff --git a/samples/Compute/create_network.php b/samples/Compute/create_network.php index ea19005b7..5f8c38fbe 100644 --- a/samples/Compute/create_network.php +++ b/samples/Compute/create_network.php @@ -1,5 +1,4 @@ getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service object -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get empty network $network = $service->network(); @@ -45,4 +36,4 @@ $network->create(array( 'label' => 'Backend Network', 'cidr' => '192.168.0.0/16' -)); \ No newline at end of file +)); diff --git a/samples/Compute/create_new_keypair.php b/samples/Compute/create_new_keypair.php index 83f14a5a1..c00df6e8c 100644 --- a/samples/Compute/create_new_keypair.php +++ b/samples/Compute/create_new_keypair.php @@ -1,5 +1,4 @@ getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service object -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get empty keypair $keypair = $service->keypair(); @@ -46,7 +40,8 @@ echo $keypair->getPublicKey(); // 5. Save private key to a file so you can use it to SSH into your server later -$sshPrivateKeyFilename = 'new_keypair_private'; +$filename = 'new_keypair_private'; $privateKey = $keypair->getPrivateKey(); -file_put_contents($sshPrivateKeyFilename, $privateKey); -chmod($sshPrivateKeyFilename, 0600); \ No newline at end of file + +file_put_contents($filename, $privateKey); +chmod($filename, 0600); diff --git a/samples/Compute/create_server.php b/samples/Compute/create_server.php index 9dd118b2a..e6ca5ee3e 100644 --- a/samples/Compute/create_server.php +++ b/samples/Compute/create_server.php @@ -16,69 +16,36 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, and - * - RAX_API_KEY: Your Rackspace Cloud Account API Key - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; use Guzzle\Http\Exception\BadResponseException; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get empty server $server = $service->server(); -// 4. Select an OS image -$images = $service->imageList(); -foreach ($images as $image) { - if (strpos($image->name, 'Ubuntu') !== false) { - $ubuntuImage = $image; - break; - } -} - -// 5. Select a hardware flavor -$flavors = $service->flavorList(); -foreach ($flavors as $flavor) { - if (strpos($flavor->name, '2GB') !== false) { - $twoGbFlavor = $flavor; - break; - } -} - -// 6. Create +// 4. Create try { $response = $server->create(array( - 'name' => 'My lovely server', - 'image' => $ubuntuImage, - 'flavor' => $twoGbFlavor + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}' )); } catch (BadResponseException $e) { - // No! Something failed. Let's find out: - $badResponse = $e->getResponse(); - echo sprintf( - 'Status: %s\nBody: %s\nHeaders: %s', - $badResponse->getStatusCode(), - $badResponse->getBody(true), - implode(', ', $response->getHeaderLines()) - ); + echo $e->getResponse(); } $body = json_decode($response->getBody(true)); // THIS IS YOUR ROOT PASSWORD - DO NOT LOSE! -$password = $body->server->adminPass; \ No newline at end of file +$password = $body->server->adminPass; diff --git a/samples/Compute/create_server_and_get_ip.php b/samples/Compute/create_server_and_get_ip.php new file mode 100644 index 000000000..3f0bbfe6f --- /dev/null +++ b/samples/Compute/create_server_and_get_ip.php @@ -0,0 +1,54 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Create Compute service +$service = $client->computeService(null, '{region}'); + +// 3. Get empty server +$server = $service->server(); + +// 4. Create the server. If you do not know what imageId or flavorId to use, +// please run the list_flavors.php and list_images.php scripts. +try { + $response = $server->create(array( + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}' + )); +} catch (BadResponseException $e) { + echo $e->getResponse(); +} + +// 5. Wait for the server to become ACTIVE. +$server->waitFor(ServerState::ACTIVE); + +// 6. Retrieve the server's IP +$ipv4Address = $server->accessIPv4; diff --git a/samples/Compute/create_server_from_bootable_volume.php b/samples/Compute/create_server_from_bootable_volume.php index 65d822086..3be223a90 100644 --- a/samples/Compute/create_server_from_bootable_volume.php +++ b/samples/Compute/create_server_from_bootable_volume.php @@ -16,54 +16,40 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, - * - RAX_API_KEY: Your Rackspace Cloud Account API Key, - * - RAX_REGION: Rackspace Cloud region in which to create server; e.g.: DFW, - * - RAX_BOOTABLE_VOLUME_ID: ID of bootable volume in Rackspace Cloud region, and - * - RAX_FLAVOR_ID: ID of a compute flavor (performance or higher) in the Rackspace Cloud; e.g.: performance1-1. - * - * - You have an existing keypair. For this script, it will be called 'my_keypair' - * but this will change depending on what you called yours. - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; use Guzzle\Http\Exception\BadResponseException; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service -$region = getenv('RAX_REGION'); -$computeService = $client->computeService(null, $region); -$volumeService = $client->volumeService(null, $region); +$computeService = $client->computeService(null, '{region}'); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get empty server $server = $computeService->server(); // 4. Select bootable volume -$bootableVolume = $volumeService->volume(getenv('RAX_BOOTABLE_VOLUME_ID')); +$bootableVolume = $volumeService->volume('{volumeId}'); // 5. Select a hardware flavor -$flavor = $computeService->flavor(getenv('RAX_FLAVOR_ID')); +$flavor = $computeService->flavor('{flavorId}'); -// 6. Create +// 6. Create the server. If you do not know what imageId or flavorId to use, +// please run the list_flavors.php and list_images.php scripts. try { $response = $server->create(array( - 'name' => 'My server created from a bootable volume', - 'volume' => $bootableVolume, - 'flavor' => $flavor + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + 'volume' => $bootableVolume )); } catch (BadResponseException $e) { - // No! Something failed. Let's find out: - echo $e->getRequest() . PHP_EOL . PHP_EOL; echo $e->getResponse(); -} \ No newline at end of file +} diff --git a/samples/Compute/create_server_from_bootable_volume_delete_on_termination.php b/samples/Compute/create_server_from_bootable_volume_delete_on_termination.php index 923b4339d..3b6425a6a 100644 --- a/samples/Compute/create_server_from_bootable_volume_delete_on_termination.php +++ b/samples/Compute/create_server_from_bootable_volume_delete_on_termination.php @@ -16,56 +16,43 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, - * - RAX_API_KEY: Your Rackspace Cloud Account API Key, - * - RAX_REGION: Rackspace Cloud region in which to create server; e.g.: DFW, - * - RAX_BOOTABLE_VOLUME_ID: ID of bootable volume in Rackspace Cloud region, and - * - RAX_FLAVOR_ID: ID of a compute flavor (performance or higher) in the Rackspace Cloud; e.g.: performance1-1. - * - * - You have an existing keypair. For this script, it will be called 'my_keypair' - * but this will change depending on what you called yours. - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; use Guzzle\Http\Exception\BadResponseException; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service -$region = getenv('RAX_REGION'); -$computeService = $client->computeService(null, $region); -$volumeService = $client->volumeService(null, $region); +$computeService = $client->computeService(null, '{region}'); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get empty server $server = $computeService->server(); // 4. Select bootable volume -$bootableVolume = $volumeService->volume(getenv('RAX_BOOTABLE_VOLUME_ID')); +$bootableVolume = $volumeService->volume('{volumeId}'); // 5. Select a hardware flavor -$flavor = $computeService->flavor(getenv('RAX_FLAVOR_ID')); +$flavor = $computeService->flavor('{flavorId}'); // 6. Create server from bootable volume, setting the volume to be -// deleted when the server is terminated (deleted). +// deleted when the server is terminated (deleted). If you do not know what +// imageId or flavorId to use, please run the list_flavors.php and +// list_images.php scripts. try { $response = $server->create(array( - 'name' => 'My server created from a bootable volume', - 'volume' => $bootableVolume, - 'volumeDeleteOnTermination' => true, - 'flavor' => $flavor + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + 'volume' => $bootableVolume, + 'volumeDeleteOnTermination' => true )); } catch (BadResponseException $e) { - // No! Something failed. Let's find out: - echo $e->getRequest() . PHP_EOL . PHP_EOL; echo $e->getResponse(); -} \ No newline at end of file +} diff --git a/samples/Compute/create_server_with_availability_zone.php b/samples/Compute/create_server_with_availability_zone.php new file mode 100644 index 000000000..cf4b1f4bc --- /dev/null +++ b/samples/Compute/create_server_with_availability_zone.php @@ -0,0 +1,48 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Create Compute service +$service = $client->computeService('nova', '{region}'); + +// 3. Get empty server +$server = $service->server(); + +// 4. Create the server. If you do not know what imageId or flavorId to use, +// please run the list_flavors.php and list_images.php scripts. +try { + $response = $server->create(array( + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + 'availabilityZone' => '{availabilityZone}' + )); +} catch (BadResponseException $e) { + echo $e->getResponse(); +} diff --git a/samples/Compute/create_server_with_keypair.php b/samples/Compute/create_server_with_keypair.php index a6a4dc285..45a655664 100644 --- a/samples/Compute/create_server_with_keypair.php +++ b/samples/Compute/create_server_with_keypair.php @@ -16,68 +16,33 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, and - * - RAX_API_KEY: Your Rackspace Cloud Account API Key - * - * - You have an existing keypair. For this script, it will be called 'my_keypair' - * but this will change depending on what you called yours. - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; use Guzzle\Http\Exception\BadResponseException; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get empty server $server = $service->server(); -// 4. Select an OS image -$images = $service->imageList(); -foreach ($images as $image) { - if (strpos($image->name, 'Ubuntu') !== false) { - $ubuntuImage = $image; - break; - } -} - -// 5. Select a hardware flavor -$flavors = $service->flavorList(); -foreach ($flavors as $flavor) { - if (strpos($flavor->name, '2GB') !== false) { - $twoGbFlavor = $flavor; - break; - } -} - -// 6. Create +// 4. Create the server. If you do not know what imageId or flavorId to use, +// please run the list_flavors.php and list_images.php scripts. try { $response = $server->create(array( - 'name' => 'My lovely server', - 'image' => $ubuntuImage, - 'flavor' => $twoGbFlavor, - 'keypair' => 'my_keypair' // Enter your own keypair name + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + 'keypair' => '{keypairName}' )); } catch (BadResponseException $e) { - // No! Something failed. Let's find out: - $badResponse = $e->getResponse(); - echo sprintf( - 'Status: %s\nBody: %s\nHeaders: %s', - $badResponse->getStatusCode(), - $badResponse->getBody(true), - implode(', ', $response->getHeaderLines()) - ); -} \ No newline at end of file + echo $e->getResponse(); +} diff --git a/samples/Compute/create_server_with_network.php b/samples/Compute/create_server_with_network.php new file mode 100644 index 000000000..cf66486c8 --- /dev/null +++ b/samples/Compute/create_server_with_network.php @@ -0,0 +1,56 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$computeService = $client->computeService(null, '{region}'); +$networkService = $client->networkingService(null, '{region}'); + +// Retrieve your custom network +$customNetwork = $networkService->getNetwork('{networkId}'); + +// Set up an empty server +$server = $computeService->server(); + +// Create the server. If you do not know what imageId or flavorId to use, +// please run the list_flavors.php and list_images.php scripts. +try { + $response = $server->create(array( + 'name' => '{serverName}', + 'imageId' => '{imageId}', + 'flavorId' => '{flavorId}', + 'networks' => array( + $customNetwork, + $computeService->network(Network::RAX_PRIVATE), + $computeService->network(Network::RAX_PUBLIC), + ), + )); +} catch (BadResponseException $e) { + echo $e->getResponse(); +} diff --git a/samples/Compute/create_volume.php b/samples/Compute/create_volume.php index ffd334928..8bfc67b41 100644 --- a/samples/Compute/create_volume.php +++ b/samples/Compute/create_volume.php @@ -16,42 +16,25 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, and - * - RAX_API_KEY: Your Rackspace Cloud Account API Key - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Volume service object -$region = 'ORD'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get empty volume $myVolume = $volumeService->volume(); -// 4. Pick a volume type - -// Option a: traverse through list -$volumeTypes = $volumeService->volumeTypeList(); -foreach ($volumeTypes as $volumeType) { - if ($volumeType->name == 'SSD') { - break; - } -} - -// Option b: pass in UUID if you already know which one you want +// 4. Pick a volume type by passing in UUID. If you do not know this, please +// run the list_volume_types.php script. $volumeType = $volumeService->volumeType('{volumeTypeId}'); // 5. Create @@ -60,4 +43,4 @@ 'volume_type' => $volumeType, 'display_name' => 'My Volume', 'display_description' => 'Used for large object storage' -)); \ No newline at end of file +)); diff --git a/samples/Compute/delete_server.php b/samples/Compute/delete_server.php index 6e49f8971..e3e433d47 100644 --- a/samples/Compute/delete_server.php +++ b/samples/Compute/delete_server.php @@ -16,34 +16,22 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, and - * - RAX_API_KEY: Your Rackspace Cloud Account API Key - * - * - There exists a server named 'my_server' and you know its ID. Run - * create_server.php if you need to create one first. - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service object -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get your existing server -$serverId = '7af22b0d-7d01-4460-a222-77e65a9ab184'; -$server = $service->server($serverId); +$server = $service->server('{serverId}'); // 4. Delete it -$server->delete(); \ No newline at end of file +$server->delete(); diff --git a/samples/Compute/detach_volume.php b/samples/Compute/detach_volume.php index c69a5e4e7..d0dc3580e 100644 --- a/samples/Compute/detach_volume.php +++ b/samples/Compute/detach_volume.php @@ -16,42 +16,26 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, and - * - RAX_API_KEY: Your Rackspace Cloud Account API Key - * - * - There exists a server named 'my_server' and you know its ID. Run - * create_server.php if you need to create one first. - * - There exists a volume name 'my_volume' and you know its ID. Run - * create_volume.php if you need to create one first. - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Crete Compute and Volume service objects -$region = 'ORD'; - -$volumeService = $client->volumeService(null, $region); -$computeService = $client->computeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); +$computeService = $client->computeService(null, '{region}'); // 3. Get your volume -$volumeId = '{volumeId}'; -$myVolume = $volumeService->volume($volumeId); +$myVolume = $volumeService->volume('{volumeId}'); // 4. Get your server -$serverId = '{serverId}'; -$myServer = $computeService->server($serverId); +$myServer = $computeService->server('{serverId}'); // 5. Detach -$myServer->detachVolume($myVolume); \ No newline at end of file +$myServer->detachVolume($myVolume); diff --git a/samples/Compute/list_flavors.php b/samples/Compute/list_flavors.php new file mode 100644 index 000000000..17f9dc371 --- /dev/null +++ b/samples/Compute/list_flavors.php @@ -0,0 +1,38 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Compute service object from the client. +$computeService = $client->computeService(null, '{region}'); + +// 3. Get the list of flavors. +$images = $service->flavorList(); + +// 4. Traverse +foreach ($flavors as $flavor) { + printf("ID: %s, Name: %s\n", $flavor->id, $flavor->name); +} diff --git a/samples/Compute/list_images.php b/samples/Compute/list_images.php new file mode 100644 index 000000000..03cfcbe9d --- /dev/null +++ b/samples/Compute/list_images.php @@ -0,0 +1,38 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Compute service object from the client. +$computeService = $client->computeService(null, '{region}'); + +// 3. Get the list of images. +$images = $service->imageList(); + +// 4. Traverse +foreach ($images as $image) { + printf("ID: %s, Name: %s\n", $image->id, $image->name); +} diff --git a/samples/Compute/list_servers.php b/samples/Compute/list_servers.php index 2712eb6c7..1cb88e777 100644 --- a/samples/Compute/list_servers.php +++ b/samples/Compute/list_servers.php @@ -15,33 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Compute service object from the client. -$region = 'DFW'; -$computeService = $client->computeService(null, $region); +$computeService = $client->computeService(null, '{region}'); // 3. Get the list of servers. $serverList = $computeService->serverList(); +// 4. Traverse over the list and output key information. foreach ($serverList as $server) { - echo str_repeat("-", 80) . PHP_EOL; - echo "ID: " . $server->id() . " | " - . "Name: " . $server->name() . " | " - . "Image ID: " . $server->image->id . PHP_EOL; - echo str_repeat("-", 80) . PHP_EOL; + printf("ID: %s, Name: %s, Image ID: %s\n", $server->id(), $server->name(), $server->image->id); } diff --git a/samples/Compute/list_volume_types.php b/samples/Compute/list_volume_types.php new file mode 100644 index 000000000..e10854b3c --- /dev/null +++ b/samples/Compute/list_volume_types.php @@ -0,0 +1,38 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Volume service object from the client. +$service = $client->volumeService(null, $region); + +// 3. Get a collection of volume types. +$volumeTypes = $service->volumeTypeList(); + +// 4. Traverse. +foreach ($volumeTypes as $volumeType) { + printf("ID: %s, Name: %s\n", $volumeType->id, $volumeType->name); +} diff --git a/samples/Compute/update_server.php b/samples/Compute/update_server.php index 9c7785d94..847b0836e 100644 --- a/samples/Compute/update_server.php +++ b/samples/Compute/update_server.php @@ -16,37 +16,25 @@ * limitations under the License. */ -/** - * Pre-requisites: - * - * Prior to running this script, you must setup the following environment variables: - * - RAX_USERNAME: Your Rackspace Cloud Account Username, and - * - RAX_API_KEY: Your Rackspace Cloud Account API Key - * - * - There exists a server named 'my_server' and you know its ID. Run - * create_server.php if you need to create one first. - */ - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service object -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get your existing server -$serverId = '{serverId}'; -$server = $service->server($serverId); +$server = $service->server('{serverId}'); // 4. Update it - here we'll change its name, but you can also update its // `accessIPv4' and `accessIPv6' attributes. $server->update(array( 'name' => 'new_awesome_name' -)); \ No newline at end of file +)); diff --git a/samples/Compute/upload_existing_keypair.php b/samples/Compute/upload_existing_keypair.php index 36d3385d1..12b81daab 100644 --- a/samples/Compute/upload_existing_keypair.php +++ b/samples/Compute/upload_existing_keypair.php @@ -16,24 +16,19 @@ * limitations under the License. */ -// Pre-requisites -// Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key - -require dirname(__DIR__) . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Create Compute service object -$region = 'ORD'; -$service = $client->computeService(null, $region); +$service = $client->computeService(null, '{region}'); // 3. Get empty keypair $keypair = $service->keypair(); @@ -46,4 +41,4 @@ $keypair->create(array( 'name' => 'new_public_key', 'publicKey' => $payload -)); \ No newline at end of file +)); diff --git a/samples/Database/create-configuration.php b/samples/Database/create-configuration.php index c744404ef..d884af0d5 100644 --- a/samples/Database/create-configuration.php +++ b/samples/Database/create-configuration.php @@ -15,38 +15,31 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * OS_REGION_NAME: OpenStack Cloud region where database configuations are created -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Create a configuration. $configuration = $databaseService->configuration(); $configuration->create(array( - 'name' => 'example-configuration-name', + 'name' => 'example-configuration-name', 'description' => 'An example configuration', - 'values' => array( + 'values' => array( 'collation_server' => 'latin1_swedish_ci', - 'connect_timeout' => 120 + 'connect_timeout' => 120 ), 'datastore' => array( - 'type' => '10000000-0000-0000-0000-000000000001', + 'type' => '10000000-0000-0000-0000-000000000001', 'version' => '1379cc8b-4bc5-4c4a-9e9d-7a9ad27c0866' ) )); diff --git a/samples/Database/create-instance.php b/samples/Database/create-instance.php index cd31522c8..ba7117bb5 100644 --- a/samples/Database/create-instance.php +++ b/samples/Database/create-instance.php @@ -15,36 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, -// * OS_DB_INSTANCE_FLAVOR_ID: ID of flavor to use for database instance, -// * OS_DB_INSTANCE_NAME: Name of database instance, and -// * OS_DB_INSTANCE_SIZE: Size, in GB, of database instance volume -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Create a database instance. $dbInstance = $databaseService->instance(); $dbInstance->create(array( - 'name' => getenv('OS_DB_INSTANCE_NAME'), - 'flavor' => $databaseService->flavor(getenv('OS_DB_INSTANCE_FLAVOR_ID')), - 'volume' => array( - 'size' => getenv('OS_DB_INSTANCE_SIZE') - ) + 'name' => '{name}', + 'flavor' => $databaseService->flavor('{flavorId}'), + 'volume' => array('size' => '{size}') )); diff --git a/samples/Database/delete-configuration.php b/samples/Database/delete-configuration.php index 43186a580..144ef228b 100644 --- a/samples/Database/delete-configuration.php +++ b/samples/Database/delete-configuration.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, and -// * OS_DB_CONFIGURATION_ID: ID of database configuration -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database configuration. -$configuration = $databaseService->configuration(getenv('OS_DB_CONFIGURATION_ID')); +$configuration = $databaseService->configuration('{configId}'); // 4. Delete it. -$configuration->delete(); \ No newline at end of file +$configuration->delete(); diff --git a/samples/Database/get-configuration.php b/samples/Database/get-configuration.php index 70c93c89c..352364c4c 100644 --- a/samples/Database/get-configuration.php +++ b/samples/Database/get-configuration.php @@ -15,28 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, and -// * OS_DB_CONFIGURATION_ID: ID of database configuration -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database configuration. -$configuration = $databaseService->configuration(getenv('OS_DB_CONFIGURATION_ID')); +$configuration = $databaseService->configuration('{configId}'); /** @var OpenCloud\Database\Resource\Configuration **/ diff --git a/samples/Database/get-datastore-version.php b/samples/Database/get-datastore-version.php index 9f8a1bc78..137a088e6 100644 --- a/samples/Database/get-datastore-version.php +++ b/samples/Database/get-datastore-version.php @@ -15,32 +15,23 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, -// * OS_DB_DATASTORE_ID: ID of database datastore, and -// * OS_DB_DATASTORE_VERSION_ID: Id of database datastore version -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database datastore. -$datastore = $databaseService->datastore(getenv('OS_DB_DATASTORE_ID')); +$datastore = $databaseService->datastore('{datastoreId}'); // 4. Retrieve the database datastore version. -$datastoreVersion = $datastore->version(getenv('OS_DB_DATASTORE_VERSION_ID')); +$datastoreVersion = $datastore->version('{datastoreVersionId}'); /** @var OpenCloud\Database\Resource\DatastoreVersion **/ diff --git a/samples/Database/get-datastore.php b/samples/Database/get-datastore.php index 19e0c7ca2..5c93d0615 100644 --- a/samples/Database/get-datastore.php +++ b/samples/Database/get-datastore.php @@ -15,28 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, and -// * OS_DB_DATASTORE_ID: ID of database datastore -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database datastore. -$datastore = $databaseService->datastore(getenv('OS_DB_DATASTORE_ID')); +$datastore = $databaseService->datastore('{datastoreId}'); /** @var OpenCloud\Database\Resource\Datastore **/ diff --git a/samples/Database/get-instance.php b/samples/Database/get-instance.php index 0696c683f..21ccdd420 100644 --- a/samples/Database/get-instance.php +++ b/samples/Database/get-instance.php @@ -15,28 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, and -// * OS_DB_INSTANCE_ID: ID of database instance -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database instance. -$instance = $databaseService->instance(getenv('OS_DB_INSTANCE_ID')); +$instance = $databaseService->instance('{instanceId}'); /** @var $instance OpenCloud\Database\Resource\Instance **/ diff --git a/samples/Database/list-configuration-instances.php b/samples/Database/list-configuration-instances.php index e86365ec4..0bb9cd18e 100644 --- a/samples/Database/list-configuration-instances.php +++ b/samples/Database/list-configuration-instances.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, and -// * OS_DB_CONFIGURATION_ID: ID of database configuration -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database configuration. -$configuration = $databaseService->configuration(getenv('OS_DB_CONFIGURATION_ID')); +$configuration = $databaseService->configuration('{configId}'); // 4. List instances using this configuration. $instances = $configuration->instanceList(); diff --git a/samples/Database/list-configurations.php b/samples/Database/list-configurations.php index 5755400f2..a25f87cc9 100644 --- a/samples/Database/list-configurations.php +++ b/samples/Database/list-configurations.php @@ -15,26 +15,19 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * OS_REGION_NAME: OpenStack Cloud region where database configuations are created -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{dbId}'); // 3. List configurations. $configurations = $databaseService->configurationList(); diff --git a/samples/Database/list-datastore-versions.php b/samples/Database/list-datastore-versions.php index 6fab90b06..3f2328f30 100644 --- a/samples/Database/list-datastore-versions.php +++ b/samples/Database/list-datastore-versions.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database version, and -// * OS_DB_DATASTORE_ID: ID of database datastore -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database datastore. -$datastore = $databaseService->datastore(getenv('OS_DB_DATASTORE_ID')); +$datastore = $databaseService->datastore('{datastoreId}'); // 4. List versions using this datastore. $versions = $datastore->versionList(); diff --git a/samples/Database/list-datastores.php b/samples/Database/list-datastores.php index 3cfdebc18..5d3389111 100644 --- a/samples/Database/list-datastores.php +++ b/samples/Database/list-datastores.php @@ -15,26 +15,19 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * OS_REGION_NAME: OpenStack Cloud region where database configuations are created -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. List datastores. $datastores = $databaseService->datastoreList(); diff --git a/samples/Database/list-instances.php b/samples/Database/list-instances.php index 077c32a35..6edd22f7a 100644 --- a/samples/Database/list-instances.php +++ b/samples/Database/list-instances.php @@ -15,26 +15,19 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * OS_REGION_NAME: OpenStack Cloud region where database instances are created -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. List instances. $instances = $databaseService->instanceList(); diff --git a/samples/Database/patch-configuration.php b/samples/Database/patch-configuration.php index e403d5dc2..60488021e 100644 --- a/samples/Database/patch-configuration.php +++ b/samples/Database/patch-configuration.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * OS_REGION_NAME: OpenStack Cloud region where database configuations are created -// * OS_DB_CONFIGURATION_ID: ID of database configuration -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database configuration. -$configuration = $databaseService->configuration(getenv('OS_DB_CONFIGURATION_ID')); +$configuration = $databaseService->configuration('{configId}'); // 3. Patch it. $configuration->patch(array( diff --git a/samples/Database/replace-configuration.php b/samples/Database/replace-configuration.php index b1309c717..9646f3773 100644 --- a/samples/Database/replace-configuration.php +++ b/samples/Database/replace-configuration.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * OS_REGION_NAME: OpenStack Cloud region where database configuations are created -// * OS_DB_CONFIGURATION_ID: ID of database configuration -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database configuration. -$configuration = $databaseService->configuration(getenv('OS_DB_CONFIGURATION_ID')); +$configuration = $databaseService->configuration('{configId}'); // 3. Replace it. $configuration->update(array( diff --git a/samples/Database/update-instance.php b/samples/Database/update-instance.php index 9ded49b84..53ca46326 100644 --- a/samples/Database/update-instance.php +++ b/samples/Database/update-instance.php @@ -15,33 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * OS_USERNAME: Your OpenStack Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, -// * OS_REGION_NAME: OpenStack Cloud region in which to create database instance, -// * OS_DB_INSTANCE_ID: ID of database instance, and -// * OS_DB_CONFIGURATION_ID: ID of database configuration -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('OS_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// 2. Obtain a Databae service object from the client. -$region = getenv('OS_REGION_NAME'); -$databaseService = $client->databaseService(null, $region); +// 2. Obtain a Database service object from the client. +$databaseService = $client->databaseService(null, '{region}'); // 3. Retrieve the database instance. -$instance = $databaseService->instance(getenv('OS_DB_INSTANCE_ID')); +$instance = $databaseService->instance('{instanceId}'); // 4. Update it with a configuration. $instance->update(array( - 'configuration' => getenv('OS_DB_CONFIGURATION_ID') + 'configuration' => '{configId}' )); diff --git a/samples/Identity/add_user.php b/samples/Identity/add_user.php new file mode 100644 index 000000000..e37e490ba --- /dev/null +++ b/samples/Identity/add_user.php @@ -0,0 +1,41 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Create user +$user = $service->createUser(array( + 'username' => '{username}', // replace username + 'email' => '{email}', // replace email address + 'enabled' => true, +)); + +// If you do not provide a "password" key in the createUser operation, the API +// will automatically generate you one. If that's the case, you will need to +// retrieve the new password and save it somewhere. +echo $user->getPassword(); diff --git a/samples/Identity/authenticate_token.php b/samples/Identity/authenticate_token.php new file mode 100644 index 000000000..e1db2e4aa --- /dev/null +++ b/samples/Identity/authenticate_token.php @@ -0,0 +1,32 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Authenticate with the above credentials +$client->authenticate(); + +// Retrieve token ID +echo $client->getToken(); diff --git a/samples/Identity/delete_user.php b/samples/Identity/delete_user.php new file mode 100644 index 000000000..493e5ff98 --- /dev/null +++ b/samples/Identity/delete_user.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Retrieve existing user +$user = $service->getUser('{username}'); + +// And delete them... +$user->delete(); diff --git a/samples/Identity/get_user_by_email.php b/samples/Identity/get_user_by_email.php new file mode 100644 index 000000000..e127dcb26 --- /dev/null +++ b/samples/Identity/get_user_by_email.php @@ -0,0 +1,33 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Retrieve existing user +$user = $service->getUser('{email}', UserConst::MODE_EMAIL); diff --git a/samples/Identity/get_user_by_id.php b/samples/Identity/get_user_by_id.php new file mode 100644 index 000000000..0efbeece0 --- /dev/null +++ b/samples/Identity/get_user_by_id.php @@ -0,0 +1,33 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Retrieve existing user +$user = $service->getUser('{userId}', UserConst::MODE_ID); diff --git a/samples/Identity/get_user_by_name.php b/samples/Identity/get_user_by_name.php new file mode 100644 index 000000000..45f1ff34f --- /dev/null +++ b/samples/Identity/get_user_by_name.php @@ -0,0 +1,33 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Retrieve existing user +$user = $service->getUser('{username}'); diff --git a/samples/Identity/list_users.php b/samples/Identity/list_users.php new file mode 100644 index 000000000..f5f0be8b5 --- /dev/null +++ b/samples/Identity/list_users.php @@ -0,0 +1,38 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Get a collection of users +$users = $service->getUsers(); + +// Traverse the collection +foreach ($users as $user) { + printf("User ID: %s, Name: %s\n", $user->getId(), $user->getUsername()); +} diff --git a/samples/Identity/reset_api_key.php b/samples/Identity/reset_api_key.php new file mode 100644 index 000000000..28efe0878 --- /dev/null +++ b/samples/Identity/reset_api_key.php @@ -0,0 +1,39 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// Set up Identity service +$service = $client->identityService(); + +// Get user by their ID +$user = $service->getUser('{userId}'); + +// Reset +$user->resetApiKey(); + +// Show the new API key +echo $user->getApiKey(); diff --git a/samples/LoadBalancer/blacklist-ip-range.php b/samples/LoadBalancer/blacklist-ip-range.php new file mode 100644 index 000000000..68805cb38 --- /dev/null +++ b/samples/LoadBalancer/blacklist-ip-range.php @@ -0,0 +1,38 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +// Retrieve your load balancer +$lb = $service->loadBalancer('{loadBalancerId}'); + +// Blacklist an IP range +$lb->createAccessList(array( + (object) array( + 'type' => 'DENY', + 'address' => '{ipAddressRange}' // Replace with your own CIDR + ) +)); diff --git a/samples/LoadBalancer/create-lb.php b/samples/LoadBalancer/create-lb.php new file mode 100644 index 000000000..9ff7661a1 --- /dev/null +++ b/samples/LoadBalancer/create-lb.php @@ -0,0 +1,49 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +// Create empty object +$lb = $service->loadBalancer(); + +// Optional: add back-end nodes that need to be load balanced. These are +// usually servers. +$serverNode = $lb->node(array( + 'address' => '{ipAddress}', // substitute your server's IPv4 address + 'port' => 80, + 'condition' => 'ENABLED', +)); + +// Configure the type of Virtual IP your LB will use +$lb->addVirtualIp('PUBLIC'); + +// Create it +$lb->create(array( + 'name' => '{name}', + 'port' => 80, + 'protocol' => 'HTTP', + 'nodes' => array($serverNode) +)); diff --git a/samples/LoadBalancer/delete-lb.php b/samples/LoadBalancer/delete-lb.php new file mode 100644 index 000000000..9be357778 --- /dev/null +++ b/samples/LoadBalancer/delete-lb.php @@ -0,0 +1,33 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +// Retrieve existing LB +$lb = $service->loadBalancer('{loadBalancerId}'); + +// Delete +$lb->delete(); diff --git a/samples/LoadBalancer/limit-access-to-1-ip.php b/samples/LoadBalancer/limit-access-to-1-ip.php new file mode 100644 index 000000000..fa04cea73 --- /dev/null +++ b/samples/LoadBalancer/limit-access-to-1-ip.php @@ -0,0 +1,42 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +// Retrieve your load balancer +$lb = $service->loadBalancer('{loadBalancerId}'); + +// Limit access to just 1 IP CIDR +$lb->createAccessList(array( + (object) array( + 'type' => 'ALLOW', + 'address' => '{ipAddress}' // Add your own CIDR + ), + (object) array( + 'type' => 'DENY', + 'address' => '0.0.0.0/0' + ) +)); diff --git a/samples/LoadBalancer/list-load-balancers.php b/samples/LoadBalancer/list-load-balancers.php new file mode 100644 index 000000000..0b62f1755 --- /dev/null +++ b/samples/LoadBalancer/list-load-balancers.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +$loadBalancers = $loadBalancerService->loadBalancerList(); + +foreach ($loadBalancers as $loadBalancer) { + /** @var $loadBalancer OpenCloud\LoadBalancer\Resource\LoadBalancer **/ + var_dump($loadBalancer); +} diff --git a/samples/LoadBalancer/ssl-termination.php b/samples/LoadBalancer/ssl-termination.php new file mode 100644 index 000000000..24767a1fa --- /dev/null +++ b/samples/LoadBalancer/ssl-termination.php @@ -0,0 +1,39 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +// Retrieve existing LB +$lb = $service->loadBalancer('{loadBalancerId}'); + +// Update SSL config +$sslConfig = $lb->SSLTermination(); +$sslConfig->update(array( + 'enabled' => true, + 'securePort' => 443, + 'privateKey' => '{privateKey}', // specify your private key + 'certificate' => '{certificate}', // specify your SSL certificate +)); diff --git a/samples/LoadBalancer/throttle-connections.php b/samples/LoadBalancer/throttle-connections.php new file mode 100644 index 000000000..6da2641f3 --- /dev/null +++ b/samples/LoadBalancer/throttle-connections.php @@ -0,0 +1,42 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->loadBalancerService(null, '{region}'); + +// Retrieve existing LB +$lb = $service->loadBalancer('{loadBalancerId}'); + +// Set up throttling +$throttle = $lb->connectionThrottle(); + +// Allow a maximum of 5,000 simultaneous connections (maxConnections) per +// minute (rateInterval). Limit each IP to a maximum of 50 connections (maxConnectionRate). +$throttle->create(array( + 'maxConnections' => 5000, + 'minConnections' => 10, + 'rateInterval' => 60, + 'maxConnectionRate' => 50 +)); diff --git a/samples/Networking/create-network.php b/samples/Networking/create-network.php new file mode 100644 index 000000000..70ed6d9bb --- /dev/null +++ b/samples/Networking/create-network.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a network. +$network = $networkingService->createNetwork(array( + 'name' => 'My private backend network' +)); +/** @var $network OpenCloud\Networking\Resource\Network **/ diff --git a/samples/Networking/create-networks.php b/samples/Networking/create-networks.php new file mode 100644 index 000000000..aa8581364 --- /dev/null +++ b/samples/Networking/create-networks.php @@ -0,0 +1,44 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create multiple networks. +$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 **/ +} diff --git a/samples/Networking/create-port.php b/samples/Networking/create-port.php new file mode 100644 index 000000000..5494b0c03 --- /dev/null +++ b/samples/Networking/create-port.php @@ -0,0 +1,37 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a port. +$port = $networkingService->createPort(array( + 'name' => 'My port', + 'networkId' => '{networkId}' +)); +/** @var $port OpenCloud\Networking\Resource\Port **/ diff --git a/samples/Networking/create-ports.php b/samples/Networking/create-ports.php new file mode 100644 index 000000000..3bcfe3201 --- /dev/null +++ b/samples/Networking/create-ports.php @@ -0,0 +1,46 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create multiple ports. +$ports = $networkingService->createPorts(array( + array( + 'name' => 'My port #1', + 'networkId' => '{networkId}' + ), + array( + 'name' => 'My port #2', + 'networkId' => '{networkId}' + ) +)); + +foreach ($ports as $port) { + /** @var $port OpenCloud\Networking\Resource\Port **/ +} diff --git a/samples/Networking/create-security-group-rule.php b/samples/Networking/create-security-group-rule.php new file mode 100644 index 000000000..e60059774 --- /dev/null +++ b/samples/Networking/create-security-group-rule.php @@ -0,0 +1,42 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a security group rule. +$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' +)); +/** @var $securityGroupRule OpenCloud\Networking\Resource\SecurityGroupRule **/ diff --git a/samples/Networking/create-security-group.php b/samples/Networking/create-security-group.php new file mode 100644 index 000000000..bf69ad044 --- /dev/null +++ b/samples/Networking/create-security-group.php @@ -0,0 +1,37 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a security group. +$securityGroup = $networkingService->createSecurityGroup(array( + 'name' => 'new-webservers', + 'description' => 'security group for webservers' +)); +/** @var $securityGroup OpenCloud\Networking\Resource\SecurityGroup **/ diff --git a/samples/Networking/create-subnet-with-gateway-ip.php b/samples/Networking/create-subnet-with-gateway-ip.php new file mode 100644 index 000000000..646d0e56f --- /dev/null +++ b/samples/Networking/create-subnet-with-gateway-ip.php @@ -0,0 +1,40 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a subnet. +$subnet = $networkingService->createSubnet(array( + 'name' => 'My subnet', + 'networkId' => '{networkId}', + 'ipVersion' => 4, + 'cidr' => '192.168.199.0/25', + 'gatewayIp' => '192.168.199.128' +)); +/** @var $subnet OpenCloud\Networking\Resource\Subnet **/ diff --git a/samples/Networking/create-subnet-with-host-routes.php b/samples/Networking/create-subnet-with-host-routes.php new file mode 100644 index 000000000..3a2ea5e44 --- /dev/null +++ b/samples/Networking/create-subnet-with-host-routes.php @@ -0,0 +1,45 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a subnet. +$subnet = $networkingService->createSubnet(array( + 'name' => 'My subnet', + 'networkId' => '{networkId}', + 'ipVersion' => 4, + 'cidr' => '192.168.199.0/24', + 'hostRoutes' => array( + array( + 'destination' => '1.1.1.0/24', + 'nexthop' => '192.168.19.20' + ) + ) +)); +/** @var $subnet OpenCloud\Networking\Resource\Subnet **/ diff --git a/samples/Networking/create-subnet.php b/samples/Networking/create-subnet.php new file mode 100644 index 000000000..85cbf6462 --- /dev/null +++ b/samples/Networking/create-subnet.php @@ -0,0 +1,39 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create a subnet. +$subnet = $networkingService->createSubnet(array( + 'name' => 'My subnet', + 'networkId' => '{networkId}', + 'ipVersion' => 4, + 'cidr' => '192.168.199.0/24' +)); +/** @var $subnet OpenCloud\Networking\Resource\Subnet **/ diff --git a/samples/Networking/create-subnets.php b/samples/Networking/create-subnets.php new file mode 100644 index 000000000..849b00c8a --- /dev/null +++ b/samples/Networking/create-subnets.php @@ -0,0 +1,50 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Create multiple subnets. +$subnets = $networkingService->createSubnets(array( + array( + 'name' => 'My subnet #1', + 'networkId' => '{networkId1}', + 'ipVersion' => 4, + 'cidr' => '192.168.199.0/24' + ), + array( + 'name' => 'My subnet #2', + 'networkId' => '{networkId2}', + 'ipVersion' => 4, + 'cidr' => '10.56.4.0/22' + ) +)); + +foreach ($subnets as $subnet) { + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ +} diff --git a/samples/Networking/delete-network.php b/samples/Networking/delete-network.php new file mode 100644 index 000000000..12b7a6d8f --- /dev/null +++ b/samples/Networking/delete-network.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get network. +$network = $networkingService->getNetwork('{networkId}'); + +// 4. Delete network. +$network->delete(); diff --git a/samples/Networking/delete-port.php b/samples/Networking/delete-port.php new file mode 100644 index 000000000..c64792eb6 --- /dev/null +++ b/samples/Networking/delete-port.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get port. +$port = $networkingService->getPort('{portId}'); + +// 4. Delete port. +$port->delete(); diff --git a/samples/Networking/delete-security-group-rule.php b/samples/Networking/delete-security-group-rule.php new file mode 100644 index 000000000..d7cf988dd --- /dev/null +++ b/samples/Networking/delete-security-group-rule.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get security group rule. +$securityGroupRule = $networkingService->getSecurityGroupRule('{securityGroupRuleId}'); + +// 4. Delete security group rule. +$securityGroupRule->delete(); diff --git a/samples/Networking/delete-security-group.php b/samples/Networking/delete-security-group.php new file mode 100644 index 000000000..758da3ae8 --- /dev/null +++ b/samples/Networking/delete-security-group.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get security group. +$securityGroup = $networkingService->getSecurityGroup('{securityGroupId}'); + +// 4. Delete security group. +$securityGroup->delete(); diff --git a/samples/Networking/delete-subnet.php b/samples/Networking/delete-subnet.php new file mode 100644 index 000000000..e0b131c4f --- /dev/null +++ b/samples/Networking/delete-subnet.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get subnet. +$subnet = $networkingService->getSubnet('{subnetId}'); + +// 4. Delete subnet. +$subnet->delete(); diff --git a/samples/Networking/get-network.php b/samples/Networking/get-network.php new file mode 100644 index 000000000..2d62fcdc6 --- /dev/null +++ b/samples/Networking/get-network.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get network. +$network = $networkingService->getNetwork('{networkId}'); +/** @var $network OpenCloud\Networking\Resource\Network **/ diff --git a/samples/Networking/get-port.php b/samples/Networking/get-port.php new file mode 100644 index 000000000..e4f8dcda9 --- /dev/null +++ b/samples/Networking/get-port.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get port. +$port = $networkingService->getPort('{portId}'); +/** @var $port OpenCloud\Networking\Resource\Port **/ diff --git a/samples/Networking/get-security-group-rule.php b/samples/Networking/get-security-group-rule.php new file mode 100644 index 000000000..f6ea2bc25 --- /dev/null +++ b/samples/Networking/get-security-group-rule.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get security group rule. +$securityGroupRule = $networkingService->getSecurityGroupRule('{securityGroupRuleId}'); +/** @var $securityGroupRule OpenCloud\Networking\Resource\SecurityGroupRule **/ diff --git a/samples/Networking/get-security-group.php b/samples/Networking/get-security-group.php new file mode 100644 index 000000000..7573aa1f9 --- /dev/null +++ b/samples/Networking/get-security-group.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get security group. +$securityGroup = $networkingService->getSecurityGroup('{securityGroupId}'); +/** @var $securityGroup OpenCloud\Networking\Resource\SecurityGroup **/ diff --git a/samples/Networking/get-subnet.php b/samples/Networking/get-subnet.php new file mode 100644 index 000000000..926310a6a --- /dev/null +++ b/samples/Networking/get-subnet.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get subnet. +$subnet = $networkingService->getSubnet('{subnetId}'); +/** @var $subnet OpenCloud\Networking\Resource\Subnet **/ diff --git a/samples/Networking/list-networks.php b/samples/Networking/list-networks.php new file mode 100644 index 000000000..eceb5b889 --- /dev/null +++ b/samples/Networking/list-networks.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. List networks +$networks = $networkingService->listNetworks(); +foreach ($networks as $network) { + /** @var $network OpenCloud\Networking\Resource\Network **/ +} diff --git a/samples/Networking/list-ports-filtered.php b/samples/Networking/list-ports-filtered.php new file mode 100644 index 000000000..d676c82a3 --- /dev/null +++ b/samples/Networking/list-ports-filtered.php @@ -0,0 +1,39 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. List ACTIVE ports for given device ID +$ports = $networkingService->listPorts([ + 'status' => 'ACTIVE', + 'device_id' => '{deviceId}' +]); +foreach ($ports as $port) { + /** @var $port OpenCloud\Networking\Resource\Port **/ +} diff --git a/samples/Networking/list-ports.php b/samples/Networking/list-ports.php new file mode 100644 index 000000000..4f2446161 --- /dev/null +++ b/samples/Networking/list-ports.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. List ports +$ports = $networkingService->listPorts(); +foreach ($ports as $port) { + /** @var $port OpenCloud\Networking\Resource\Port **/ +} diff --git a/samples/Networking/list-security-group-rules.php b/samples/Networking/list-security-group-rules.php new file mode 100644 index 000000000..1adba50d7 --- /dev/null +++ b/samples/Networking/list-security-group-rules.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. List security group rules +$securityGroupRules = $networkingService->listSecurityGroupRules(); +foreach ($securityGroupRules as $securityGroupRule) { + /** @var $securityGroupRule OpenCloud\Networking\Resource\SecurityGroupRule **/ +} diff --git a/samples/Networking/list-security-groups.php b/samples/Networking/list-security-groups.php new file mode 100644 index 000000000..82ffd0931 --- /dev/null +++ b/samples/Networking/list-security-groups.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. List security groups +$securityGroups = $networkingService->listSecurityGroups(); +foreach ($securityGroups as $securityGroup) { + /** @var $securityGroup OpenCloud\Networking\Resource\SecurityGroup **/ +} diff --git a/samples/Networking/list-subnets.php b/samples/Networking/list-subnets.php new file mode 100644 index 000000000..009e46ff8 --- /dev/null +++ b/samples/Networking/list-subnets.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. List subnets +$subnets = $networkingService->listSubnets(); +foreach ($subnets as $subnet) { + /** @var $subnet OpenCloud\Networking\Resource\Subnet **/ +} diff --git a/samples/Networking/update-network.php b/samples/Networking/update-network.php new file mode 100644 index 000000000..94748471a --- /dev/null +++ b/samples/Networking/update-network.php @@ -0,0 +1,38 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get network. +$network = $networkingService->getNetwork('{networkId}'); + +// 4. Update network. +$network->update(array( + 'name' => 'My updated private backend network' +)); diff --git a/samples/Networking/update-port.php b/samples/Networking/update-port.php new file mode 100644 index 000000000..abc1cbaf4 --- /dev/null +++ b/samples/Networking/update-port.php @@ -0,0 +1,44 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get port. +$port = $networkingService->getPort('{portId}'); + +// 4. Update port. +$port->update(array( + 'name' => 'My updated port', + 'fixedIps' => array( + array( + 'subnetId' => '{subnetId}', + 'ipAddress' => '{ipAddress}' + ) + ) +)); diff --git a/samples/Networking/update-subnet.php b/samples/Networking/update-subnet.php new file mode 100644 index 000000000..1259fd0d7 --- /dev/null +++ b/samples/Networking/update-subnet.php @@ -0,0 +1,45 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain a Networking service object from the client. +$networkingService = $client->networkingService(null, '{region}'); + +// 3. Get subnet. +$subnet = $networkingService->getSubnet('{subnetId}'); + +// 4. Update subnet. +$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' +)); diff --git a/samples/ObjectStore/auto-extract-archive-files.php b/samples/ObjectStore/auto-extract-archive-files.php index bd6a90957..53717b3c6 100644 --- a/samples/ObjectStore/auto-extract-archive-files.php +++ b/samples/ObjectStore/auto-extract-archive-files.php @@ -15,35 +15,28 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; -use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Constants\UrlType; +use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); - -// 3. Upload archive file for auto-extraction into objects. -$localArchiveFileName = __DIR__ . '/logos.tar.gz'; -$remotePath = 'logos/'; +$objectStoreService = $client->objectStoreService(null, '{region}'); -$fileData = fopen($localArchiveFileName, 'r'); -$objectStoreService->bulkExtract($remotePath, $fileData, UrlType::TAR_GZ); +// 3. Open local file +$fileData = fopen('{localArchiveFilePath}', 'r'); -// Note that while we call fopen to open the file resource, we do not call fclose at the end. -// The file resource is automatically closed inside the bulkExtract call. +// 4. Upload archive for auto-extraction. Note that while we call fopen to open +// the file resource, we do not call fclose at the end. The file resource is +// automatically closed inside the bulkExtract call. +// +// For example, if you have a photo.jpg file inside a container named Photos, +// then the remote path will be Photos/photo.jpg. +$objectStoreService->bulkExtract('{remotePath}', $fileData, UrlType::TAR_GZ); diff --git a/samples/ObjectStore/bulk-delete.php b/samples/ObjectStore/bulk-delete.php index d9b2d902c..81a47cd0b 100644 --- a/samples/ObjectStore/bulk-delete.php +++ b/samples/ObjectStore/bulk-delete.php @@ -15,38 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains two objects named 'php-elephant.jpg' and -// 'python-snakes.jpg'. Run upload-multiple-objects.php if you need to create -// them first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Constants\UrlType; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); -// 3. Just to demonstrate bulk delete, create an empty container. -$objectStoreService->createContainer('some_empty_container'); - -// 4. Bulk delete objects and empty containers. -$response = $objectStoreService->bulkDelete(array( - 'logos/php-elephant.png', - 'logos/python-snakes.png', - 'some_empty_container' +// 3. Bulk delete objects and empty containers. +$response = $objectStoreService->batchDelete(array( + '{container1}/{objectName}', + '{container2}/{objectName}', + '{container3}' )); diff --git a/samples/ObjectStore/cleanup.php b/samples/ObjectStore/cleanup.php index c54227ce6..3d152c18b 100644 --- a/samples/ObjectStore/cleanup.php +++ b/samples/ObjectStore/cleanup.php @@ -15,25 +15,19 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// Instantiate Rackspace client -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); -// Instantiate Object Store service -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); // Get all containers $containers = $objectStoreService->listContainers(); diff --git a/samples/ObjectStore/copy-object.php b/samples/ObjectStore/copy-object.php index 989ab2a91..882df7f27 100644 --- a/samples/ObjectStore/copy-object.php +++ b/samples/ObjectStore/copy-object.php @@ -15,39 +15,28 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{sourceContainerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Create another container for object's copy. -$objectStoreService->createContainer('logos_copy'); +$objectStoreService->createContainer('{destinationContainerName}'); // 6. Copy object to another container. -$object->copy('logos_copy/php.jpg'); +$object->copy('{destinationContainerName}/{objectName}'); diff --git a/samples/ObjectStore/create-container.php b/samples/ObjectStore/create-container.php index 206c8f883..c0f5a4346 100644 --- a/samples/ObjectStore/create-container.php +++ b/samples/ObjectStore/create-container.php @@ -15,25 +15,19 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Create a container for your objects (also referred to as files). -$container = $objectStoreService->createContainer('logos'); +$container = $objectStoreService->createContainer('{containerName}'); diff --git a/samples/ObjectStore/delete-container-recursive.php b/samples/ObjectStore/delete-container-recursive.php index 54adac208..37b47d8ba 100644 --- a/samples/ObjectStore/delete-container-recursive.php +++ b/samples/ObjectStore/delete-container-recursive.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Delete container. -$container->delete(true); \ No newline at end of file +// 4. Delete container and all its contents. +$container->delete(true); diff --git a/samples/ObjectStore/delete-container.php b/samples/ObjectStore/delete-container.php index ec8d68287..7663e0140 100644 --- a/samples/ObjectStore/delete-container.php +++ b/samples/ObjectStore/delete-container.php @@ -15,31 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container is empty. That is, it has no objects in it. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Delete container. -$container->delete(); \ No newline at end of file +$container->delete(); diff --git a/samples/ObjectStore/delete-object-without-download.php b/samples/ObjectStore/delete-object-without-download.php new file mode 100644 index 000000000..bbed09c2e --- /dev/null +++ b/samples/ObjectStore/delete-object-without-download.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get container. +$container = $objectStoreService->getContainer('{containerName}'); + +// 4. Delete object. +$container->deleteObject('{objectName}'); diff --git a/samples/ObjectStore/delete-object.php b/samples/ObjectStore/delete-object.php index bd5f92ef8..5cb8f3570 100644 --- a/samples/ObjectStore/delete-object.php +++ b/samples/ObjectStore/delete-object.php @@ -15,36 +15,25 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Delete object. -$object->delete(); \ No newline at end of file +$object->delete(); diff --git a/samples/ObjectStore/disable-container-cdn.php b/samples/ObjectStore/disable-container-cdn.php index 4133a37f8..c0587f640 100644 --- a/samples/ObjectStore/disable-container-cdn.php +++ b/samples/ObjectStore/disable-container-cdn.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Disable CDN for the container. $container->disableCdn(); diff --git a/samples/ObjectStore/enable-container-cdn.php b/samples/ObjectStore/enable-container-cdn.php index 0d614ed98..ebd94c2ae 100644 --- a/samples/ObjectStore/enable-container-cdn.php +++ b/samples/ObjectStore/enable-container-cdn.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Enable CDN for the container. $container->enableCdn(); diff --git a/samples/ObjectStore/get-account-bytes-used.php b/samples/ObjectStore/get-account-bytes-used.php index cefccf89c..655e48581 100644 --- a/samples/ObjectStore/get-account-bytes-used.php +++ b/samples/ObjectStore/get-account-bytes-used.php @@ -15,29 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get the account. $account = $objectStoreService->getAccount(); // 4. Get the space (in bytes) used by the account. + +/** @var $accountSizeInBytes int */ $accountSizeInBytes = $account->getBytesUsed(); -printf("Space (in bytes) used by this account: %d\n", $accountSizeInBytes); \ No newline at end of file diff --git a/samples/ObjectStore/get-account-container-count.php b/samples/ObjectStore/get-account-container-count.php index dfc3a574b..66c4ace18 100644 --- a/samples/ObjectStore/get-account-container-count.php +++ b/samples/ObjectStore/get-account-container-count.php @@ -15,29 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get the account. $account = $objectStoreService->getAccount(); // 4. Get the number of containers in the account. + +/** @var $accountContainerCount int */ $accountContainerCount = $account->getContainerCount(); -printf("# of containers in account: %d\n", $accountContainerCount); \ No newline at end of file diff --git a/samples/ObjectStore/get-account-object-count.php b/samples/ObjectStore/get-account-object-count.php index 4092006cc..05f0e90a8 100644 --- a/samples/ObjectStore/get-account-object-count.php +++ b/samples/ObjectStore/get-account-object-count.php @@ -15,29 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get the account. $account = $objectStoreService->getAccount(); // 4. Get the number of objects in the account. + +/** @var $accountObjectCount int */ $accountObjectCount = $account->getObjectCount(); -printf("# of objects in account: %d\n", $accountObjectCount); \ No newline at end of file diff --git a/samples/ObjectStore/get-account-temp-url-secret.php b/samples/ObjectStore/get-account-temp-url-secret.php index 1e69608a5..d0d4275ad 100644 --- a/samples/ObjectStore/get-account-temp-url-secret.php +++ b/samples/ObjectStore/get-account-temp-url-secret.php @@ -15,30 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get the account. $account = $objectStoreService->getAccount(); // 4. Get the temporary URL secret. -$tempUrlSecret = $account->getTempUrlSecret(); -printf("Account temporary URL secret: %s\n", $tempUrlSecret); \ No newline at end of file +/** @var $tempUrlSecret string */ +$tempUrlSecret = $account->getTempUrlSecret(); diff --git a/samples/ObjectStore/get-cdn-object-http-url.php b/samples/ObjectStore/get-cdn-object-http-url.php index 3947df022..8427bce81 100644 --- a/samples/ObjectStore/get-cdn-object-http-url.php +++ b/samples/ObjectStore/get-cdn-object-http-url.php @@ -15,40 +15,27 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container is CDN-enabled. Run enable-container-cdn.php if -// you need to CDN-enable the container first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Get object's publicly-accessible HTTP URL. -$httpUrl = $object->getPublicUrl(); -printf("Object's publicly accessible HTTP URL: %s\n", $httpUrl); +/** @var $httpUrl string */ +$httpUrl = $object->getPublicUrl(); diff --git a/samples/ObjectStore/get-cdn-object-https-url.php b/samples/ObjectStore/get-cdn-object-https-url.php index 9b8ffda2a..cac63bcef 100644 --- a/samples/ObjectStore/get-cdn-object-https-url.php +++ b/samples/ObjectStore/get-cdn-object-https-url.php @@ -15,41 +15,28 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container is CDN-enabled. Run enable-container-cdn.php if -// you need to CDN-enable the container first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Constants\UrlType; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Get object's publicly-accessible HTTPS URL. -$httpsUrl = $object->getPublicUrl(UrlType::SSL); -printf("Object's publicly accessible HTTPS URL: %s\n", $httpsUrl); +/** @var $httpsUrl string */ +$httpsUrl = $object->getPublicUrl(UrlType::SSL); diff --git a/samples/ObjectStore/get-cdn-object-ios-streaming-url.php b/samples/ObjectStore/get-cdn-object-ios-streaming-url.php index 51a94f781..684cfe0e9 100644 --- a/samples/ObjectStore/get-cdn-object-ios-streaming-url.php +++ b/samples/ObjectStore/get-cdn-object-ios-streaming-url.php @@ -15,41 +15,28 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container is CDN-enabled. Run enable-container-cdn.php if -// you need to CDN-enable the container first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Constants\UrlType; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Get object's publicly-accessible iOS streaming URL. -$iosStreamingUrl = $object->getPublicUrl(UrlType::IOS_STREAMING); -printf("Object's publicly accessible iOS streaming URL: %s\n", $iosStreamingUrl); +/** @var $iosStreamingUrl string */ +$iosStreamingUrl = $object->getPublicUrl(UrlType::IOS_STREAMING); diff --git a/samples/ObjectStore/get-cdn-object-streaming-url.php b/samples/ObjectStore/get-cdn-object-streaming-url.php index 70ef9f5b6..d66040664 100644 --- a/samples/ObjectStore/get-cdn-object-streaming-url.php +++ b/samples/ObjectStore/get-cdn-object-streaming-url.php @@ -15,41 +15,28 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container is CDN-enabled. Run enable-container-cdn.php if -// you need to CDN-enable the container first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Constants\UrlType; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Get object's publicly-accessible streaming URL. -$streamingUrl = $object->getPublicUrl(UrlType::STREAMING); -printf("Object's publicly accessible streaming URL: %s\n", $streamingUrl); +/** @var $streamingUrl string */ +$streamingUrl = $object->getPublicUrl(UrlType::STREAMING); diff --git a/samples/ObjectStore/get-container-bytes-quota.php b/samples/ObjectStore/get-container-bytes-quota.php index 960f2f43d..11603e215 100644 --- a/samples/ObjectStore/get-container-bytes-quota.php +++ b/samples/ObjectStore/get-container-bytes-quota.php @@ -15,31 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get the quota for total size of objects in container. -$maximumTotalSizeOfObjectsAllowedInContainer = $container->getBytesQuota(); -printf("Total size of objects allowed in container: %d\n", $maximumTotalSizeOfObjectsAllowedInContainer); \ No newline at end of file + +/** @var $bytesQuota int */ +$bytesQuota = $container->getBytesQuota(); diff --git a/samples/ObjectStore/get-container-bytes-used.php b/samples/ObjectStore/get-container-bytes-used.php index 5e6345e53..31cca2f00 100644 --- a/samples/ObjectStore/get-container-bytes-used.php +++ b/samples/ObjectStore/get-container-bytes-used.php @@ -15,31 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get the space (in bytes) used by this container. -$containerSizeInBytes = $container->getBytesUsed(); -printf("Space (in bytes) used by this container: %d\n", $containerSizeInBytes); \ No newline at end of file + +/** @var $bytesUsed int */ +$bytesUsed = $container->getBytesUsed(); diff --git a/samples/ObjectStore/get-container-count-quota.php b/samples/ObjectStore/get-container-count-quota.php index 8f93b954c..58e1e983d 100644 --- a/samples/ObjectStore/get-container-count-quota.php +++ b/samples/ObjectStore/get-container-count-quota.php @@ -15,31 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get the quota for number of objects in container. -$maximumNumberOfObjectsAllowedInContainer = $container->getCountQuota(); -printf("Number of objects allowed in container: %d\n", $maximumNumberOfObjectsAllowedInContainer); \ No newline at end of file + +/** @var $countQuota int */ +$countQuota = $container->getCountQuota(); diff --git a/samples/ObjectStore/get-container-metadata.php b/samples/ObjectStore/get-container-metadata.php index b6a74c90d..a5cbe6dac 100644 --- a/samples/ObjectStore/get-container-metadata.php +++ b/samples/ObjectStore/get-container-metadata.php @@ -15,34 +15,23 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container has a metadata filed named 'author' set on it. Run -// set-container-metadata.php if you need to set this field first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Set container metadata. -$containerMetadata = $container->getMetadata(); -/** @var $container $containerMetadata OpenCloud\ObjectStore\Resource\ContainerMetadata **/ -printf("Container author: %s\n", $containerMetadata->getProperty('author')); +// 4. Get container metadata. +/** @var $metadata OpenCloud\ObjectStore\Resource\ContainerMetadata **/ +$metadata = $container->getMetadata(); diff --git a/samples/ObjectStore/get-container-object-count.php b/samples/ObjectStore/get-container-object-count.php index b4ce66039..94607d8c3 100644 --- a/samples/ObjectStore/get-container-object-count.php +++ b/samples/ObjectStore/get-container-object-count.php @@ -15,31 +15,23 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get the number of objects in this container. +/** @param $containerObjectCount int */ $containerObjectCount = $container->getObjectCount(); -printf("# of objects in container: %d\n", $containerObjectCount); \ No newline at end of file diff --git a/samples/ObjectStore/get-container.php b/samples/ObjectStore/get-container.php index d5cdb92e6..7d3a20a23 100644 --- a/samples/ObjectStore/get-container.php +++ b/samples/ObjectStore/get-container.php @@ -15,29 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); /** @var $container OpenCloud\ObjectStore\Resource\Container **/ -printf("Container name: %s\n", $container->getName()); +$container = $objectStoreService->getContainer('{containerName}'); diff --git a/samples/ObjectStore/get-object-metadata.php b/samples/ObjectStore/get-object-metadata.php index fc0ebdd0f..e2ca0d300 100644 --- a/samples/ObjectStore/get-object-metadata.php +++ b/samples/ObjectStore/get-object-metadata.php @@ -15,37 +15,29 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg' with metadata -// set on it. Run upload-object-with-metadata.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Get object metadata. -$objectName = 'php-elephant.jpg'; -$object = $container->getPartialObject($objectName); -$objectMetadata = $object->getMetadata(); +// 4. Retrieve information about the object. +$object = $container->getPartialObject('{objectName}'); +// 5. Retrieve metadata. /** @var $objectMetadata \OpenCloud\Common\Metadata **/ -printf("Object author: %s\n", $objectMetadata->getProperty('author')); +$objectMetadata = $object->getMetadata(); + +/** @var $metadataItemValue mixed **/ +$metadataItemValue = $objectMetadata->getProperty('{key}'); diff --git a/samples/ObjectStore/get-object-temporary-url.php b/samples/ObjectStore/get-object-temporary-url.php index 8a2b86fcc..f8a2b0211 100644 --- a/samples/ObjectStore/get-object-temporary-url.php +++ b/samples/ObjectStore/get-object-temporary-url.php @@ -15,42 +15,34 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// * The temporary URL secret has been set on the account. Run -// set-account-temp-url-secret.php if you need to set the secret first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object metadata. -$objectName = 'php-elephant.jpg'; -$object = $container->getPartialObject($objectName); +$object = $container->getPartialObject('{objectName}'); + +// 5. Set expiration (in seconds) +$expirationTime = 3600; // one hour from now + +// 6. Set the HTTP method allowed on the object in the container. If you want +// to allow read-only access, use GET; for write-access, use POST. +$httpMethod = 'GET'; -// 5. Get object's temporary URL. -$expirationTimeInSeconds = 3600; // one hour from now -$httpMethodAllowed = 'GET'; -$tempUrl = $object->getTemporaryUrl($expirationTimeInSeconds, $httpMethodAllowed); +// 7. Get temp URL -printf("Object temporary URL: %s\n", $tempUrl); +/** @param $tempUrl string */ +$tempUrl = $object->getTemporaryUrl($expirationTime, $httpMethod); diff --git a/samples/ObjectStore/get-object.php b/samples/ObjectStore/get-object.php index 23004dbf2..a6b5e94fb 100644 --- a/samples/ObjectStore/get-object.php +++ b/samples/ObjectStore/get-object.php @@ -15,48 +15,33 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ -printf("Object name: %s\n", $object->getName()); - -$objectContent = $object->getContent(); +$object = $container->getObject('{objectName}'); /** @var $objectContent Guzzle\Http\EntityBody **/ +$objectContent = $object->getContent(); // 5. Write object content to file on local filesystem. $objectContent->rewind(); $stream = $objectContent->getStream(); $localFilename = tempnam("/tmp", 'php-opencloud-'); file_put_contents($localFilename, $stream); - -printf("Your object has been written to %s\n", $localFilename); \ No newline at end of file diff --git a/samples/ObjectStore/list-cdn-containers.php b/samples/ObjectStore/list-cdn-containers.php new file mode 100644 index 000000000..a71a8bed9 --- /dev/null +++ b/samples/ObjectStore/list-cdn-containers.php @@ -0,0 +1,40 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Object a CDN service object +$cdnService = $objectStoreService->getCdnService(); + +// 4. Get container list. +$containers = $cdnService->listContainers(); + +foreach ($containers as $container) { + /** @var $container OpenCloud\ObjectStore\Resource\CDNContainer **/ +} diff --git a/samples/ObjectStore/list-containers.php b/samples/ObjectStore/list-containers.php index 0c31e16b1..5011d41fb 100644 --- a/samples/ObjectStore/list-containers.php +++ b/samples/ObjectStore/list-containers.php @@ -15,29 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container list. $containers = $objectStoreService->listContainers(); foreach ($containers as $container) { - /** @var $container OpenCloud\ObjectStore\Resource\Container **/ - printf("Container name: %s\n", $container->getName()); -} \ No newline at end of file + /** @var $container OpenCloud\ObjectStore\Resource\Container **/ +} diff --git a/samples/ObjectStore/list-objects-over-10000.php b/samples/ObjectStore/list-objects-over-10000.php new file mode 100644 index 000000000..ec349e88d --- /dev/null +++ b/samples/ObjectStore/list-objects-over-10000.php @@ -0,0 +1,62 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get container. +$container = $objectStoreService->getContainer('{containerName}'); + +// 4. Get the list of objects +$objects = $container->objectList(); + +// 5. Create a list of all objects in the container +$containerObjects = array(); +$marker = ''; + +while ($marker !== null) { + $params = array( + 'marker' => $marker, + ); + + $objects = $container->objectList($params); + $total = $objects->count(); + $count = 0; + + if ($total == 0) { + break; + } + + foreach ($objects as $object) { + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ + $containerObjects[] = $object->getName(); + $count++; + + $marker = ($count == $total) ? $object->getName() : null; + } +} diff --git a/samples/ObjectStore/list-objects-with-limit-and-prefix.php b/samples/ObjectStore/list-objects-with-limit-and-prefix.php new file mode 100644 index 000000000..0462aaf01 --- /dev/null +++ b/samples/ObjectStore/list-objects-with-limit-and-prefix.php @@ -0,0 +1,43 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get container. +$container = $objectStoreService->getContainer('{containerName}'); + +// 4. Get list of objects, limited to a number and refined by a prefix +$objects = $container->objectList(array( + 'limit' => '{limit}', + 'prefix' => '{prefix}', +)); + +foreach ($objects as $object) { + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ +} diff --git a/samples/ObjectStore/list-objects-with-limit.php b/samples/ObjectStore/list-objects-with-limit.php new file mode 100644 index 000000000..3720ae9cb --- /dev/null +++ b/samples/ObjectStore/list-objects-with-limit.php @@ -0,0 +1,42 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get container. +$container = $objectStoreService->getContainer('{containerName}'); + +// 4. Get a limited list of objects +$objects = $container->objectList(array( + 'limit' => '{limit}' +)); + +foreach ($objects as $object) { + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ +} diff --git a/samples/ObjectStore/list-objects-with-params.php b/samples/ObjectStore/list-objects-with-params.php deleted file mode 100644 index 6de68edc4..000000000 --- a/samples/ObjectStore/list-objects-with-params.php +++ /dev/null @@ -1,51 +0,0 @@ - getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') -)); - -// 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); - -// 3. Get container. -$container = $objectStoreService->getContainer('logos'); - -// 4. Get list of objects whose names start with "php" in container. -$options = array( - 'prefix' => 'php' -); -$objects = $container->objectList($options); -foreach ($objects as $object) { - /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ - printf("Object name: %s\n", $object->getName()); -} diff --git a/samples/ObjectStore/list-objects-with-prefix.php b/samples/ObjectStore/list-objects-with-prefix.php new file mode 100644 index 000000000..c2814c9f8 --- /dev/null +++ b/samples/ObjectStore/list-objects-with-prefix.php @@ -0,0 +1,42 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get container. +$container = $objectStoreService->getContainer('{containerName}'); + +// 4. Get list of objects whose names start with {prefix} +$objects = $container->objectList(array( + 'prefix' => '{prefix}' +)); + +foreach ($objects as $object) { + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ +} diff --git a/samples/ObjectStore/list-objects.php b/samples/ObjectStore/list-objects.php index 8e53643ba..0621c0f08 100644 --- a/samples/ObjectStore/list-objects.php +++ b/samples/ObjectStore/list-objects.php @@ -15,34 +15,26 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get list of objects in container. $objects = $container->objectList(); + foreach ($objects as $object) { - /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ - printf("Object name: %s\n", $object->getName()); + /** @var $object OpenCloud\ObjectStore\Resource\DataObject **/ } diff --git a/samples/ObjectStore/logos.tar.gz b/samples/ObjectStore/logos.tar.gz deleted file mode 100644 index c757ac0b5..000000000 Binary files a/samples/ObjectStore/logos.tar.gz and /dev/null differ diff --git a/samples/ObjectStore/php-elephant.jpg b/samples/ObjectStore/php-elephant.jpg deleted file mode 100644 index ca09b7efa..000000000 Binary files a/samples/ObjectStore/php-elephant.jpg and /dev/null differ diff --git a/samples/ObjectStore/pseudo-hierarchical-folders.php b/samples/ObjectStore/pseudo-hierarchical-folders.php index 9ecddcf67..f2cf68d37 100644 --- a/samples/ObjectStore/pseudo-hierarchical-folders.php +++ b/samples/ObjectStore/pseudo-hierarchical-folders.php @@ -15,37 +15,27 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Upload an object to the container. -$localFileName = __DIR__ . '/php-elephant.jpg'; -$remoteFileName = 'languages/php/elephant.jpg'; +// 4. Open a local file +$fileData = fopen('{localFilePath}', 'r'); -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData); - -// Note that while we call fopen to open the file resource, we do not call fclose at the end. -// The file resource is automatically closed inside the uploadObject call. +// 5. Upload its contents to a remote location. Note that while we call fopen +// to open the file resource, we do not call fclose at the end. The file +// resource is automatically closed inside the uploadObject call. +$container->uploadObject('{remoteObjectName}', $fileData); diff --git a/samples/ObjectStore/python-snakes.jpg b/samples/ObjectStore/python-snakes.jpg deleted file mode 100644 index 434a031b6..000000000 Binary files a/samples/ObjectStore/python-snakes.jpg and /dev/null differ diff --git a/samples/ObjectStore/quickstart.php b/samples/ObjectStore/quickstart.php index ef5147bca..60c650ca7 100644 --- a/samples/ObjectStore/quickstart.php +++ b/samples/ObjectStore/quickstart.php @@ -15,32 +15,27 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Create a container for your objects (also referred to as files). -$container = $objectStoreService->createContainer('logos'); +$container = $objectStoreService->createContainer('{containerName}'); -// 4. Upload an object to the container. -$localFileName = __DIR__ . '/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; +// 4. Open a local file +$fileData = fopen('{localFilePath}', 'r'); -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData); \ No newline at end of file +// 5. Upload its contents to a remote location. Note that while we call fopen +// to open the file resource, we do not call fclose at the end. The file +// resource is automatically closed inside the uploadObject call. +$container->uploadObject('{remoteObjectName}', $fileData); diff --git a/samples/ObjectStore/set-account-temp-url-secret-specified.php b/samples/ObjectStore/set-account-temp-url-secret-specified.php index 2e197fc71..6ef4db8ff 100644 --- a/samples/ObjectStore/set-account-temp-url-secret-specified.php +++ b/samples/ObjectStore/set-account-temp-url-secret-specified.php @@ -15,28 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get the account. $account = $objectStoreService->getAccount(); -// 4. Set the temporary URL secret to "ssshhhh" -$account->setTempUrlSecret("ssshhhh"); +// 4. Set the temporary URL secret +$account->setTempUrlSecret('{secret}'); diff --git a/samples/ObjectStore/set-account-temp-url-secret.php b/samples/ObjectStore/set-account-temp-url-secret.php index 2a5f26e83..b69f81998 100644 --- a/samples/ObjectStore/set-account-temp-url-secret.php +++ b/samples/ObjectStore/set-account-temp-url-secret.php @@ -15,25 +15,19 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get the account. $account = $objectStoreService->getAccount(); diff --git a/samples/ObjectStore/set-cdn-container-ttl.php b/samples/ObjectStore/set-cdn-container-ttl.php new file mode 100644 index 000000000..1fa99b3e1 --- /dev/null +++ b/samples/ObjectStore/set-cdn-container-ttl.php @@ -0,0 +1,37 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get CDN-enabled container. +$container = $objectStoreService->getContainer('{containerName}'); +$cdnContainer = $container->getCdn(); + +// 4. Set container metadata. +$cdnContainer->setTtl(4 * 24 * 60 * 60); // 4 days diff --git a/samples/ObjectStore/set-container-bytes-quota.php b/samples/ObjectStore/set-container-bytes-quota.php index db241e60a..967989908 100644 --- a/samples/ObjectStore/set-container-bytes-quota.php +++ b/samples/ObjectStore/set-container-bytes-quota.php @@ -15,32 +15,23 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; use OpenCloud\Common\Constants\Size; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Set quota for total size of objects in container. -$maximumTotalSizeOfObjectsInContainer = 5 * Size::GB; -$container->setBytesQuota($maximumTotalSizeOfObjectsInContainer); +// 4. Set quota for total size of objects permitted in container. +$container->setBytesQuota(5 * Size::GB); // 5GB diff --git a/samples/ObjectStore/set-container-count-quota.php b/samples/ObjectStore/set-container-count-quota.php index cb07d316b..eed0e9055 100644 --- a/samples/ObjectStore/set-container-count-quota.php +++ b/samples/ObjectStore/set-container-count-quota.php @@ -15,31 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Set quota for number of objects in container. -$maximumNumberOfObjectsAllowedInContainer = 25; -$container->setCountQuota($maximumNumberOfObjectsAllowedInContainer); \ No newline at end of file +// 4. Set quota for number of objects allowed in container. +$container->setCountQuota(25); diff --git a/samples/ObjectStore/set-container-metadata.php b/samples/ObjectStore/set-container-metadata.php index c91baa8a8..ee7525fc6 100644 --- a/samples/ObjectStore/set-container-metadata.php +++ b/samples/ObjectStore/set-container-metadata.php @@ -15,32 +15,24 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Set container metadata. $container->saveMetadata(array( - 'author' => 'John Doe' -)); \ No newline at end of file + '{key}' => '{value}' +)); diff --git a/samples/ObjectStore/symlink-object.php b/samples/ObjectStore/symlink-object.php new file mode 100644 index 000000000..f5c4bc129 --- /dev/null +++ b/samples/ObjectStore/symlink-object.php @@ -0,0 +1,45 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +// 2. Obtain an Object Store service object from the client. +$objectStoreService = $client->objectStoreService(null, '{region}'); + +// 3. Get container. +$container = $objectStoreService->getContainer('{sourceContainerName}'); + +// 4. Get object. +$object = $container->getObject('{objectName}'); + +// 5. Create another container for object's copy. +$objectStoreService->createContainer('{destinationContainerName}'); + +// 6. Symlink to object from another container object. {objectName} must either not exist or be an empty file. +$object->createSymlinkFrom('{destinationContainerName}/{objectName}'); + +// 7. Symlink from object to another container object. $object must be an empty file. +$object->createSymlinkTo('{destinationContainerName}/{objectName}'); diff --git a/samples/ObjectStore/update-object-content-type.php b/samples/ObjectStore/update-object-content-type.php index cd6613172..7ce760f8e 100644 --- a/samples/ObjectStore/update-object-content-type.php +++ b/samples/ObjectStore/update-object-content-type.php @@ -15,36 +15,25 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getPartialObject($objectName); +$object = $container->getPartialObject('{objectName}'); // 5. Update object content type. -$object->saveMetadata(array('Content-Type' => 'image/jpeg'), false); +$object->saveMetadata(array('Content-Type' => '{contentType}'), false); diff --git a/samples/ObjectStore/update-object-metadata.php b/samples/ObjectStore/update-object-metadata.php index 404b3725a..18df42dea 100644 --- a/samples/ObjectStore/update-object-metadata.php +++ b/samples/ObjectStore/update-object-metadata.php @@ -15,38 +15,27 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// * The 'logos' container contains an object named 'php-elephant.jpg'. Run -// upload-object.php if you need to create it first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Get object. -$objectName = 'php-elephant.jpg'; -$object = $container->getObject($objectName); +$object = $container->getObject('{objectName}'); // 5. Update object metadata. $object->saveMetadata(array( - 'author' => 'John Doe' + '{key}' => '{value}' )); diff --git a/samples/ObjectStore/upload-directory.php b/samples/ObjectStore/upload-directory.php new file mode 100644 index 000000000..304779be4 --- /dev/null +++ b/samples/ObjectStore/upload-directory.php @@ -0,0 +1,34 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->objectStoreService(null, '{region}'); + +// Find the container you want to upload to. +$container = $service->getContainer('{containerName}'); + +// Specify the local directory you want to upload. +$container->uploadDirectory('{localDir}'); diff --git a/samples/ObjectStore/upload-large-object.php b/samples/ObjectStore/upload-large-object.php index a236f3e29..c67ca4e1f 100644 --- a/samples/ObjectStore/upload-large-object.php +++ b/samples/ObjectStore/upload-large-object.php @@ -15,36 +15,28 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * LARGE_FILE_PATH: Path to large file (5GB+) on your local filesystem -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Upload large object to the container. -$options = array( - 'name' => 'large_object', - 'path' => getenv('LARGE_FILE_PATH') -); -$objectTransfer = $container->setupObjectTransfer($options); -$objectTransfer->upload(); \ No newline at end of file +// 4. Configure +$objectTransfer = $container->setupObjectTransfer(array( + 'name' => '{remoteObjectName}', + 'path' => '{localFilePath}', +)); + +// 5. Initiate transfer +$objectTransfer->upload(); diff --git a/samples/ObjectStore/upload-multiple-objects-with-metadata.php b/samples/ObjectStore/upload-multiple-objects-with-metadata.php index f30ef3a49..4d67d9d11 100644 --- a/samples/ObjectStore/upload-multiple-objects-with-metadata.php +++ b/samples/ObjectStore/upload-multiple-objects-with-metadata.php @@ -15,48 +15,42 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Resource\DataObject; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Upload multiple object to the container. +// 4. Specify the locations of the files you want to upload $objects = array( array( - 'name' => 'php-elephant.jpg', - 'path' => __DIR__ . '/php-elephant.jpg' + 'name' => '{objectName1}', + 'path' => '{localFilePath1}' ), array( - 'name' => 'python-snakes.jpg', - 'path' => __DIR__ . '/python-snakes.jpg' + 'name' => '{objectName2}', + 'path' => '{localFilePath2}' ) ); -$metadata = array('author' => 'Jane Doe'); - -$customHeaders = array(); +// 5. Specify any metadata you want your objects to have +$metadata = array('{key}' => '{value}'); $metadataHeaders = DataObject::stockHeaders($metadata); -$allHeaders = $customHeaders + $metadataHeaders; +// 6. Merge the metadata with any additional HTTP headers you want to set +$allHttpHeaders = array('Content-Type' => '{contentType}') + $metadataHeaders; + +// 7. Upload them $container->uploadObjects($objects, $allHeaders); diff --git a/samples/ObjectStore/upload-multiple-objects.php b/samples/ObjectStore/upload-multiple-objects.php index ff44ea287..835cd5e4c 100644 --- a/samples/ObjectStore/upload-multiple-objects.php +++ b/samples/ObjectStore/upload-multiple-objects.php @@ -15,41 +15,33 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Upload multiple object to the container. $objects = array( array( - 'name' => 'php-elephant.jpg', - 'path' => __DIR__ . '/php-elephant.jpg' + 'name' => '{objectName1}', + 'path' => '{localFilePath1}' ), array( - 'name' => 'python-snakes.jpg', - 'path' => __DIR__ . '/python-snakes.jpg' + 'name' => '{objectName2}', + 'path' => '{localFilePath2}' ) ); -$container->uploadObjects($objects); \ No newline at end of file +$container->uploadObjects($objects); diff --git a/samples/ObjectStore/upload-object-with-content-type.php b/samples/ObjectStore/upload-object-with-content-type.php index 528b67bd3..ad0a21850 100644 --- a/samples/ObjectStore/upload-object-with-content-type.php +++ b/samples/ObjectStore/upload-object-with-content-type.php @@ -15,30 +15,22 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); // 4. Setup headers with custom content type. // NOTE: Normally you do NOT need to specify the content type. The @@ -46,16 +38,12 @@ // are using an obscure type of content or want to be explicit about // the content type rather than letting the service guess at it, // you may specify it as shown below. -$customHeaders = array( - 'Content-Type' => 'image/gif' -); - -// 5. Upload an object to the container. -$localFileName = __DIR__ . '/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; +$customHeaders = array('Content-Type' => '{contentType}'); -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData, $customHeaders); +// 5. Open local file +$fileData = fopen('{localFileName}', 'r'); -// Note that while we call fopen to open the file resource, we do not call fclose at the end. -// The file resource is automatically closed inside the uploadObject call. +// 6. Upload to API. Note that while we call fopen to open the file resource, +// we do not call fclose at the end. The file resource is automatically closed +// inside the uploadObject call. +$container->uploadObject('{remoteObjectName}', $fileData, $customHeaders); diff --git a/samples/ObjectStore/upload-object-with-metadata.php b/samples/ObjectStore/upload-object-with-metadata.php index 8325c8156..954b1ef38 100644 --- a/samples/ObjectStore/upload-object-with-metadata.php +++ b/samples/ObjectStore/upload-object-with-metadata.php @@ -15,43 +15,35 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// - -require __DIR__ . '/../../vendor/autoload.php'; +require dirname(__DIR__) . '/../vendor/autoload.php'; + use OpenCloud\Rackspace; use OpenCloud\ObjectStore\Resource\DataObject; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Upload an object to the container. -$localFileName = __DIR__ . '/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; -$metadata = array('author' => 'Jane Doe'); +// 4. Open local file +$fileData = fopen('{localFilePath}', 'r'); -$customHeaders = array(); +// 5. Specify any metadata you want your objects to have +$metadata = array('{key}' => '{value}'); $metadataHeaders = DataObject::stockHeaders($metadata); -$allHeaders = $customHeaders + $metadataHeaders; -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData, $allHeaders); +// 6. Merge the metadata with any additional HTTP headers you want to set +$allHttpHeaders = array('Content-Type' => '{contentType}') + $metadataHeaders; -// Note that while we call fopen to open the file resource, we do not call fclose at the end. -// The file resource is automatically closed inside the uploadObject call. +// 7. Upload it! Note that while we call fopen to open the file resource, we do +// not call fclose at the end. The file resource is automatically closed inside +// the uploadObject call. +$container->uploadObject('{remoteObjectName}', $fileData, $allHttpHeaders); diff --git a/samples/ObjectStore/upload-object.php b/samples/ObjectStore/upload-object.php index e47648ead..42c50cd55 100644 --- a/samples/ObjectStore/upload-object.php +++ b/samples/ObjectStore/upload-object.php @@ -15,37 +15,27 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * There exists a container named 'logos' in your Object Store. Run -// create-container.php if you need to create one first. -// +require dirname(__DIR__) . '/../vendor/autoload.php'; -require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; -// 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +// 1. Instantiate a Rackspace client. You can replace {authUrl} with +// Rackspace::US_IDENTITY_ENDPOINT or similar +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain an Object Store service object from the client. -$region = 'DFW'; -$objectStoreService = $client->objectStoreService(null, $region); +$objectStoreService = $client->objectStoreService(null, '{region}'); // 3. Get container. -$container = $objectStoreService->getContainer('logos'); +$container = $objectStoreService->getContainer('{containerName}'); -// 4. Upload an object to the container. -$localFileName = __DIR__ . '/php-elephant.jpg'; -$remoteFileName = 'php-elephant.jpg'; +// 4. Open local file +$fileData = fopen('{localFilePath}', 'r'); -$fileData = fopen($localFileName, 'r'); -$container->uploadObject($remoteFileName, $fileData); - -// Note that while we call fopen to open the file resource, we do not call fclose at the end. -// The file resource is automatically closed inside the uploadObject call. +// 5. Upload it! Note that while we call fopen to open the file resource, we do +// not call fclose at the end. The file resource is automatically closed inside +// the uploadObject call. +$container->uploadObject('{remoteObjectName}', $fileData); diff --git a/samples/Orchestration/abandon-stack.php b/samples/Orchestration/abandon-stack.php new file mode 100644 index 000000000..842978524 --- /dev/null +++ b/samples/Orchestration/abandon-stack.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Abandon stack. + +/** @var $abandonStackData string **/ +$abandonStackData = $stack->abandon(); + +file_put_contents(__DIR__ . '/sample_adopt_stack_data.json', $abandonStackData); diff --git a/samples/Orchestration/adopt-stack.php b/samples/Orchestration/adopt-stack.php new file mode 100644 index 000000000..4c470c8bb --- /dev/null +++ b/samples/Orchestration/adopt-stack.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Adopt a stack. + +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack = $orchestrationService->adoptStack(array( + 'name' => '{stackName}', + 'template' => file_get_contents('{yamlTemplateFilePath}'), + 'adoptStackData' => file_get_contents('{stackDataFilePath}'), + 'timeoutMins' => 5 +)); diff --git a/samples/Orchestration/create-stack-from-template-file.php b/samples/Orchestration/create-stack-from-template-file.php new file mode 100644 index 000000000..b7d8d892f --- /dev/null +++ b/samples/Orchestration/create-stack-from-template-file.php @@ -0,0 +1,42 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Create a stack. + +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack = $orchestrationService->createStack(array( + 'name' => '{stackName}', + 'template' => file_get_contents('{yamlTemplateFilePath}'), + 'parameters' => array( + 'server_hostname' => '{hostName}', + 'image' => '{image}' + ), + 'timeoutMins' => 5 +)); diff --git a/samples/Orchestration/create-stack-from-template-url.php b/samples/Orchestration/create-stack-from-template-url.php new file mode 100644 index 000000000..c0efbd702 --- /dev/null +++ b/samples/Orchestration/create-stack-from-template-url.php @@ -0,0 +1,42 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Create a stack. + +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack = $orchestrationService->createStack(array( + 'name' => '{name}', + 'templateUrl' => '{templateUrl}', + 'parameters' => array( + 'server_hostname' => '{serverHost}', + 'image' => '{image}' + ), + 'timeoutMins' => 5 +)); diff --git a/samples/Orchestration/delete-stack.php b/samples/Orchestration/delete-stack.php new file mode 100644 index 000000000..05c0acc80 --- /dev/null +++ b/samples/Orchestration/delete-stack.php @@ -0,0 +1,35 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Delete stack. +$stack->delete(); diff --git a/samples/Orchestration/get-build-info.php b/samples/Orchestration/get-build-info.php new file mode 100644 index 000000000..ae9557a5f --- /dev/null +++ b/samples/Orchestration/get-build-info.php @@ -0,0 +1,33 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get build info. +/** @var $resourceType OpenCloud\Orchestration\Resource\BuildInfo **/ +$buildInfo = $orchestrationService->getBuildInfo(); diff --git a/samples/Orchestration/get-resource-type-template.php b/samples/Orchestration/get-resource-type-template.php new file mode 100644 index 000000000..963bbf8df --- /dev/null +++ b/samples/Orchestration/get-resource-type-template.php @@ -0,0 +1,37 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get resource type. +$resourceType = $orchestrationService->getResourceType('{resourceTypeName}'); + +// 4. Get template for resource type. + +/** @var $resourceTypeTemplate string **/ +$resourceTypeTemplate = $resourceType->getTemplate(); diff --git a/samples/Orchestration/get-resource-type.php b/samples/Orchestration/get-resource-type.php new file mode 100644 index 000000000..6e9956039 --- /dev/null +++ b/samples/Orchestration/get-resource-type.php @@ -0,0 +1,34 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get resource type. + +/** @var $resourceType OpenCloud\Orchestration\Resource\ResourceType **/ +$resourceType = $orchestrationService->getResourceType('{resourceTypeName}'); diff --git a/samples/Orchestration/get-stack-resource-event.php b/samples/Orchestration/get-stack-resource-event.php new file mode 100644 index 000000000..e8b2ccbf5 --- /dev/null +++ b/samples/Orchestration/get-stack-resource-event.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get resource in stack. +$resource = $stack->getResource('{stackResourceName}'); + +// 5. Get stack resource event. +/** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/ +$resourceEvent = $resource->getEvent('{stackResourceEventId}'); diff --git a/samples/Orchestration/get-stack-resource-metadata.php b/samples/Orchestration/get-stack-resource-metadata.php new file mode 100644 index 000000000..0b9b4c97a --- /dev/null +++ b/samples/Orchestration/get-stack-resource-metadata.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get resource in stack. +$resource = $stack->getResource('{stackResourceName}'); + +// 5. Get stack resource metadata. +/** @var $resourceMetadata \stdClass **/ +$resourceMetadata = $resource->getMetadata(); diff --git a/samples/Orchestration/get-stack-resource.php b/samples/Orchestration/get-stack-resource.php new file mode 100644 index 000000000..574691732 --- /dev/null +++ b/samples/Orchestration/get-stack-resource.php @@ -0,0 +1,36 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get resource in stack. +/** @var $resource OpenCloud\Orchestration\Resource\Resource **/ +$resource = $stack->getResource('{stackResourceName}'); diff --git a/samples/Orchestration/get-stack-template.php b/samples/Orchestration/get-stack-template.php new file mode 100644 index 000000000..828697a0e --- /dev/null +++ b/samples/Orchestration/get-stack-template.php @@ -0,0 +1,36 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get stack template. +/** @var $stackTemplate string **/ +$stackTemplate = $stack->getStackTemplate(); diff --git a/samples/Orchestration/get-stack.php b/samples/Orchestration/get-stack.php new file mode 100644 index 000000000..5ad0b731a --- /dev/null +++ b/samples/Orchestration/get-stack.php @@ -0,0 +1,33 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack using the stack name. +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack = $orchestrationService->getStack('{stackName}'); diff --git a/samples/Orchestration/lamp-updated.yaml b/samples/Orchestration/lamp-updated.yaml new file mode 100644 index 000000000..35e65116c --- /dev/null +++ b/samples/Orchestration/lamp-updated.yaml @@ -0,0 +1,184 @@ +heat_template_version: 2013-05-23 + +description: | + This is a Heat template to deploy a server with LAMP + +parameter_groups: +- label: Server Settings + parameters: + - server_hostname + - image + - flavor + +- label: phpMyAdmin Settings + parameters: + - phpmyadmin_user + +- label: rax-dev-params + parameters: + - kitchen + - chef_version + +parameters: + server_hostname: + label: Server Name + description: Hostname to use for setting the server name. + type: string + default: web + constraints: + - length: + min: 1 + max: 64 + - allowed_pattern: "^[a-zA-Z0-9]([a-zA-Z0-9.-])*$" + description: | + Must begin with a letter or number and be alphanumeric or '-' and '.' + + image: + label: Operating System + description: | + Required: Server image used for all servers that are created as a part of + this deployment. + type: string + default: CentOS 6.5 (PVHVM) + constraints: + - allowed_values: + - CentOS 6.5 (PVHVM) + - Red Hat Enterprise Linux 6.5 (PVHVM) + - Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM) + - Ubuntu 12.04 LTS (Precise Pangolin) + - Debian 7 (Wheezy) (PVHVM) + description: Must be a supported operating system. + + flavor: + label: Server Size + description: | + Required: Rackspace Cloud Server flavor to use. The size is based on the + amount of RAM for the provisioned server. + type: string + default: 1 GB General Purpose v1 + constraints: + - allowed_values: + - 1 GB General Purpose v1 + - 2 GB General Purpose v1 + - 4 GB General Purpose v1 + - 8 GB General Purpose v1 + - 15 GB I/O v1 + - 30 GB I/O v1 + description: | + Must be a valid Rackspace Cloud Server flavor for the region you have + selected to deploy into. + + phpmyadmin_user: + label: Username + description: "Username for phpMyAdmin logins." + type: string + default: serverinfo + constraints: + - allowed_pattern: "^(.){1,16}$" + description: | + Must be shorter than 16 characters, this is due to MySQL's maximum + username length. + + kitchen: + description: URL for the kitchen to use + type: string + default: https://github.com/rackspace-orchestration-templates/lamp + + chef_version: + description: Version of chef client to use + type: string + default: 11.12.8 + +resources: + + ssh_key: + type: "OS::Nova::KeyPair" + properties: + name: { get_param: "OS::stack_id" } + save_private_key: true + + mysql_root_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_repl_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_debian_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + phpmyadmin_pass: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + linux_server: + type: "Rackspace::Cloud::Server" + properties: + name: { get_param: server_hostname } + flavor: { get_param: flavor } + image: { get_param: image } + key_name: { get_resource: ssh_key } + config_drive: "true" + metadata: + rax-heat: { get_param: "OS::stack_id" } + metadata: + foo: bar + baz: qux + + linux_setup: + type: "OS::Heat::ChefSolo" + depends_on: linux_server + properties: + username: root + private_key: { get_attr: [ssh_key, private_key] } + host: { get_attr: [linux_server, accessIPv4] } + kitchen: { get_param: kitchen } + chef_version: { get_param: chef_version } + node: + mysql: + server_root_password: { get_attr: [mysql_root_password, value] } + server_repl_password: { get_attr: [mysql_repl_password, value] } + server_debian_password: { get_attr: [mysql_debian_password, value] } + phpmyadmin: + pass: { get_attr: [phpmyadmin_pass, value] } + user: { get_param: phpmyadmin_user } + run_list: ["recipe[LAMP]"] + +outputs: + private_key: + description: SSH Private Key + value: { get_attr: [ssh_key, private_key] } + + server_ip: + description: Server IP + value: { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_url: + description: phpMyAdmin URL + value: + str_replace: + template: "http://%server_ip%/phpmyadmin" + params: + "%server_ip%": { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_user: + description: phpMyAdmin User + value: { get_param: phpmyadmin_user } + + phpmyadmin_password: + description: phpMyAdmin Password + value: { get_attr: [phpmyadmin_pass, value] } + + mysql_root_password: + description: MySQL Root Password + value: { get_attr: [mysql_root_password, value] } diff --git a/samples/Orchestration/lamp.yaml b/samples/Orchestration/lamp.yaml new file mode 100644 index 000000000..7a0c16b64 --- /dev/null +++ b/samples/Orchestration/lamp.yaml @@ -0,0 +1,184 @@ +heat_template_version: 2013-05-23 + +description: | + This is a Heat template to deploy a server with LAMP + +parameter_groups: +- label: Server Settings + parameters: + - server_hostname + - image + - flavor + +- label: phpMyAdmin Settings + parameters: + - phpmyadmin_user + +- label: rax-dev-params + parameters: + - kitchen + - chef_version + +parameters: + server_hostname: + label: Server Name + description: Hostname to use for setting the server name. + type: string + default: web + constraints: + - length: + min: 1 + max: 64 + - allowed_pattern: "^[a-zA-Z0-9]([a-zA-Z0-9.-])*$" + description: | + Must begin with a letter or number and be alphanumeric or '-' and '.' + + image: + label: Operating System + description: | + Required: Server image used for all servers that are created as a part of + this deployment. + type: string + default: CentOS 6.5 (PVHVM) + constraints: + - allowed_values: + - CentOS 6.5 (PVHVM) + - Red Hat Enterprise Linux 6.5 (PVHVM) + - Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM) + - Ubuntu 12.04 LTS (Precise Pangolin) + - Debian 7 (Wheezy) (PVHVM) + description: Must be a supported operating system. + + flavor: + label: Server Size + description: | + Required: Rackspace Cloud Server flavor to use. The size is based on the + amount of RAM for the provisioned server. + type: string + default: 1 GB General Purpose v1 + constraints: + - allowed_values: + - 1 GB General Purpose v1 + - 2 GB General Purpose v1 + - 4 GB General Purpose v1 + - 8 GB General Purpose v1 + - 15 GB I/O v1 + - 30 GB I/O v1 + description: | + Must be a valid Rackspace Cloud Server flavor for the region you have + selected to deploy into. + + phpmyadmin_user: + label: Username + description: "Username for phpMyAdmin logins." + type: string + default: serverinfo + constraints: + - allowed_pattern: "^(.){1,16}$" + description: | + Must be shorter than 16 characters, this is due to MySQL's maximum + username length. + + kitchen: + description: URL for the kitchen to use + type: string + default: https://github.com/rackspace-orchestration-templates/lamp + + chef_version: + description: Version of chef client to use + type: string + default: 11.12.8 + +resources: + + ssh_key: + type: "OS::Nova::KeyPair" + properties: + name: { get_param: "OS::stack_id" } + save_private_key: true + + mysql_root_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_repl_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_debian_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + phpmyadmin_pass: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + linux_server: + type: "Rackspace::Cloud::Server" + properties: + name: { get_param: server_hostname } + flavor: { get_param: flavor } + image: { get_param: image } + key_name: { get_resource: ssh_key } + config_drive: "true" + metadata: + rax-heat: { get_param: "OS::stack_id" } + metadata: + foo: bar + baz: brrr + + linux_setup: + type: "OS::Heat::ChefSolo" + depends_on: linux_server + properties: + username: root + private_key: { get_attr: [ssh_key, private_key] } + host: { get_attr: [linux_server, accessIPv4] } + kitchen: { get_param: kitchen } + chef_version: { get_param: chef_version } + node: + mysql: + server_root_password: { get_attr: [mysql_root_password, value] } + server_repl_password: { get_attr: [mysql_repl_password, value] } + server_debian_password: { get_attr: [mysql_debian_password, value] } + phpmyadmin: + pass: { get_attr: [phpmyadmin_pass, value] } + user: { get_param: phpmyadmin_user } + run_list: ["recipe[LAMP]"] + +outputs: + private_key: + description: SSH Private Key + value: { get_attr: [ssh_key, private_key] } + + server_ip: + description: Server IP + value: { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_url: + description: phpMyAdmin URL + value: + str_replace: + template: "http://%server_ip%/phpmyadmin" + params: + "%server_ip%": { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_user: + description: phpMyAdmin User + value: { get_param: phpmyadmin_user } + + phpmyadmin_password: + description: phpMyAdmin Password + value: { get_attr: [phpmyadmin_pass, value] } + + mysql_root_password: + description: MySQL Root Password + value: { get_attr: [mysql_root_password, value] } diff --git a/samples/Orchestration/list-resource-types.php b/samples/Orchestration/list-resource-types.php new file mode 100644 index 000000000..3d70eca47 --- /dev/null +++ b/samples/Orchestration/list-resource-types.php @@ -0,0 +1,36 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get resource types. +$resourceTypes = $orchestrationService->listResourceTypes(); + +foreach ($resourceTypes as $resourceType) { + /** @var $resourceType OpenCloud\Orchestration\Resource\ResourceType **/ +} diff --git a/samples/Orchestration/list-stack-events.php b/samples/Orchestration/list-stack-events.php new file mode 100644 index 000000000..3ed4533db --- /dev/null +++ b/samples/Orchestration/list-stack-events.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get list of events for the stack. +$stackEvents = $stack->listEvents(); + +foreach ($stackEvents as $stackEvent) { + /** @var $stackEvent OpenCloud\Orchestration\Resource\Event **/ +} diff --git a/samples/Orchestration/list-stack-resource-events.php b/samples/Orchestration/list-stack-resource-events.php new file mode 100644 index 000000000..29e9e81ec --- /dev/null +++ b/samples/Orchestration/list-stack-resource-events.php @@ -0,0 +1,42 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get resource in stack. +$resource = $stack->getResource('{stackResourceName}'); + +// 5. Get list of events for the stack resource. +$resourceEvents = $resource->listEvents(); + +foreach ($resourceEvents as $resourceEvent) { + /** @var $resourceEvent OpenCloud\Orchestration\Resource\Event **/ +} diff --git a/samples/Orchestration/list-stack-resources.php b/samples/Orchestration/list-stack-resources.php new file mode 100644 index 000000000..eb6e47e2a --- /dev/null +++ b/samples/Orchestration/list-stack-resources.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Get list of resources in the stack. +$resources = $stack->listResources(); + +foreach ($resources as $resource) { + /** @var $resource OpenCloud\Orchestration\Resource\Resource **/ +} diff --git a/samples/Orchestration/list-stacks.php b/samples/Orchestration/list-stacks.php new file mode 100644 index 000000000..6edc47db4 --- /dev/null +++ b/samples/Orchestration/list-stacks.php @@ -0,0 +1,36 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stacks. +$stacks = $orchestrationService->listStacks(); + +foreach ($stacks as $stack) { + /** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +} diff --git a/samples/Orchestration/preview-stack-from-template-file.php b/samples/Orchestration/preview-stack-from-template-file.php new file mode 100644 index 000000000..480798ce4 --- /dev/null +++ b/samples/Orchestration/preview-stack-from-template-file.php @@ -0,0 +1,40 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Preview a stack. +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack = $orchestrationService->previewStack(array( + 'name' => '{name}', + 'template' => file_get_contents('{yamlTemplateFilePath}'), + 'parameters' => array( + 'server_hostname' => '{serverHost}', + 'image' => '{image}' + ) +)); diff --git a/samples/Orchestration/preview-stack-from-template-url.php b/samples/Orchestration/preview-stack-from-template-url.php new file mode 100644 index 000000000..bced6086e --- /dev/null +++ b/samples/Orchestration/preview-stack-from-template-url.php @@ -0,0 +1,40 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Preview a stack. +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack = $orchestrationService->previewStack(array( + 'name' => '{name}', + 'templateUrl' => '{templateUrl}', + 'parameters' => array( + 'server_hostname' => '{serverHost}', + 'image' => '{image}' + ) +)); diff --git a/samples/Orchestration/quickstart.php b/samples/Orchestration/quickstart.php new file mode 100644 index 000000000..a81540bf0 --- /dev/null +++ b/samples/Orchestration/quickstart.php @@ -0,0 +1,40 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Create a stack. +$stack = $orchestrationService->createStack(array( + 'name' => '{name}', + 'templateUrl' => '{templateUrl}', + 'parameters' => array( + 'server_hostname' => '{serverHost}', + 'image' => '{image}' + ), + 'timeoutMins' => 5 +)); diff --git a/samples/Orchestration/update-stack-from-template-file.php b/samples/Orchestration/update-stack-from-template-file.php new file mode 100644 index 000000000..52219e4b2 --- /dev/null +++ b/samples/Orchestration/update-stack-from-template-file.php @@ -0,0 +1,42 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Update stack. +$stack->update(array( + 'template' => '{yamlTemplateFilePath}', + 'parameters' => array( + 'server_hostname' => '{serverHost}', + 'image' => '{image}' + ), + 'timeoutMins' => 5 +)); diff --git a/samples/Orchestration/update-stack-from-template-url.php b/samples/Orchestration/update-stack-from-template-url.php new file mode 100644 index 000000000..23cae7be0 --- /dev/null +++ b/samples/Orchestration/update-stack-from-template-url.php @@ -0,0 +1,43 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Get stack. +$stack = $orchestrationService->getStack('{stackName}'); + +// 4. Update stack. +/** @var $stack OpenCloud\Orchestration\Resource\Stack **/ +$stack->update(array( + 'templateUrl' => '{templateUrl}', + 'parameters' => array( + 'server_hostname' => '{serverHost}', + 'image' => '{image}' + ), + 'timeoutMins' => 5 +)); diff --git a/samples/Orchestration/validate-template-from-template-file.php b/samples/Orchestration/validate-template-from-template-file.php new file mode 100644 index 000000000..c8b179d55 --- /dev/null +++ b/samples/Orchestration/validate-template-from-template-file.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Validate template from file. +try { + $orchestrationService->validateTemplate(array( + 'template' => '{yamlTemplateFilePath}', + )); +} catch (InvalidTemplateError $e) { + // Use $e->getMessage() for explanation of why template is invalid +} diff --git a/samples/Orchestration/validate-template-from-template-url.php b/samples/Orchestration/validate-template-from-template-url.php new file mode 100644 index 000000000..6cce6b4b4 --- /dev/null +++ b/samples/Orchestration/validate-template-from-template-url.php @@ -0,0 +1,39 @@ + '{username}', + 'password' => '{password}', +)); + +// 2. Obtain an Orchestration service object from the client. +$orchestrationService = $client->orchestrationService(null, '{region}'); + +// 3. Validate template from URL +try { + $orchestrationService->validateTemplate(array( + 'templateUrl' => '{templateUrl}' + )); +} catch (InvalidTemplateError $e) { + // Use $e->getMessage() for explanation of why template is invalid +} diff --git a/samples/Queues/add-message.php b/samples/Queues/add-message.php new file mode 100644 index 000000000..fce3b742c --- /dev/null +++ b/samples/Queues/add-message.php @@ -0,0 +1,48 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->queuesService(null, '{region}'); + +// You MUST set a client ID before executing any operation. This ID must be a +// valid UUID. The SDK can set a random UUID for you if you don't want to +// define your own, just leave the argument empty. +$service->setClientId(); + +// Get your queue +$queue = $service->getQueue('{queueName}'); + +// Post a new message. 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 +$queue->createMessage(array( + 'body' => (object) array( // This can be anything you want + 'event' => 'foo' // and not necessarily an object + ), + 'ttl' => 2 * Datetime::DAY, +)); diff --git a/samples/Queues/claim-messages.php b/samples/Queues/claim-messages.php new file mode 100644 index 000000000..89d3825f3 --- /dev/null +++ b/samples/Queues/claim-messages.php @@ -0,0 +1,50 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->queuesService(null, '{region}'); + +// You MUST set a client ID before executing any operation. This ID must be a +// valid UUID. The SDK can set a random UUID for you if you don't want to +// define your own, just leave the argument empty. +$service->setClientId(); + +// Get your queue +$queue = $service->getQueue('{queueName}'); + +// Claim messages that fall under a few conditions: limit the claim size to 15, +// set the grace and TTL period to 5 minutes. These are just examples and may +// be replaced. +$messages = $queue->claimMessages(array( + 'limit' => 15, + 'grace' => 5 * Datetime::MINUTE, + 'ttl' => 5 * Datetime::MINUTE +)); + +// Iterate over your claimed messages in order to perform computation on them. +foreach ($messages as $message) { + /** @var OpenCloud\Queues\Resource\Message */ +} diff --git a/samples/Queues/create-queue.php b/samples/Queues/create-queue.php new file mode 100644 index 000000000..28aa0c659 --- /dev/null +++ b/samples/Queues/create-queue.php @@ -0,0 +1,36 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->queuesService(null, '{region}'); + +// You MUST set a client ID before executing any operation. This ID must be a +// valid UUID. The SDK can set a random UUID for you if you don't want to +// define your own, just leave the argument empty. +$service->setClientId(); + +// Create a new queue +$queue = $service->createQueue('{queueName}'); diff --git a/samples/Queues/delete-queue.php b/samples/Queues/delete-queue.php new file mode 100644 index 000000000..1ec8db139 --- /dev/null +++ b/samples/Queues/delete-queue.php @@ -0,0 +1,39 @@ + '{username}', + 'apiKey' => '{apiKey}', +)); + +$service = $client->queuesService(null, '{region}'); + +// You MUST set a client ID before executing any operation. This ID must be a +// valid UUID. The SDK can set a random UUID for you if you don't want to +// define your own, just leave the argument empty. +$service->setClientId(); + +// Get an existing queue +$queue = $service->getQueue('{queueName}'); + +// Permanently delete it +$queue->delete(); diff --git a/samples/Volume/create-bootable-volume.php b/samples/Volume/create-bootable-volume.php index 9a5f61f4e..687b79b81 100644 --- a/samples/Volume/create-bootable-volume.php +++ b/samples/Volume/create-bootable-volume.php @@ -15,26 +15,17 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_BOOT_IMAGE_ID: ID of image with bootable operating system on it -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Create the volume. Specify a name and size (in GB). You may optionally // specify a volume type, which is either 'SSD' (faster, more expensive), or @@ -45,5 +36,5 @@ 'size' => 1000, 'volume_type' => 'SSD', 'bootable' => true, - 'imageRef' => getenv('RAX_BOOT_IMAGE_ID') + 'imageRef' => '{imageId}' )); diff --git a/samples/Volume/create-snapshot.php b/samples/Volume/create-snapshot.php index b04199a1c..49b16fb1d 100644 --- a/samples/Volume/create-snapshot.php +++ b/samples/Volume/create-snapshot.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * RAX_VOLUME_ID: ID of the volume you want to snapshot. Run create-volume.php if -// you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Snapshot service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the volume you want to snapshot. -$volume = $volumeService->volume(getenv('RAX_VOLUME_ID')); +$volume = $volumeService->volume('{volumeId}'); // 4. Create the snapshot. Specify a name and the volume ID. $snapshot = $volumeService->snapshot(); diff --git a/samples/Volume/create-volume.php b/samples/Volume/create-volume.php index 47a6b2610..d950f4f70 100644 --- a/samples/Volume/create-volume.php +++ b/samples/Volume/create-volume.php @@ -15,25 +15,17 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Create the volume. Specify a name and size (in GB). You may optionally // specify a volume type, which is either 'SSD' (faster, more expensive), or diff --git a/samples/Volume/delete-snapshot.php b/samples/Volume/delete-snapshot.php index ec237e85e..09012d60b 100644 --- a/samples/Volume/delete-snapshot.php +++ b/samples/Volume/delete-snapshot.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_SNAPSHOT_ID: ID of the snapshot you want to update. Run create-snapshot.php if -// you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the snapshot. -$snapshot = $volumeService->snapshot(getenv('RAX_SNAPSHOT_ID')); +$snapshot = $volumeService->snapshot('{snapshotId}'); // 4. Delete it. $snapshot->delete(); diff --git a/samples/Volume/delete-volume.php b/samples/Volume/delete-volume.php index 60d12b0be..d68210f47 100644 --- a/samples/Volume/delete-volume.php +++ b/samples/Volume/delete-volume.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_VOLUME_ID: ID of the volume you want to update. Run create-volume.php if -// you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the volume. -$volume = $volumeService->volume(getenv('RAX_VOLUME_ID')); +$volume = $volumeService->volume('{volumeId}'); // 4. Delete it. $volume->delete(); diff --git a/samples/Volume/get-snapshot.php b/samples/Volume/get-snapshot.php index ad3db4d00..ff0896c6f 100644 --- a/samples/Volume/get-snapshot.php +++ b/samples/Volume/get-snapshot.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_SNAPSHOT_ID: ID of the volume you want to get. Run create-volume.php if -// you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the volume. -$snapshot = $volumeService->snapshot(getenv('RAX_SNAPSHOT_ID')); +$snapshot = $volumeService->snapshot('{snapshotId}'); /** @var $snapshot OpenCloud\Volume\Resource\Snapshot **/ echo "ID: " . $snapshot->id() . " | " . "Name: " . $snapshot->name() . PHP_EOL; diff --git a/samples/Volume/get-volume.php b/samples/Volume/get-volume.php index 172726156..e88ba7e7c 100644 --- a/samples/Volume/get-volume.php +++ b/samples/Volume/get-volume.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_VOLUME_ID: ID of the volume you want to get. Run create-volume.php if -// you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the volume. -$volume = $volumeService->volume(getenv('RAX_VOLUME_ID')); +$volume = $volumeService->volume('{volumeId}'); /** @var $volume OpenCloud\Volume\Resource\Volume **/ echo "ID: " . $volume->id() . " | " . "Name: " . $volume->name() . PHP_EOL; diff --git a/samples/Volume/list-snapshots.php b/samples/Volume/list-snapshots.php index fe4d1a7d4..0e1f2f8b1 100644 --- a/samples/Volume/list-snapshots.php +++ b/samples/Volume/list-snapshots.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// * RAX_VOLUME_ID: ID of the volume whose snapshots you want to list. Run -// create-volume.php if you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the volume you want to snapshot. -$volume = $volumeService->volume(getenv('RAX_VOLUME_ID')); +$volume = $volumeService->volume('{volumeId}'); // 4. Get snapshot list for volume. $snapshots = $volumeService->snapshotList(array( diff --git a/samples/Volume/list-volumes.php b/samples/Volume/list-volumes.php index 43c88d8d6..18003855e 100644 --- a/samples/Volume/list-volumes.php +++ b/samples/Volume/list-volumes.php @@ -15,29 +15,21 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get volume list. $volumes = $volumeService->volumeList(); foreach ($volumes as $volume) { /** @var $volume OpenCloud\Volume\Resource\Volume **/ echo "ID: " . $volume->id() . " | " . "Name: " . $volume->name() . PHP_EOL; -} \ No newline at end of file +} diff --git a/samples/Volume/rename-snapshot.php b/samples/Volume/rename-snapshot.php index db407721f..47e9f0dc5 100644 --- a/samples/Volume/rename-snapshot.php +++ b/samples/Volume/rename-snapshot.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_SNAPSHOT_ID: ID of the snapshot you want to rename. Run create-snapshot.php -// if you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the snapshot. -$snapshot = $volumeService->snapshot(getenv('RAX_SNAPSHOT_ID')); +$snapshot = $volumeService->snapshot('{snapshotId}'); // 4. Update its name and description. $snapshot->rename(array( diff --git a/samples/Volume/rename-volume.php b/samples/Volume/rename-volume.php index e886abb87..4855dc7dd 100644 --- a/samples/Volume/rename-volume.php +++ b/samples/Volume/rename-volume.php @@ -15,30 +15,20 @@ * limitations under the License. */ -// -// Pre-requisites: -// * Prior to running this script, you must setup the following environment variables: -// * RAX_USERNAME: Your Rackspace Cloud Account Username, and -// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and -// * RAX_VOLUME_ID: ID of the volume you want to rename. Run create-volume.php if -// you need to create one first. -// - require __DIR__ . '/../../vendor/autoload.php'; use OpenCloud\Rackspace; // 1. Instantiate a Rackspace client. -$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( - 'username' => getenv('RAX_USERNAME'), - 'apiKey' => getenv('RAX_API_KEY') +$client = new Rackspace('{authUrl}', array( + 'username' => '{username}', + 'apiKey' => '{apiKey}', )); // 2. Obtain a Volume service object from the client. -$region = 'DFW'; -$volumeService = $client->volumeService(null, $region); +$volumeService = $client->volumeService(null, '{region}'); // 3. Get the volume. -$volume = $volumeService->volume(getenv('RAX_VOLUME_ID')); +$volume = $volumeService->volume('{volumeId}'); // 4. Update its name and description. $volume->rename(array( diff --git a/tests/OpenCloud/Smoke/.gitignore b/tests/OpenCloud/Smoke/.gitignore deleted file mode 100644 index 62112125e..000000000 --- a/tests/OpenCloud/Smoke/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Resource/ diff --git a/tests/OpenCloud/Smoke/Enum.php b/tests/OpenCloud/Smoke/Enum.php index 76b293cde..a25b1386c 100644 --- a/tests/OpenCloud/Smoke/Enum.php +++ b/tests/OpenCloud/Smoke/Enum.php @@ -28,12 +28,11 @@ /** * Description of Enum - * - * @link + * + * @link */ class Enum { - const USER_AGENT = 'PHP OpenCloud SMOKETEST'; const CREDS_FILENAME = '.smoketestCredentials'; @@ -49,11 +48,10 @@ class Enum const ENV_IDENTITY_ENDPOINT = 'IDENTITY_ENDPOINT'; // Defaults - const DEFAULT_REGION = 'ORD'; + const DEFAULT_REGION = 'IAD'; // How many iterations do we want for resource lists? We don't have all day... const DISPLAY_ITER_LIMIT = 10; const DIVIDER = '-------------'; - } diff --git a/tests/OpenCloud/Smoke/Logger.php b/tests/OpenCloud/Smoke/Logger.php index b43053ce8..f1a884b38 100644 --- a/tests/OpenCloud/Smoke/Logger.php +++ b/tests/OpenCloud/Smoke/Logger.php @@ -22,11 +22,9 @@ class Logger extends AbstractLogger { - public function log($level, $message, array $context = array()) { $logger = new CommonLogger(); return $logger->log($level, $message, $context); } - } diff --git a/tests/OpenCloud/Smoke/Resource/.gitignore b/tests/OpenCloud/Smoke/Resource/.gitignore new file mode 100644 index 000000000..836d1ecc8 --- /dev/null +++ b/tests/OpenCloud/Smoke/Resource/.gitignore @@ -0,0 +1 @@ +ObjectStore/ diff --git a/tests/OpenCloud/Smoke/Resource/Orchestration/lamp-updated.yaml b/tests/OpenCloud/Smoke/Resource/Orchestration/lamp-updated.yaml new file mode 100644 index 000000000..35e65116c --- /dev/null +++ b/tests/OpenCloud/Smoke/Resource/Orchestration/lamp-updated.yaml @@ -0,0 +1,184 @@ +heat_template_version: 2013-05-23 + +description: | + This is a Heat template to deploy a server with LAMP + +parameter_groups: +- label: Server Settings + parameters: + - server_hostname + - image + - flavor + +- label: phpMyAdmin Settings + parameters: + - phpmyadmin_user + +- label: rax-dev-params + parameters: + - kitchen + - chef_version + +parameters: + server_hostname: + label: Server Name + description: Hostname to use for setting the server name. + type: string + default: web + constraints: + - length: + min: 1 + max: 64 + - allowed_pattern: "^[a-zA-Z0-9]([a-zA-Z0-9.-])*$" + description: | + Must begin with a letter or number and be alphanumeric or '-' and '.' + + image: + label: Operating System + description: | + Required: Server image used for all servers that are created as a part of + this deployment. + type: string + default: CentOS 6.5 (PVHVM) + constraints: + - allowed_values: + - CentOS 6.5 (PVHVM) + - Red Hat Enterprise Linux 6.5 (PVHVM) + - Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM) + - Ubuntu 12.04 LTS (Precise Pangolin) + - Debian 7 (Wheezy) (PVHVM) + description: Must be a supported operating system. + + flavor: + label: Server Size + description: | + Required: Rackspace Cloud Server flavor to use. The size is based on the + amount of RAM for the provisioned server. + type: string + default: 1 GB General Purpose v1 + constraints: + - allowed_values: + - 1 GB General Purpose v1 + - 2 GB General Purpose v1 + - 4 GB General Purpose v1 + - 8 GB General Purpose v1 + - 15 GB I/O v1 + - 30 GB I/O v1 + description: | + Must be a valid Rackspace Cloud Server flavor for the region you have + selected to deploy into. + + phpmyadmin_user: + label: Username + description: "Username for phpMyAdmin logins." + type: string + default: serverinfo + constraints: + - allowed_pattern: "^(.){1,16}$" + description: | + Must be shorter than 16 characters, this is due to MySQL's maximum + username length. + + kitchen: + description: URL for the kitchen to use + type: string + default: https://github.com/rackspace-orchestration-templates/lamp + + chef_version: + description: Version of chef client to use + type: string + default: 11.12.8 + +resources: + + ssh_key: + type: "OS::Nova::KeyPair" + properties: + name: { get_param: "OS::stack_id" } + save_private_key: true + + mysql_root_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_repl_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_debian_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + phpmyadmin_pass: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + linux_server: + type: "Rackspace::Cloud::Server" + properties: + name: { get_param: server_hostname } + flavor: { get_param: flavor } + image: { get_param: image } + key_name: { get_resource: ssh_key } + config_drive: "true" + metadata: + rax-heat: { get_param: "OS::stack_id" } + metadata: + foo: bar + baz: qux + + linux_setup: + type: "OS::Heat::ChefSolo" + depends_on: linux_server + properties: + username: root + private_key: { get_attr: [ssh_key, private_key] } + host: { get_attr: [linux_server, accessIPv4] } + kitchen: { get_param: kitchen } + chef_version: { get_param: chef_version } + node: + mysql: + server_root_password: { get_attr: [mysql_root_password, value] } + server_repl_password: { get_attr: [mysql_repl_password, value] } + server_debian_password: { get_attr: [mysql_debian_password, value] } + phpmyadmin: + pass: { get_attr: [phpmyadmin_pass, value] } + user: { get_param: phpmyadmin_user } + run_list: ["recipe[LAMP]"] + +outputs: + private_key: + description: SSH Private Key + value: { get_attr: [ssh_key, private_key] } + + server_ip: + description: Server IP + value: { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_url: + description: phpMyAdmin URL + value: + str_replace: + template: "http://%server_ip%/phpmyadmin" + params: + "%server_ip%": { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_user: + description: phpMyAdmin User + value: { get_param: phpmyadmin_user } + + phpmyadmin_password: + description: phpMyAdmin Password + value: { get_attr: [phpmyadmin_pass, value] } + + mysql_root_password: + description: MySQL Root Password + value: { get_attr: [mysql_root_password, value] } diff --git a/tests/OpenCloud/Smoke/Resource/Orchestration/lamp.yaml b/tests/OpenCloud/Smoke/Resource/Orchestration/lamp.yaml new file mode 100644 index 000000000..7a0c16b64 --- /dev/null +++ b/tests/OpenCloud/Smoke/Resource/Orchestration/lamp.yaml @@ -0,0 +1,184 @@ +heat_template_version: 2013-05-23 + +description: | + This is a Heat template to deploy a server with LAMP + +parameter_groups: +- label: Server Settings + parameters: + - server_hostname + - image + - flavor + +- label: phpMyAdmin Settings + parameters: + - phpmyadmin_user + +- label: rax-dev-params + parameters: + - kitchen + - chef_version + +parameters: + server_hostname: + label: Server Name + description: Hostname to use for setting the server name. + type: string + default: web + constraints: + - length: + min: 1 + max: 64 + - allowed_pattern: "^[a-zA-Z0-9]([a-zA-Z0-9.-])*$" + description: | + Must begin with a letter or number and be alphanumeric or '-' and '.' + + image: + label: Operating System + description: | + Required: Server image used for all servers that are created as a part of + this deployment. + type: string + default: CentOS 6.5 (PVHVM) + constraints: + - allowed_values: + - CentOS 6.5 (PVHVM) + - Red Hat Enterprise Linux 6.5 (PVHVM) + - Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM) + - Ubuntu 12.04 LTS (Precise Pangolin) + - Debian 7 (Wheezy) (PVHVM) + description: Must be a supported operating system. + + flavor: + label: Server Size + description: | + Required: Rackspace Cloud Server flavor to use. The size is based on the + amount of RAM for the provisioned server. + type: string + default: 1 GB General Purpose v1 + constraints: + - allowed_values: + - 1 GB General Purpose v1 + - 2 GB General Purpose v1 + - 4 GB General Purpose v1 + - 8 GB General Purpose v1 + - 15 GB I/O v1 + - 30 GB I/O v1 + description: | + Must be a valid Rackspace Cloud Server flavor for the region you have + selected to deploy into. + + phpmyadmin_user: + label: Username + description: "Username for phpMyAdmin logins." + type: string + default: serverinfo + constraints: + - allowed_pattern: "^(.){1,16}$" + description: | + Must be shorter than 16 characters, this is due to MySQL's maximum + username length. + + kitchen: + description: URL for the kitchen to use + type: string + default: https://github.com/rackspace-orchestration-templates/lamp + + chef_version: + description: Version of chef client to use + type: string + default: 11.12.8 + +resources: + + ssh_key: + type: "OS::Nova::KeyPair" + properties: + name: { get_param: "OS::stack_id" } + save_private_key: true + + mysql_root_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_repl_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + mysql_debian_password: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + phpmyadmin_pass: + type: "OS::Heat::RandomString" + properties: + length: 16 + sequence: lettersdigits + + linux_server: + type: "Rackspace::Cloud::Server" + properties: + name: { get_param: server_hostname } + flavor: { get_param: flavor } + image: { get_param: image } + key_name: { get_resource: ssh_key } + config_drive: "true" + metadata: + rax-heat: { get_param: "OS::stack_id" } + metadata: + foo: bar + baz: brrr + + linux_setup: + type: "OS::Heat::ChefSolo" + depends_on: linux_server + properties: + username: root + private_key: { get_attr: [ssh_key, private_key] } + host: { get_attr: [linux_server, accessIPv4] } + kitchen: { get_param: kitchen } + chef_version: { get_param: chef_version } + node: + mysql: + server_root_password: { get_attr: [mysql_root_password, value] } + server_repl_password: { get_attr: [mysql_repl_password, value] } + server_debian_password: { get_attr: [mysql_debian_password, value] } + phpmyadmin: + pass: { get_attr: [phpmyadmin_pass, value] } + user: { get_param: phpmyadmin_user } + run_list: ["recipe[LAMP]"] + +outputs: + private_key: + description: SSH Private Key + value: { get_attr: [ssh_key, private_key] } + + server_ip: + description: Server IP + value: { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_url: + description: phpMyAdmin URL + value: + str_replace: + template: "http://%server_ip%/phpmyadmin" + params: + "%server_ip%": { get_attr: [linux_server, accessIPv4] } + + phpmyadmin_user: + description: phpMyAdmin User + value: { get_param: phpmyadmin_user } + + phpmyadmin_password: + description: phpMyAdmin Password + value: { get_attr: [phpmyadmin_pass, value] } + + mysql_root_password: + description: MySQL Root Password + value: { get_attr: [mysql_root_password, value] } diff --git a/tests/OpenCloud/Smoke/Runner.php b/tests/OpenCloud/Smoke/Runner.php index a387c6c99..57dc8852a 100644 --- a/tests/OpenCloud/Smoke/Runner.php +++ b/tests/OpenCloud/Smoke/Runner.php @@ -30,17 +30,19 @@ class Runner { /** * These are the individual tests, or units, that can execute. - * - * @var array + * + * @var array */ private $units = array( 'Autoscale', 'Compute', 'CloudMonitoring', + 'CDN', 'DNS', 'Database', 'Identity', 'LoadBalancer', + 'Networking', 'ObjectStore', 'Orchestration', 'Queues', @@ -90,7 +92,7 @@ private function formatDuration($duration) } private function handleArguments() - { + { $options = getopt('D::H::E::I::A', array( 'debug::', 'help::', @@ -174,7 +176,6 @@ public function executeTemplate() $client = $this->createClient(); foreach ($this->included as $unit) { - $class = __NAMESPACE__ . '\\Unit\\' . $unit; if (!class_exists($class)) { @@ -197,10 +198,10 @@ public function executeTemplate() private function createClient() { - Utils::log('Authenticate'); + Utils::log('Authenticate'); $secret = array( - 'username' => Utils::getEnvVar(Enum::ENV_USERNAME), + 'username' => Utils::getEnvVar(Enum::ENV_USERNAME), 'apiKey' => Utils::getEnvVar(Enum::ENV_API_KEY) ); @@ -223,7 +224,6 @@ private function createClient() return $client; } - } require __DIR__ . '/../../bootstrap.php'; diff --git a/tests/OpenCloud/Smoke/SmokeException.php b/tests/OpenCloud/Smoke/SmokeException.php index 107af2318..ed7953d90 100644 --- a/tests/OpenCloud/Smoke/SmokeException.php +++ b/tests/OpenCloud/Smoke/SmokeException.php @@ -30,8 +30,8 @@ /** * Description of SmokeException - * - * @link + * + * @link */ class SmokeException extends Exception { diff --git a/tests/OpenCloud/Smoke/Step.php b/tests/OpenCloud/Smoke/Step.php index 8744c19b8..9009e5026 100644 --- a/tests/OpenCloud/Smoke/Step.php +++ b/tests/OpenCloud/Smoke/Step.php @@ -28,8 +28,8 @@ /** * Description of Step - * - * @link + * + * @link */ class Step { @@ -43,7 +43,7 @@ class Step public $message; /** - * @var string Either default, `spacer` or `dotter`. + * @var string Either default, `spacer` or `dotter`. */ public $outputType; @@ -58,7 +58,7 @@ class Step public $depth = 0; /** - * @var int The count for this step. + * @var int The count for this step. */ public $count = 1; @@ -136,7 +136,7 @@ public function getOutput() switch ($this->getOutputType()) { default: $leadingLine = true; - $outputString = sprintf('%d. %s', $this->getCount(), $this->getMessage()); + $outputString = sprintf('%d. %s', $this->getCount(), $this->getMessage()); break; case self::TYPE_DOTTER: $outputString = sprintf('... %s', $this->getMessage()); @@ -146,9 +146,9 @@ public function getOutput() break; } - return ((isset($leadingLine)) ? PHP_EOL : '') + return ((isset($leadingLine)) ? PHP_EOL : '') . $this->computeSpacePrefix() . $outputString; - } + } private function computeSpacePrefix() { @@ -198,5 +198,4 @@ public function createSubStep($string, $outputType = null) ->setCount($this->getCount() + 1) ->output(); } - } diff --git a/tests/OpenCloud/Smoke/Unit/AbstractUnit.php b/tests/OpenCloud/Smoke/Unit/AbstractUnit.php index 4ff1011cf..08896aefc 100644 --- a/tests/OpenCloud/Smoke/Unit/AbstractUnit.php +++ b/tests/OpenCloud/Smoke/Unit/AbstractUnit.php @@ -25,29 +25,29 @@ /** * Description of AbstractUnit - * - * @link + * + * @link */ -abstract class AbstractUnit +abstract class AbstractUnit extends \PHPUnit_Framework_TestCase { /** * The credentials cache filename. - * - * @var string + * + * @var string */ private $credentialsCacheFile; /** * The connection object which everything routes through. - * + * * @var OpenCloud\OpenStack */ protected $connection; /** * The particular service that each unit uses. - * - * @var OpenCloud\Common\Service + * + * @var OpenCloud\Common\Service */ protected $service; @@ -57,9 +57,9 @@ abstract class AbstractUnit protected $includedUnits; /** - * Factory method for instantiating the unit object, and executing its + * Factory method for instantiating the unit object, and executing its * main algorithm. - * + * * @return UnitInterface */ public static function factory(OpenStack $connection, array $includedUnits) @@ -118,9 +118,10 @@ public function getIncludedUnits() public function getWaiterCallback() { - return function($object) { + return function ($object) { if (!empty($object->error)) { - var_dump($object->error); die; + var_dump($object->error); + die; } else { $this->stepInfoDotter( "Waiting on %s/%-12s %4s%%", @@ -184,4 +185,10 @@ public function createSubStep($string, $outputType = null) return $step->output(); } + protected function getResourceDir() + { + $className = get_class($this); + $className = join('', array_slice(explode('\\', $className), -1)); + return __DIR__ . '/../Resource/' . $className; + } } diff --git a/tests/OpenCloud/Smoke/Unit/Autoscale.php b/tests/OpenCloud/Smoke/Unit/Autoscale.php index f470437aa..10e44e7ad 100644 --- a/tests/OpenCloud/Smoke/Unit/Autoscale.php +++ b/tests/OpenCloud/Smoke/Unit/Autoscale.php @@ -19,13 +19,11 @@ class Autoscale extends AbstractUnit implements UnitInterface { - /** * {@inheritDoc} */ public function setupService() { - } /** @@ -33,7 +31,6 @@ public function setupService() */ public function main() { - } /** @@ -41,7 +38,5 @@ public function main() */ public function teardown() { - } - } diff --git a/tests/OpenCloud/Smoke/Unit/CDN.php b/tests/OpenCloud/Smoke/Unit/CDN.php new file mode 100644 index 000000000..da828676b --- /dev/null +++ b/tests/OpenCloud/Smoke/Unit/CDN.php @@ -0,0 +1,100 @@ +getConnection()->cdnService(); + return $service; + } + + public function main() + { + $this->step('Get home document'); + $homeDocument = $this->getService()->getHomeDocument(); + $this->stepInfo('Home document: %s', json_encode($homeDocument)); + + $this->step('Get ping'); + $ping = $this->getService()->getPing(); + $this->stepInfo('Ping successful'); + + $this->step('List flavors'); + $flavors = $this->getService()->listFlavors(); + $this->stepInfo('%-40s | %s', 'Flavor ID', 'Number of providers'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($flavors as $flavor) { + $this->stepInfo('%-40s | %d', $flavor->getId(), count($flavor->getProviders())); + } + + $this->step('Create service'); + $createdService = $this->getService()->createService(array( + 'name' => 'php-opencloud.com', + 'domains' => array( + array( 'domain' => 'php-opencloud.com' ), + array( 'domain' => 'www.php-opencloud.com' ) + ), + 'origins' => array( + array( 'origin' => 'origin.php-opencloud.com' ) + ), + 'flavorId' => 'cdn' + )); + $this->stepInfo('Service name: ' . $createdService->getName()); + + $this->step('List services'); + $services = $this->getService()->listServices(); + $this->stepInfo('%-40s | %s', 'Service Name', 'Number of domains'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($services as $service) { + $this->stepInfo('%-40s | %d', $service->getName(), count($service->getDomains())); + } + + $this->step('Get service'); + $service = $this->getService()->getService($createdService->getId()); + $this->stepInfo('Service name: ' . $service->getName()); + $this->stepInfo('Status: ' . $service->getStatus()); + $origins = $service->getOrigins(); + $this->stepInfo('Origin: ' . $origins[0]->origin); + + $this->step('Update service'); + $service->waitFor('deployed', null, function ($s) { + $this->stepInfo('Service is still being created. Waiting...'); + }); + $service->update(array( + 'origins' => array( + array( 'origin' => 'updated-origin.php-opencloud.com' ) + ) + )); + + $this->step('Purge ALL cached service assets'); + $service->waitFor('deployed', null, function ($s) { + $this->stepInfo('Service is still being updated. Waiting...'); + }); + $service->purgeAssets(); + + $this->step('Delete service'); + $createdService->delete(); + } + + public function teardown() + { + } +} diff --git a/tests/OpenCloud/Smoke/Unit/CloudMonitoring.php b/tests/OpenCloud/Smoke/Unit/CloudMonitoring.php index 2bf609d70..b01543f70 100644 --- a/tests/OpenCloud/Smoke/Unit/CloudMonitoring.php +++ b/tests/OpenCloud/Smoke/Unit/CloudMonitoring.php @@ -21,8 +21,8 @@ /** * Description of CloudMonitoring - * - * @link + * + * @link */ class CloudMonitoring extends AbstractUnit implements UnitInterface { @@ -318,7 +318,7 @@ public function doMonitoringZonesBlock() $zone = $this->getService()->getMonitoringZone($zoneId); // perform traceroute - $trace = $zone->traceroute(array('target' => self::TRACEROUTE_TARGET,'target_resolver' => 'IPv4')); + $trace = $zone->traceroute(array('target' => self::TRACEROUTE_TARGET, 'target_resolver' => 'IPv4')); $this->stepInfo('Traceroute: %s', print_r($trace, true)); } diff --git a/tests/OpenCloud/Smoke/Unit/Compute.php b/tests/OpenCloud/Smoke/Unit/Compute.php index d49837b41..d7c96fe97 100644 --- a/tests/OpenCloud/Smoke/Unit/Compute.php +++ b/tests/OpenCloud/Smoke/Unit/Compute.php @@ -24,8 +24,8 @@ /** * Description of Compute - * - * @link + * + * @link */ class Compute extends AbstractUnit implements UnitInterface { @@ -35,7 +35,7 @@ class Compute extends AbstractUnit implements UnitInterface const SERVER_NAME = 'FooServer'; const SNAPSHOT_NAME = 'FooSnapshot'; - const FLAVOR = 'performance1-2'; + const FLAVOR = 'general1-2'; const IMAGE = "046832f9-4549-4b38-a903-11acecac8cb9"; public function setupService() @@ -66,7 +66,7 @@ public function main() $network = $this->getService()->network(); try { $network->create(array( - 'label' => $this->prepend(self::NETWORK_NAME), + 'label' => $this->prepend(self::NETWORK_NAME), 'cidr' => '192.168.0.0/24' )); } catch (ClientErrorResponseException $e) { @@ -199,7 +199,6 @@ public function teardown() // Delete servers foreach ($servers as $server) { - $attachments = $server->volumeAttachmentList(); foreach ($attachments as $volumeAttachment) { diff --git a/tests/OpenCloud/Smoke/Unit/DNS.php b/tests/OpenCloud/Smoke/Unit/DNS.php index 0cb22b219..bfc4b95ec 100644 --- a/tests/OpenCloud/Smoke/Unit/DNS.php +++ b/tests/OpenCloud/Smoke/Unit/DNS.php @@ -28,9 +28,10 @@ public function setupService() public function getWaiterCallback() { - return function($object) { + return function ($object) { if (!empty($object->error)) { - var_dump($object->error); die; + var_dump($object->error); + die; } else { $this->stepInfoDotter("Waiting..."); } @@ -61,8 +62,8 @@ public function main() if ($asyncResponse->Status() == 'ERROR') { $this->stepInfo( 'Error: [%d] %s - %s', - $asyncResponse->error->code, - $asyncResponse->error->message, + $asyncResponse->error->code, + $asyncResponse->error->message, $asyncResponse->error->details ); } @@ -75,8 +76,8 @@ public function main() $record = $domain->record(); $asyncResponse = $record->create(array( - 'type' => 'CNAME', - 'ttl' => 600, + 'type' => 'CNAME', + 'ttl' => 600, 'name' => 'www.'. $domainName, 'data' => 'developer.rackspace.com' )); @@ -84,8 +85,8 @@ public function main() if ($asyncResponse->status() == 'ERROR') { $this->stepInfo( - 'Error: [%d] $s - %s', - $asyncResponse->error->code, + 'Error: [%d] $s - %s', + $asyncResponse->error->code, $asyncResponse->error->message, $asyncResponse->error->details ); @@ -103,7 +104,6 @@ public function main() $domains->setOption('limit.total', Enum::DISPLAY_ITER_LIMIT); foreach ($domains as $domain) { - $this->stepInfo('%s [%s]', $domain->name(), $domain->emailAddress); $step = $this->stepInfo('Domain Records:'); @@ -111,9 +111,9 @@ public function main() foreach ($records as $record) { $step->stepInfo( '- %s %d %s %s', - $record->type, - $record->ttl, - $record->name(), + $record->type, + $record->ttl, + $record->name(), $record->data ); } diff --git a/tests/OpenCloud/Smoke/Unit/Database.php b/tests/OpenCloud/Smoke/Unit/Database.php index 3900660b6..c5f76899e 100644 --- a/tests/OpenCloud/Smoke/Unit/Database.php +++ b/tests/OpenCloud/Smoke/Unit/Database.php @@ -94,7 +94,6 @@ public function teardown() $instances = $this->getService()->instanceList(); foreach ($instances as $instance) { - // Users $users = $instance->userList(); foreach ($users as $user) { @@ -113,11 +112,11 @@ public function teardown() } } - // Instance + // Instance if ($this->shouldDelete($instance->name)) { $this->stepInfo('Deleting instance: %s', $instance->id); $instance->delete(); - } + } } } } diff --git a/tests/OpenCloud/Smoke/Unit/Identity.php b/tests/OpenCloud/Smoke/Unit/Identity.php index 4f8a44175..97bd0f571 100644 --- a/tests/OpenCloud/Smoke/Unit/Identity.php +++ b/tests/OpenCloud/Smoke/Unit/Identity.php @@ -128,4 +128,4 @@ public function executeTenants() public function teardown() { } -} +} diff --git a/tests/OpenCloud/Smoke/Unit/LoadBalancer.php b/tests/OpenCloud/Smoke/Unit/LoadBalancer.php index 9d408037f..e7a451c05 100644 --- a/tests/OpenCloud/Smoke/Unit/LoadBalancer.php +++ b/tests/OpenCloud/Smoke/Unit/LoadBalancer.php @@ -68,8 +68,8 @@ public function main() $protocolList = $this->getService()->protocolList(); foreach ($protocolList as $protocol) { $this->stepInfo( - '%s %4d', - substr($protocol->name() . '..................', 0, 20), + '%s %4d', + substr($protocol->name() . '..................', 0, 20), $protocol->port ); } @@ -87,15 +87,13 @@ public function main() $loadBalancers->setOption('limit.total', Enum::DISPLAY_ITER_LIMIT); if ($loadBalancers->count()) { - $i = 1; $total = $loadBalancers->count() > 10 ? 10 : $loadBalancers->count(); foreach ($loadBalancers as $loadBalancer) { - $step = $this->stepInfo('Load balancer (%d/%d)', $i, $total); $step->stepInfo( - 'ID [%s], Name [%s], Status [%s]', + 'ID [%s], Name [%s], Status [%s]', $loadBalancer->id, $loadBalancer->name(), $loadBalancer->status() @@ -109,10 +107,10 @@ public function main() } else { foreach ($nodeList as $node) { $step1->stepInfo('Node: [%s] %s:%d %s/%s', - $node->id(), - $node->address, + $node->id(), + $node->address, $node->port, - $node->condition, + $node->condition, $node->status ); } @@ -126,7 +124,7 @@ public function main() } else { foreach ($nodeEvents as $event) { $step2->stepInfo('Event: %s (%s)', - $event->detailedMessage, + $event->detailedMessage, $event->author ); } @@ -145,8 +143,8 @@ public function main() $metadataList = $loadBalancer->metadataList(); foreach ($metadataList as $metadataItem) { $step3->stepInfo('[Metadata #%s] %s=%s', - $metadataItem->Id(), - $metadataItem->key, + $metadataItem->Id(), + $metadataItem->key, $metadataItem->value ); } @@ -164,7 +162,7 @@ public function main() $this->step('Billable Load Balancers from %s to %s', $start, $end); $list = $this->getService()->billableLoadBalancerList(array( - 'startTime' => $start, + 'startTime' => $start, 'endTime' => $end )); diff --git a/tests/OpenCloud/Smoke/Unit/Networking.php b/tests/OpenCloud/Smoke/Unit/Networking.php new file mode 100644 index 000000000..02ed838bb --- /dev/null +++ b/tests/OpenCloud/Smoke/Unit/Networking.php @@ -0,0 +1,362 @@ +getConnection()->networkingService('cloudNetworks', Utils::getRegion()); + } + + public function main() + { + $this->testNetworkOperations(); + $this->testSubnetOperations(); + $this->testPortOperations(); + $this->testSecurityGroupOperations(); + $this->testSecurityGroupRuleOperations(); + } + + protected function testNetworkOperations() + { + $this->step('Create network'); + $createdNetwork = $this->getService()->createNetwork(array( + 'name' => 'test_network' + )); + $this->stepInfo('Network ID: ' . $createdNetwork->getId()); + $this->stepInfo('Network Name: ' . $createdNetwork->getName()); + $this->cleanupNetworkIds[] = $createdNetwork->getId(); + + // The next operation is commented out (for now) because the Rackspace + // Networking API does not support bulk operations (for now). When that + // changes in the future, please uncomment this operation. + // $this->step('Create networks'); + // $createdNetworks = $this->getService()->createNetworks(array( + // array( 'name' => 'test_network_1' ), + // array( 'name' => 'test_network_2' ), + // array( 'name' => 'test_network_3' ), + // )); + // $this->stepInfo('%-40s | %s', 'Network ID', 'Network name'); + // $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + // foreach ($createdNetworks as $network) { + // $this->stepInfo('%-40s | %s', $network->getId(), $network->getName()); + // $this->cleanupNetworkIds[] = $network->getId(); + // } + + $this->step('List networks'); + $networks = $this->getService()->listNetworks(); + $this->stepInfo('%-40s | %s', 'Network ID', 'Network name'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($networks as $network) { + $this->stepInfo('%-40s | %s', $network->getId(), $network->getName()); + } + + $this->step('Get network'); + $network = $this->getService()->getNetwork($createdNetwork->getId()); + $this->stepInfo('Network ID: ' . $network->getId()); + $this->stepInfo('Network Name: ' . $network->getName()); + + $this->step('Update network'); + $network->update(array( + 'name' => 'updated_test_network' + )); + } + + protected function testSubnetOperations() + { + $network1 = $this->getService()->createNetwork(array( + 'name' => 'test_network_for_test_subnet' + )); + $this->cleanupNetworkIds[] = $network1->getId(); + + $this->step('Create subnet'); + $subnet = $this->getService()->createSubnet(array( + 'cidr' => '192.168.199.0/24', + 'networkId' => $network1->getId(), + 'ipVersion' => 4, + 'name' => 'test_subnet' + )); + $this->stepInfo('Subnet ID: ' . $subnet->getId()); + $this->stepInfo('Subnet Name: ' . $subnet->getName()); + $this->cleanupSubnetIds[] = $subnet->getId(); + + $network2 = $this->getService()->createNetwork(array( + 'name' => 'test_network_for_test_subnet_w_gateway' + )); + $this->cleanupNetworkIds[] = $network2->getId(); + + $this->step('Create subnet with gateway IP'); + $subnet = $this->getService()->createSubnet(array( + 'cidr' => '192.168.62.0/25', + 'networkId' => $network2->getId(), + 'ipVersion' => 4, + 'name' => 'test_subnet_with_gateway_ip', + 'gatewayIp' => '192.168.62.128' + )); + $this->stepInfo('Subnet ID: ' . $subnet->getId()); + $this->stepInfo('Subnet Name: ' . $subnet->getName()); + $this->cleanupSubnetIds[] = $subnet->getId(); + + $network3 = $this->getService()->createNetwork(array( + 'name' => 'test_network_for_test_subnet_w_host_rt' + )); + $this->cleanupNetworkIds[] = $network3->getId(); + + $this->step('Create subnet with host routes'); + $subnet = $this->getService()->createSubnet(array( + 'cidr' => '192.168.62.0/25', + 'networkId' => $network3->getId(), + 'ipVersion' => 4, + 'name' => 'test_subnet_with_host_routes', + 'hostRoutes' => array( + array( + 'destination' => '1.1.1.0/24', + 'nexthop' => '192.168.19.20' + ) + ) + )); + $this->stepInfo('Subnet ID: ' . $subnet->getId()); + $this->stepInfo('Subnet Name: ' . $subnet->getName()); + $this->cleanupSubnetIds[] = $subnet->getId(); + + // The next operation is commented out (for now) because the Rackspace + // Networking API does not support bulk operations (for now). When that + // changes in the future, please uncomment this operation. + // $this->step('Create subnets'); + // $subnets = $this->getService()->createSubnets(array( + // array( + // 'cidr' => '192.168.199.0/24', + // 'networkId' => $network->getId(), + // 'ipVersion' => 4, + // 'name' => 'test_subnet_1' + // ) + // )); + // $this->stepInfo('%-40s | %s', 'Subnet ID', 'Subnet name'); + // $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + // foreach ($subnets as $subnet) { + // $this->stepInfo('%-40s | %s', $subnet->getId(), $subnet->getName()); + // $this->cleanupSubnetIds[] = $subnet->getId(); + // } + + $this->step('List subnets'); + $subnets = $this->getService()->listSubnets(); + $this->stepInfo('%-40s | %s', 'Subnet ID', 'Subnet name'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($subnets as $subnet) { + $this->stepInfo('%-40s | %s', $subnet->getId(), $subnet->getName()); + } + + $this->step('Get subnet'); + $subnet = $this->getService()->getSubnet($subnet->getId()); + $this->stepInfo('Subnet ID: ' . $subnet->getId()); + $this->stepInfo('Subnet Name: ' . $subnet->getName()); + + $this->step('Update subnet'); + $subnet->update(array( + 'name' => 'updated_test_subnet', + 'hostRoutes' => array( + array( + 'destination' => '1.1.1.0/24', + 'nexthop' => '192.168.17.19' + ) + ), + 'gatewayIp' => '192.168.62.155' + )); + } + + protected function testPortOperations() + { + $network1 = $this->getService()->createNetwork(array( + 'name' => 'test_network_for_test_port' + )); + $this->cleanupNetworkIds[] = $network1->getId(); + + $subnet1 = $this->getService()->createSubnet(array( + 'cidr' => '192.168.62.0/25', + 'networkId' => $network1->getId(), + 'ipVersion' => 4, + 'name' => 'test_subnet_for_test_port' + )); + $this->cleanupSubnetIds[] = $subnet1->getId(); + + $this->step('Create port'); + $port = $this->getService()->createPort(array( + 'networkId' => $network1->getId(), + 'name' => 'test_port' + )); + $this->stepInfo('Port ID: ' . $port->getId()); + $this->stepInfo('Port Name: ' . $port->getName()); + $this->cleanupPortIds[] = $port->getId(); + + // The next operation is commented out (for now) because the Rackspace + // Networking API does not support bulk operations (for now). When that + // changes in the future, please uncomment this operation. + // $this->step('Create ports'); + // $ports = $this->getService()->createPorts(array( + // )); + // $this->stepInfo('%-40s | %s', 'Port ID', 'Port name'); + // $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + // foreach ($ports as $port) { + // $this->stepInfo('%-40s | %s', $port->getId(), $port->getName()); + // $this->cleanupPortIds[] = $port->getId(); + // } + + $this->step('List ports'); + $ports = $this->getService()->listPorts(); + $this->stepInfo('%-40s | %s', 'Port ID', 'Port name'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($ports as $port) { + $this->stepInfo('%-40s | %s', $port->getId(), $port->getName()); + } + + $this->step('Get port'); + $port = $this->getService()->getPort($port->getId()); + $this->stepInfo('Port ID: ' . $port->getId()); + $this->stepInfo('Port Name: ' . $port->getName()); + + $this->step('Update port'); + $port->update(array( + 'name' => 'updated_test_port' + )); + } + + protected function testSecurityGroupOperations() + { + $this->step('Create security group'); + $securityGroup = $this->getService()->createSecurityGroup(array( + 'name' => 'new-webservers', + 'description' => 'security group for webservers' + )); + $this->stepInfo('Security Group ID: ' . $securityGroup->getId()); + $this->stepInfo('Security Group Name: ' . $securityGroup->getName()); + $this->cleanupSecurityGroupIds[] = $securityGroup->getId(); + + $this->step('List security groups'); + $securityGroups = $this->getService()->listSecurityGroups(); + $this->stepInfo('%-40s | %s', 'Security Group ID', 'Security Group name'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($securityGroups as $securityGroup) { + $this->stepInfo('%-40s | %s', $securityGroup->getId(), $securityGroup->getName()); + } + + $this->step('Get security group'); + $securityGroup = $this->getService()->getSecurityGroup($securityGroup->getId()); + $this->stepInfo('Security Group ID: ' . $securityGroup->getId()); + $this->stepInfo('Security Group Name: ' . $securityGroup->getName()); + + $network1 = $this->getService()->createNetwork(array( + 'name' => 'test_network_for_test_port_sg' + )); + $this->cleanupNetworkIds[] = $network1->getId(); + + $subnet1 = $this->getService()->createSubnet(array( + 'cidr' => '192.165.66.0/25', + 'networkId' => $network1->getId(), + 'ipVersion' => 4, + 'name' => 'test_subnet_for_test_port_sg' + )); + $this->cleanupSubnetIds[] = $subnet1->getId(); + + $port1 = $this->getService()->createPort(array( + 'networkId' => $network1->getId(), + 'name' => 'test_port_for_test_port_sg' + )); + $this->cleanupPortIds[] = $port1->getId(); + + $this->step('Apply security group to port'); + $port1->update(array( + 'securityGroups' => array($securityGroup->getId()) + )); + } + + protected function testSecurityGroupRuleOperations() + { + $securityGroup1 = $this->getService()->createSecurityGroup(array( + 'name' => 'test_security_group_for_test_security_group_rule' + )); + $this->cleanupSecurityGroupIds[] = $securityGroup1->getId(); + + $this->step('Create security group rule'); + $securityGroupRule = $this->getService()->createSecurityGroupRule(array( + 'securityGroupId' => $securityGroup1->getId(), + 'direction' => 'ingress', + 'ethertype' => 'IPv4', + 'portRangeMin' => 80, + 'portRangeMax' => 80, + 'protocol' => 'tcp' + )); + $this->stepInfo('Security Group Rule ID: ' . $securityGroupRule->getId()); + $this->stepInfo('Security Group Rule Direction: ' . $securityGroupRule->getDirection()); + $this->cleanupSecurityGroupRuleIds[] = $securityGroupRule->getId(); + + $this->step('List security group rules'); + $securityGroupRules = $this->getService()->listSecurityGroupRules(); + $this->stepInfo('%-40s | %s', 'Security Group Rule ID', 'Security Group Rule direction'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($securityGroupRules as $securityGroupRule) { + $this->stepInfo('%-40s | %s', $securityGroupRule->getId(), $securityGroupRule->getDirection()); + } + + $this->step('Get security group rule'); + $securityGroupRule = $this->getService()->getSecurityGroupRule($securityGroupRule->getId()); + $this->stepInfo('Security Group Rule ID: ' . $securityGroupRule->getId()); + $this->stepInfo('Security Group Rule Direction: ' . $securityGroupRule->getDirection()); + } + + public function teardown() + { + foreach ($this->cleanupSecurityGroupRuleIds as $securityGroupRuleId) { + $securityGroupRule = $this->getService()->getSecurityGroupRule($securityGroupRuleId); + $securityGroupRule->delete(); + } + + foreach ($this->cleanupSecurityGroupIds as $securityGroupId) { + $securityGroup = $this->getService()->getSecurityGroup($securityGroupId); + $securityGroup->delete(); + } + + foreach ($this->cleanupPortIds as $portId) { + $port = $this->getService()->getPort($portId); + $port->delete(); + } + + foreach ($this->cleanupSubnetIds as $subnetId) { + $subnet = $this->getService()->getSubnet($subnetId); + $subnet->delete(); + } + + foreach ($this->cleanupNetworkIds as $networkId) { + $network = $this->getService()->getNetwork($networkId); + $network->delete(); + } + } +} diff --git a/tests/OpenCloud/Smoke/Unit/ObjectStore.php b/tests/OpenCloud/Smoke/Unit/ObjectStore.php index 213981412..a24b1a94f 100644 --- a/tests/OpenCloud/Smoke/Unit/ObjectStore.php +++ b/tests/OpenCloud/Smoke/Unit/ObjectStore.php @@ -26,7 +26,6 @@ class ObjectStore extends AbstractUnit implements UnitInterface { - const OBJECT_NAME = 'TestObject'; const UPLOAD_COUNT = 50; const MASSIVE_FILE_PATH = '/tmp/massive.txt'; @@ -40,7 +39,7 @@ private function createFiles($dir) { $content = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 1000); for ($i = 1; $i <= 50; $i++) { - $fh = fopen($dir . self::OBJECT_NAME . "_$i", 'c+'); + $fh = fopen($dir . '/' . self::OBJECT_NAME . "_$i", 'c+'); fwrite($fh, $content); fclose($fh); } @@ -60,7 +59,7 @@ public function main() { // Container $this->step('Create Container'); - $container = $this->getService()->createContainer($this->prepend(rand(1,99999))); + $container = $this->getService()->createContainer($this->prepend(rand(1, 99999))); // Upload normal file $this->step('Upload 1 file'); @@ -70,7 +69,7 @@ public function main() // Upload 50 objects $this->step('Upload ' . self::UPLOAD_COUNT . ' files'); - $dir = __DIR__ . '/../Resource/ObjectStore/'; + $dir = $this->getResourceDir(); if (!file_exists($dir)) { mkdir($dir); } @@ -81,7 +80,7 @@ public function main() $files = array(); for ($i = 1; $i <= 50; $i++) { $file = self::OBJECT_NAME . "_$i"; - $files[] = array('name' => $file . '.txt', 'path' => __DIR__ . '/../Resource/ObjectStore/' . $file); + $files[] = array('name' => $file . '.txt', 'path' => $dir . '/' . $file); } $container->uploadObjects($files); @@ -132,7 +131,6 @@ public function main() $containers = $this->getService()->listContainers(); foreach ($containers as $container) { - $step = $this->stepInfo('Container: %s', $container->getName()); // List this container's objects @@ -140,7 +138,7 @@ public function main() foreach ($containers as $container) { $step->stepInfo('Object: %s', $object->getName()); } - } + } } public function teardown() @@ -156,7 +154,8 @@ public function teardown() $this->stepInfo('Disable Container CDN'); try { $container->disableCDN(); - } catch (CdnNotAvailableError $e) {} + } catch (CdnNotAvailableError $e) { + } $step = $this->stepInfo('Delete objects'); $objects = $container->objectList(); diff --git a/tests/OpenCloud/Smoke/Unit/Orchestration.php b/tests/OpenCloud/Smoke/Unit/Orchestration.php index 9498c12a4..0b9baa340 100644 --- a/tests/OpenCloud/Smoke/Unit/Orchestration.php +++ b/tests/OpenCloud/Smoke/Unit/Orchestration.php @@ -17,34 +17,206 @@ namespace OpenCloud\Smoke\Unit; +use OpenCloud\Smoke\Utils; + /** * Description of Orchestration - * - * @link + * + * @link */ class Orchestration extends AbstractUnit implements UnitInterface { - /** - * {@inheritDoc} - */ + protected $cleanupStackIds = array(); + public function setupService() { - + return $this->getConnection()->orchestrationService('cloudOrchestration', Utils::getRegion()); } - - /** - * {@inheritDoc} - */ + public function main() { + $this->step('Validate template from a file'); + $this->getService()->validateTemplate(array( + 'template' => file_get_contents($this->getResourceDir() . '/lamp.yaml') + )); + + $this->step('Validate template from a URL'); + $this->getService()->validateTemplate(array( + 'templateUrl' => 'https://raw.githubusercontent.com/rackspace-orchestration-templates/lamp/master/lamp.yaml' + )); + + $this->step('Preview stack from template file'); + $stack = $this->getService()->previewStack(array( + 'name' => 'simple-lamp-setup', + 'template' => file_get_contents($this->getResourceDir() . '/lamp.yaml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ) + )); + + $this->step('Preview stack from template URL'); + $stack = $this->getService()->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)' + ) + )); + + $this->step('Create stack from template file'); + $stack = $this->getService()->createStack(array( + 'name' => 'simple-lamp-setup-from-template-file', + 'template' => file_get_contents($this->getResourceDir() . '/lamp.yaml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ) + )); + $this->stepInfo('Stack ID: ' . $stack->getId()); + $this->stepInfo('Stack Name: ' . $stack->getName()); + $this->cleanupStackIds[] = $stack->getId(); + + $this->step('Create stack from template URL'); + $stack = $this->getService()->createStack(array( + 'name' => 'simple-lamp-setup-from-template-url', + '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)' + ) + )); + $this->stepInfo('Stack ID: ' . $stack->getId()); + $this->stepInfo('Stack Name: ' . $stack->getName()); + + $this->step('List stacks'); + $stacks = $this->getService()->listStacks(); + $this->stepInfo('%-40s | %s', 'Stack ID', 'Stack name'); + $this->stepInfo('%-40s | %s', str_repeat('-', 40), str_repeat('-', 40)); + foreach ($stacks as $stack) { + $this->stepInfo('%-40s | %s', $stack->getId(), $stack->getName()); + } + + $this->step('Get stack'); + $stack = $this->getService()->getStack('simple-lamp-setup-from-template-file'); + $this->stepInfo('Stack ID: ' . $stack->getId()); + $this->stepInfo('Stack name: ' . $stack->getName()); + + $this->step('Get stack template'); + $stackTemplateJsonStr = $stack->getStackTemplate(); + $this->stepInfo('Stack template JSON: %s ', $stackTemplateJsonStr); + + $this->step('List stack resources'); + $resources = $stack->listResources(); + $this->stepInfo('Resource name'); + $this->stepInfo(str_repeat('-', 25)); + foreach ($resources as $resource) { + $this->stepInfo($resource->getName()); + } + $this->step('Get stack resource'); + $resource = $stack->getResource('linux_server'); + $this->stepInfo('Resource name: ' . $resource->getName()); + + $this->step('Get stack resource metadata'); + $metadata = $resource->getMetadata(); + $this->stepInfo('%-25s | %s', 'Metadata key', 'Metadata value'); + foreach ($metadata as $key => $value) { + $this->stepInfo('%-25s | %s', $key, $value); + } + + $this->step('List stack events'); + $events = $stack->listEvents(); + $this->stepInfo('%-40s | %-20s | %-25s | %s', 'Event ID', 'Event time', 'Resource name', 'Resource status'); + $this->stepInfo('%-40s | %-20s | %-25s | %s', str_repeat('-', 40), str_repeat('-', 20), str_repeat('-', 25), str_repeat('-', 20)); + foreach ($events as $event) { + $this->stepInfo('%-40s | %-20s | %-25s | %s', + $event->getId(), $event->getTime(), $event->getResourceName(), $event->getResourceStatus()); + } + + $this->step('List stack resource events'); + $events = $resource->listEvents(); + $this->stepInfo('%-40s | %-20s | %-25s | %s', 'Event ID', 'Event time', 'Resource name', 'Resource status'); + $this->stepInfo('%-40s | %-20s | %-25s | %s', str_repeat('-', 40), str_repeat('-', 20), str_repeat('-', 25), str_repeat('-', 20)); + foreach ($events as $event) { + $this->stepInfo('%-40s | %-20s | %-25s | %s', + $event->getId(), $event->getTime(), $event->getResourceName(), $event->getResourceStatus()); + $lastEventId = $event->getId(); + } + + $this->step('Get stack resource event'); + $event = $resource->getEvent($lastEventId); + $this->stepInfo('Event ID: ' . $event->getId()); + $this->stepInfo('Event time: ' . $event->getTime()); + $this->stepInfo('Resource name: ' . $event->getResourceName()); + $this->stepInfo('Resource status: ' . $event->getResourceStatus()); + + $this->step('List resource types'); + $resourceTypes = $this->getService()->listResourceTypes(); + $this->stepInfo('Resource type'); + $this->stepInfo(str_repeat('-', 40)); + foreach ($resourceTypes as $resourceType) { + $this->stepInfo($resourceType->getResourceType()); + $lastResourceType = $resourceType->getResourceType(); + } + + $this->step('Get resource type'); + $resourceType = $this->getService()->getResourceType($lastResourceType); + $this->stepInfo('Resource type: ' . $resourceType->getResourceType()); + + $this->step('Get resource type template'); + $this->stepInfo('Resource type template: ' . $resourceType->getTemplate()); + + $this->step('Get build info'); + $buildInfo = $this->getService()->getBuildInfo(); + $this->stepInfo('API revision: ' . $buildInfo->getApi()->revision); + $this->stepInfo('Engine revision: ' . $buildInfo->getEngine()->revision); + + $this->step('Update stack from template file'); + $stack->waitFor('CREATE_COMPLETE', null, function ($s) { + $this->stepInfo('Stack is still being created. Waiting...'); + }); + $stack->update(array( + 'template' => file_get_contents($this->getResourceDir() . '/lamp-updated.yaml'), + 'parameters' => array( + 'server_hostname' => 'web01', + 'image' => 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)' + ), + 'timeoutMins' => 5 + )); + $this->stepInfo('Done! Stack update requested.'); + + $this->step('Abandon stack'); + $stack = $this->getService()->getStack('simple-lamp-setup-from-template-url'); + $stack->waitFor('CREATE_COMPLETE', null, function ($s) { + $this->stepInfo('Stack is still being created. Waiting...'); + }); + $abandonedStackData = $stack->abandon(); + $this->stepInfo('Abandon stack data: %s ', $abandonedStackData); + + $this->step('Adopt stack'); + sleep(10); // For abandoned stack to get deleted. + $stack = $this->getService()->adoptStack(array( + 'name' => 'simple-lamp-setup-from-template-url', + '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)' + ), + 'adoptStackData' => $abandonedStackData, + 'timeoutMins' => 5 + )); + $this->stepInfo('Stack ID: ' . $stack->getId()); + $this->stepInfo('Stack name: ' . $stack->getName()); + $this->cleanupStackIds[] = $stack->getId(); } - - /** - * {@inheritDoc} - */ + public function teardown() { - + foreach ($this->cleanupStackIds as $stackId) { + $stack = $this->getService()->getStack($stackId); + $stack->delete(); + } } } diff --git a/tests/OpenCloud/Smoke/Unit/Queues.php b/tests/OpenCloud/Smoke/Unit/Queues.php index 5079ed2cc..326e726ae 100644 --- a/tests/OpenCloud/Smoke/Unit/Queues.php +++ b/tests/OpenCloud/Smoke/Unit/Queues.php @@ -17,6 +17,8 @@ namespace OpenCloud\Smoke\Unit; +use OpenCloud\Queues\Resource\Queue; + class Queues extends AbstractUnit implements UnitInterface { const QUEUE_NAME = 'test_queue'; @@ -71,6 +73,7 @@ public function doMessageBlock() $this->step('Messages'); // post + $numMessagesCreated = 0; $this->stepInfo('Create messages for queue %s', $this->queue->getName()); $this->queue->createMessage(array( 'body' => (object) array( @@ -78,26 +81,37 @@ public function doMessageBlock() ), 'ttl' => 300 )); + ++$numMessagesCreated; + + for ($creationBatch = 0; $creationBatch < 3; ++$creationBatch) { + $messages = array(); + for ($messageIndex = 0; $messageIndex < Queue::MAX_POST_MESSAGES; ++$messageIndex) { + $messages[] = array( + 'body' => (object) array('message_number' => ($creationBatch * Queue::MAX_POST_MESSAGES) + $messageIndex + 1), + 'ttl' => mt_rand(300, 600) + ); + ++$numMessagesCreated; + } + $this->queue->createMessages($messages); + } - $this->queue->createMessages(array( - array( - 'body' => (object) array('foo' => 'bar'), - 'ttl' => 700 - ), - array( - 'body' => (object) array('baz' => 'lol'), - 'ttl' => 600 - ) - )); - - // list + // list ( 'echo' => true is needed to list client's own messages) $step = $this->stepInfo('List messages for queue %s', $this->queue->getName()); - $messages = $this->queue->listMessages(); + $messages = $this->queue->listMessages(array( + 'echo' => true + )); $ids = array(); + $numMessagesListed = 0; + $step->stepInfo("%-30s | %-40s", "Message ID", "Message body"); + $step->stepInfo("%-30s | %-40s", str_repeat("-", 30), str_repeat("-", 40)); foreach ($messages as $message) { - $step->stepInfo($message->getId()); + $step->stepInfo("%-30s | %-40s", $message->getId(), json_encode($message->getBody())); $ids[] = $message->getId(); + ++$numMessagesListed; } + $this->stepInfo("Number of messages to be listed: " . $numMessagesCreated); + $this->stepInfo("Number of messages actually listed: " . $numMessagesListed); + $this->assertEquals($numMessagesCreated, $numMessagesListed); array_pop($ids); } diff --git a/tests/OpenCloud/Smoke/Unit/UnitInterface.php b/tests/OpenCloud/Smoke/Unit/UnitInterface.php index 3e321c67c..214d6c883 100644 --- a/tests/OpenCloud/Smoke/Unit/UnitInterface.php +++ b/tests/OpenCloud/Smoke/Unit/UnitInterface.php @@ -22,7 +22,6 @@ */ interface UnitInterface { - /** * Method for executing the main algorithm of the test. */ @@ -34,9 +33,8 @@ public function main(); public function setupService(); /** - * Allows for the deletion of any persistent resources created during + * Allows for the deletion of any persistent resources created during * execution. */ public function teardown(); - } diff --git a/tests/OpenCloud/Smoke/Unit/Volume.php b/tests/OpenCloud/Smoke/Unit/Volume.php index 020dea9cc..1085f14e9 100644 --- a/tests/OpenCloud/Smoke/Unit/Volume.php +++ b/tests/OpenCloud/Smoke/Unit/Volume.php @@ -21,11 +21,11 @@ /** * Description of Volume - * - * @link + * + * @link */ class Volume extends AbstractUnit implements UnitInterface -{ +{ /** * {@inheritDoc} */ diff --git a/tests/OpenCloud/Smoke/Utils.php b/tests/OpenCloud/Smoke/Utils.php index 2e3394bba..a643d0d86 100644 --- a/tests/OpenCloud/Smoke/Utils.php +++ b/tests/OpenCloud/Smoke/Utils.php @@ -28,15 +28,14 @@ /** * Description of Utils - * - * @link + * + * @link */ class Utils { - /** * Basic logging function. - * + * * @param string $string */ public static function log($string) @@ -53,7 +52,7 @@ public static function convertArgsToString(array $args) } /** - * A logging function similar to sprintf(). Accepts a format string as a + * A logging function similar to sprintf(). Accepts a format string as a * first argument, and an array as a second argument to stock the format. */ public static function logf() @@ -120,5 +119,4 @@ public static function getIdentityEndpoint() return \OpenCloud\Rackspace::US_IDENTITY_ENDPOINT; } } - } diff --git a/tests/OpenCloud/Tests/Autoscale/Resource/GroupTest.php b/tests/OpenCloud/Tests/Autoscale/Resource/GroupTest.php index ddc9e4386..76f898b9c 100644 --- a/tests/OpenCloud/Tests/Autoscale/Resource/GroupTest.php +++ b/tests/OpenCloud/Tests/Autoscale/Resource/GroupTest.php @@ -129,4 +129,4 @@ public function testCreatingScalingPolicies() $this->isResponse($response); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Autoscale/Resource/ScalingPolicyTest.php b/tests/OpenCloud/Tests/Autoscale/Resource/ScalingPolicyTest.php index d9ca24258..d1d16d1e2 100644 --- a/tests/OpenCloud/Tests/Autoscale/Resource/ScalingPolicyTest.php +++ b/tests/OpenCloud/Tests/Autoscale/Resource/ScalingPolicyTest.php @@ -22,7 +22,6 @@ class ScalingPolicyTest extends AutoscaleTestCase { - public function setupObjects() { parent::setupObjects(); diff --git a/tests/OpenCloud/Tests/CDN/CDNTestCase.php b/tests/OpenCloud/Tests/CDN/CDNTestCase.php new file mode 100644 index 000000000..4f07d58f4 --- /dev/null +++ b/tests/OpenCloud/Tests/CDN/CDNTestCase.php @@ -0,0 +1,49 @@ +service = $this->getClient()->cdnService(); + + $this->addMockSubscriber($this->makeResponse('{"name":"mywebsite.com","domains":[{"domain":"blog.mywebsite.com"}],"origins":[{"origin":"mywebsite.com","port":80,"ssl":false},{"origin":"77.66.55.44","port":80,"ssl":false,"rules":[{"name":"videos","request_url":"^/videos/*.m3u"}]}],"caching":[{"name":"default","ttl":3600},{"name":"home","ttl":17200,"rules":[{"name":"index","request_url":"/index.htm"}]},{"name":"images","ttl":12800,"rules":[{"name":"images","request_url":"*.png"}]}],"restrictions":[{"name":"website only","rules":[{"name":"mywebsite.com","http_host":"www.mywebsite.com"}]}],"flavor_id":"cdn","status":"deployed","links":[{"href":"https://global.cdn.api.rackspacecloud.com/v1.0/services/mywebsite.com","rel":"self"},{"href":"mywebsite.com","rel":"access_url"}]}')); + $this->serviceResource = $this->service->getService('mywebsite.com'); + } + + protected function assertIsService($object) + { + $this->assertInstanceOf('OpenCloud\CDN\Service', $object); + } + + protected function assertIsServiceResource($object) + { + $this->assertInstanceOf('OpenCloud\CDN\Resource\Service', $object); + } + + protected function assertIsFlavorResource($object) + { + $this->assertInstanceOf('OpenCloud\CDN\Resource\Flavor', $object); + } +} diff --git a/tests/OpenCloud/Tests/CDN/Resource/ServiceTest.php b/tests/OpenCloud/Tests/CDN/Resource/ServiceTest.php new file mode 100644 index 000000000..37bd61a50 --- /dev/null +++ b/tests/OpenCloud/Tests/CDN/Resource/ServiceTest.php @@ -0,0 +1,40 @@ +addMockSubscriber($this->makeResponse(null, 202)); + + $actualResponse = $this->serviceResource->purgeAssets('/images/foo.png'); + $this->assertEquals(202, $actualResponse->getStatusCode()); + } + + public function testPurgeAllAssets() + { + $this->addMockSubscriber($this->makeResponse(null, 202)); + + $actualResponse = $this->serviceResource->purgeAssets(); + $this->assertEquals(202, $actualResponse->getStatusCode()); + } +} diff --git a/tests/OpenCloud/Tests/CDN/ServiceTest.php b/tests/OpenCloud/Tests/CDN/ServiceTest.php new file mode 100644 index 000000000..b3a2bb7f7 --- /dev/null +++ b/tests/OpenCloud/Tests/CDN/ServiceTest.php @@ -0,0 +1,101 @@ +getClient()->cdnService(); + $this->assertIsService($service); + } + + public function testCreateService() + { + $this->assertIsServiceResource($this->service->createService(array( + 'name' => 'mywebsite' + ))); + } + + public function testListServices() + { + $this->addMockSubscriber($this->makeResponse('{"links":[{"rel":"next","href":"https://global.cdn.api.rackspacecloud.com/v1.0/services?marker=www.myothersite.com&limit=20"}],"services":[{"name":"mywebsite.com","domains":[{"domain":"www.mywebsite.com"}],"origins":[{"origin":"mywebsite.com","port":80,"ssl":false}],"caching":[{"name":"default","ttl":3600},{"name":"home","ttl":17200,"rules":[{"name":"index","request_url":"/index.htm"}]},{"name":"images","ttl":12800,"rules":[{"name":"images","request_url":"*.png"}]}],"restrictions":[{"name":"website only","rules":[{"name":"mywebsite.com","http_host":"www.mywebsite.com"}]}],"flavor_id":"cdn","status":"deployed","links":[{"href":"https://global.cdn.api.rackspacecloud.com/v1.0/services/mywebsite.com","rel":"self"},{"href":"mywebsite.com","rel":"access_url"}]},{"name":"myothersite.com","domains":[{"domain":"www.myothersite.com"}],"origins":[{"origin":"44.33.22.11","port":80,"ssl":false},{"origin":"77.66.55.44","port":80,"ssl":false,"rules":[{"name":"videos","request_url":"^/videos/*.m3u"}]}],"caching":[{"name":"default","ttl":3600}],"restrictions":[{}],"flavor_id":"cdn","status":"deployed","links":[{"href":"https://global.cdn.api.rackspacecloud.com/v1.0/services/myothersite.com","rel":"self"},{"href":"myothersite.com","rel":"access_url"}]}]}')); + + $services = $this->service->listServices(); + $this->isCollection($services); + $this->assertIsServiceResource($services->getElement(0)); + } + + public function testGetService() + { + $this->addMockSubscriber($this->makeResponse('{"name":"mywebsite.com","domains":[{"domain":"blog.mywebsite.com"}],"origins":[{"origin":"mywebsite.com","port":80,"ssl":false},{"origin":"77.66.55.44","port":80,"ssl":false,"rules":[{"name":"videos","request_url":"^/videos/*.m3u"}]}],"caching":[{"name":"default","ttl":3600},{"name":"home","ttl":17200,"rules":[{"name":"index","request_url":"/index.htm"}]},{"name":"images","ttl":12800,"rules":[{"name":"images","request_url":"*.png"}]}],"restrictions":[{"name":"website only","rules":[{"name":"mywebsite.com","http_host":"www.mywebsite.com"}]}],"flavor_id":"cdn","status":"deployed","links":[{"href":"https://global.cdn.api.rackspacecloud.com/v1.0/services/mywebsite.com","rel":"self"},{"href":"mywebsite.com","rel":"access_url"}]}')); + + $service = $this->service->getService('mywebsite.com'); + $this->assertIsServiceResource($service); + $this->assertEquals('mywebsite.com', $service->getName()); + $this->assertEquals('cdn', $service->getFlavorId()); + } + + public function testCreateFlavor() + { + $this->assertIsFlavorResource($this->service->createFlavor(array( + 'id' => 'asia' + ))); + } + + public function testListFlavors() + { + $this->addMockSubscriber($this->makeResponse('{"flavors":[{"id":"cdn","providers":[{"provider":"akamai","links":[{"href":"http://www.akamai.com","rel":"provider_url"}]}],"links":[{"href":"https://global.cdn.api.rackspacecloud.com/v1.0/flavors/cdn","rel":"self"}]} ]}')); + + $flavors = $this->service->listFlavors(); + $this->isCollection($flavors); + $this->assertIsFlavorResource($flavors->getElement(0)); + } + + public function testGetFlavor() + { + $this->addMockSubscriber($this->makeResponse('{"id":"cdn","providers":[{"provider":"akamai","links":[{"href":"http://www.akamai.com","rel":"provider_url"}]}],"links":[{"href":"http://preview.cdn.api.rackspacecloud.com/v1.0/flavors/cdn","rel":"self"}]}')); + + $flavor = $this->service->getFlavor('cdn'); + $this->assertIsFlavorResource($flavor); + $this->assertEquals('cdn', $flavor->getId()); + + $providers = $flavor->getProviders(); + $this->assertEquals('akamai', $providers[0]->provider); + } + + public function testGetHomeDocument() + { + $this->addMockSubscriber($this->makeResponse('{"resources":{"rel/cdn":{"href-template":"services{?marker,limit}","href-vars":{"marker":"param/marker","limit":"param/limit"},"hints":{"allow":["GET"],"formats":{"application/json":{}}}}}}')); + + $homeDocument = $this->service->getHomeDocument(); + $this->assertNotEmpty($homeDocument); + $this->assertEquals("services{?marker,limit}", $homeDocument->resources->{"rel/cdn"}->{"href-template"}); + } + + public function testGetPing() + { + $this->addMockSubscriber($this->makeResponse(null, 204)); + + $ping = $this->service->getPing(); + $this->assertEquals(204, $ping->getStatusCode()); + } +} diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTest.php index c173c6eab..b38de3db8 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTest.php @@ -21,7 +21,6 @@ class AgentTest extends CloudMonitoringTestCase { - const AGENT_ID = '00-agent.example.com'; const CONNECTION_ID = 'cntl4qsIbA'; diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTokenTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTokenTest.php index c6729aa87..c25636773 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTokenTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/AgentTokenTest.php @@ -21,7 +21,6 @@ class AgentTokenTest extends OpenCloudTestCase { - const TOKEN_ID = 'someId'; public function setupObjects() diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/AlarmTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/AlarmTest.php index 44a71f207..a2a6c72dd 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/AlarmTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/AlarmTest.php @@ -21,7 +21,6 @@ class AlarmTest extends CloudMonitoringTestCase { - const ENTITY_ID = 'en5hw56rAh'; const ALARM_ID = 'alAAAA'; diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/ChangelogTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/ChangelogTest.php index 7d40ec752..c07621e22 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/ChangelogTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/ChangelogTest.php @@ -19,7 +19,6 @@ class ChangelogTest extends CloudMonitoringTestCase { - const NT_ID = 'webhook'; public function setupObjects() diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/CheckTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/CheckTest.php index 812c657d9..f2f9ada0b 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/CheckTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/CheckTest.php @@ -22,7 +22,6 @@ class CheckTest extends CloudMonitoringTestCase { - public function setupObjects() { parent::setupObjects(); diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/EntityTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/EntityTest.php index b9c36b70f..b1ea5e34f 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/EntityTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/EntityTest.php @@ -21,7 +21,6 @@ class EntityTest extends CloudMonitoringTestCase { - public function testResourceClass() { $this->assertInstanceOf('OpenCloud\CloudMonitoring\Resource\Entity', $this->entity); diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/MetricTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/MetricTest.php index bc0b7a4f5..06a75a608 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/MetricTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/MetricTest.php @@ -21,7 +21,6 @@ class MetricTest extends CloudMonitoringTestCase { - const CHECK_ID = 'chAAAA'; const METRIC_NAME = 'mzdfw.available'; diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationHistoryTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationHistoryTest.php index cdff81645..f5bdef5d4 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationHistoryTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationHistoryTest.php @@ -21,7 +21,6 @@ class NotificationHistoryTest extends CloudMonitoringTestCase { - const ENTITY_ID = 'enAAAAA'; const ALARM_ID = 'alAAAA'; const CHECK_ID = 'chAAAA'; diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationPlanTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationPlanTest.php index 0619e6372..c3f39b5d3 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationPlanTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationPlanTest.php @@ -22,7 +22,6 @@ class NotificationPlanTest extends CloudMonitoringTestCase { - const NP_ID = 'npAAAA'; public function setupObjects() diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTest.php index 1d207d986..05701e232 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTest.php @@ -22,7 +22,6 @@ class NotificationTest extends CloudMonitoringTestCase { - const NOTIFICATION_ID = 'ntAAAA'; public function setupObjects() diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTypeTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTypeTest.php index eb5f8bc39..ab1d39c18 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTypeTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/NotificationTypeTest.php @@ -22,7 +22,6 @@ class NotificationTypeTest extends CloudMonitoringTestCase { - const NT_ID = 'webhook'; public function setupObjects() diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/ViewTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/ViewTest.php index 3a5c61624..40eb6abe0 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/ViewTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/ViewTest.php @@ -21,7 +21,6 @@ class ViewTest extends CloudMonitoringTestCase { - public function setupObjects() { $this->service = $this->getClient()->cloudMonitoringService(); diff --git a/tests/OpenCloud/Tests/CloudMonitoring/Resource/ZoneTest.php b/tests/OpenCloud/Tests/CloudMonitoring/Resource/ZoneTest.php index f292a2519..20ef87a53 100644 --- a/tests/OpenCloud/Tests/CloudMonitoring/Resource/ZoneTest.php +++ b/tests/OpenCloud/Tests/CloudMonitoring/Resource/ZoneTest.php @@ -22,7 +22,6 @@ class ZoneTest extends CloudMonitoringTestCase { - public function setupObjects() { $this->service = $this->getClient()->cloudMonitoringService(); diff --git a/tests/OpenCloud/Tests/Common/BaseTest.php b/tests/OpenCloud/Tests/Common/BaseTest.php index dce924db6..625863fb7 100644 --- a/tests/OpenCloud/Tests/Common/BaseTest.php +++ b/tests/OpenCloud/Tests/Common/BaseTest.php @@ -22,7 +22,6 @@ class MyBase extends Base { - public $foo; protected $bar; private $baz; @@ -37,11 +36,15 @@ public function getBar() { return $this->bar; } + + public static function getPatchHeaders() + { + return parent::getPatchHeaders(); + } } class BaseTest extends \OpenCloud\Tests\OpenCloudTestCase { - private $my; public function setupObjects() @@ -102,4 +105,14 @@ public function testSetProperty() $this->my->setBaz('goodbye'); $this->assertEquals('goodbye', $this->my->getBaz()); } + + public function testGetPatchHeaders() + { + $expectedHeaders = array( + 'Content-Type' => 'application/json-patch+json' + ); + + $my = $this->my; + $this->assertEquals($expectedHeaders, $my::getPatchHeaders()); + } } diff --git a/tests/OpenCloud/Tests/Common/Collection/ArrayCollectionTest.php b/tests/OpenCloud/Tests/Common/Collection/ArrayCollectionTest.php index a50722dd1..150bc961b 100644 --- a/tests/OpenCloud/Tests/Common/Collection/ArrayCollectionTest.php +++ b/tests/OpenCloud/Tests/Common/Collection/ArrayCollectionTest.php @@ -21,7 +21,6 @@ class ArrayCollectionTest extends OpenCloudTestCase { - public function test_Basic_Operations() { $iterator = $this->getMockForAbstractClass('OpenCloud\Common\Collection\ArrayCollection'); diff --git a/tests/OpenCloud/Tests/Common/Log/LoggerTest.php b/tests/OpenCloud/Tests/Common/Log/LoggerTest.php index 0cdbdcc40..c18f38c62 100644 --- a/tests/OpenCloud/Tests/Common/Log/LoggerTest.php +++ b/tests/OpenCloud/Tests/Common/Log/LoggerTest.php @@ -22,7 +22,6 @@ class LoggerTest extends PHPUnit_Framework_TestCase { - public function __construct() { $this->logger = new Logger; @@ -86,4 +85,12 @@ public function testOutputFailsWithIncorrectFile() $this->logger->emergency('Can anyone see this?'); } + + public function testDeprecationMessage() + { + $this->assertEquals( + 'The OpenCloud\Tests\Common\Log\LoggerTest::testDeprecationMessage method is deprecated, please use testMethod instead', + $this->logger->deprecated(__METHOD__, 'testMethod') + ); + } } diff --git a/tests/OpenCloud/Tests/Common/MetadataTest.php b/tests/OpenCloud/Tests/Common/MetadataTest.php index 655933c3e..d759ccd8a 100644 --- a/tests/OpenCloud/Tests/Common/MetadataTest.php +++ b/tests/OpenCloud/Tests/Common/MetadataTest.php @@ -31,7 +31,6 @@ class MetadataTest extends \OpenCloud\Tests\OpenCloudTestCase { - private $metadata; public function __construct() diff --git a/tests/OpenCloud/Tests/Common/PersistentObjectTest.php b/tests/OpenCloud/Tests/Common/PersistentObjectTest.php index 25440c057..4f5c886d4 100644 --- a/tests/OpenCloud/Tests/Common/PersistentObjectTest.php +++ b/tests/OpenCloud/Tests/Common/PersistentObjectTest.php @@ -93,7 +93,6 @@ class NamelessObject extends NovaResource class PersistentObjectTest extends \OpenCloud\Tests\OpenCloudTestCase { - private $service; private $instance; @@ -178,14 +177,6 @@ public function testCreate() $this->instance->create(); } - /** - * @expectedException OpenCloud\Common\Exceptions\UpdateError - */ - public function testUpdate() - { - $this->instance->update(); - } - public function testName() { $this->instance->name = ''; diff --git a/tests/OpenCloud/Tests/Common/Resource/PersistentResourceTest.php b/tests/OpenCloud/Tests/Common/Resource/PersistentResourceTest.php new file mode 100644 index 000000000..79d350e3b --- /dev/null +++ b/tests/OpenCloud/Tests/Common/Resource/PersistentResourceTest.php @@ -0,0 +1,193 @@ + 'fooBar' + ); + + protected $updateKeys = array( + 'baz', + 'tags', + 'domains', + 'origins', + 'status' + ); + + public function recursivelyAliasPropertyValue($propertyValue) + { + return parent::recursivelyAliasPropertyValue($propertyValue); + } + + public function getUpdateablePropertiesAsArray() + { + return parent::getUpdateablePropertiesAsArray(); + } + + public function generateJsonPatch($updateParams) + { + return parent::generateJsonPatch($updateParams); + } +} + +class PersistentResourceTest extends OpenCloudTestCase +{ + private $persistentResource; + + public function setupObjects() + { + $service = IdentityService::factory($this->client); + $this->persistentResource = new PublicPersistentResource($service); + } + + public function testRecursivelyAliasPropertyValueWithScalars() + { + $this->assertEquals(11, + $this->persistentResource->recursivelyAliasPropertyValue(11)); + $this->assertEquals("foobar", + $this->persistentResource->recursivelyAliasPropertyValue("foobar")); + $this->assertEquals("fooBar", + $this->persistentResource->recursivelyAliasPropertyValue("fooBar")); + $this->assertEquals(false, + $this->persistentResource->recursivelyAliasPropertyValue(false)); + } + + public function testRecursivelyAliasPropertyValueWithIndexedArrays() + { + $this->assertEquals(array(18), + $this->persistentResource->recursivelyAliasPropertyValue(array(18))); + $this->assertEquals(array("foobar"), + $this->persistentResource->recursivelyAliasPropertyValue(array("foobar"))); + $this->assertEquals(array("fooBar"), + $this->persistentResource->recursivelyAliasPropertyValue(array("fooBar"))); + } + + public function testRecursivelyAliasPropertyValueWithAssociativeArrays() + { + $this->assertEquals(array("foobar" => "baz"), + $this->persistentResource->recursivelyAliasPropertyValue(array("foobar" => "baz"))); + $this->assertEquals(array("foo_bar" => "baz"), + $this->persistentResource->recursivelyAliasPropertyValue(array("fooBar" => "baz"))); + $this->assertEquals(array("qux" => array("foo_bar" => "baz")), + $this->persistentResource->recursivelyAliasPropertyValue(array("qux" => array("fooBar" => "baz")))); + } + + public function testRecursivelyAliasPropertyValueWithObjects() + { + $obj1 = new \stdClass(); + $obj1->foobar = "baz"; + + $obj1Expected = new \stdClass(); + $obj1Expected->foobar = "baz"; + + $this->assertEquals($obj1Expected, + $this->persistentResource->recursivelyAliasPropertyValue($obj1)); + + $obj2 = new \stdClass(); + $obj2->fooBar = "baz"; + + $obj2Expected = new \stdClass(); + $obj2Expected->foo_bar = "baz"; + + $this->assertEquals($obj2Expected, + $this->persistentResource->recursivelyAliasPropertyValue($obj2)); + + $obj3 = new \stdClass(); + $obj3->qux = new \stdClass(); + $obj3->qux->fooBar = "baz"; + + $obj3Expected = new \stdClass(); + $obj3Expected->qux = new \stdClass(); + $obj3Expected->qux->foo_bar = "baz"; + + $this->assertEquals($obj3Expected, + $this->persistentResource->recursivelyAliasPropertyValue($obj3)); + } + + public function testGetUpdateablePropertiesAsArray() + { + $this->persistentResource->id = 17; + $this->persistentResource->tags = array('foo', 'bar'); + $this->persistentResource->domains = array( + (object) array('domain' => 'foo.phpopencloud.com'), + array('domain' => 'bar.phpopencloud.com') + ); + $this->persistentResource->origins = array( + array('origin' => 'origin1.phpopencloud.com') + ); + $this->persistentResource->status = (object) array('message' => 'Creation in progress'); + + $expectedArray = array( + 'tags' => array('foo', 'bar'), + 'domains' => array( + (object) array('domain' => 'foo.phpopencloud.com'), + array('domain' => 'bar.phpopencloud.com') + ), + 'origins' => array( + array('origin' => 'origin1.phpopencloud.com'), + ), + 'status' => (object) array('message' => 'Creation in progress') + ); + + $this->assertEquals($expectedArray, $this->persistentResource->getUpdateablePropertiesAsArray()); + } + + public function testGenerateJsonPatch() + { + $this->persistentResource->id = 17; + $this->persistentResource->tags = array('foo', 'bar'); + $this->persistentResource->domains = array( + array('domain' => 'foo.phpopencloud.com'), + array('domain' => 'bar.phpopencloud.com') + ); + $this->persistentResource->origins = array( + array('origin' => 'origin1.phpopencloud.com') + ); + $this->persistentResource->status = array('message' => 'Creation in progress'); + $this->persistentResource->baz = (object) array( 'fooBar' => 'barbar'); + + $updateParams = array( + 'tags' => array('foo', 'qux', 'baz'), + 'domains' => array( + array('domain' => 'foo.phpopencloud.com') + ), + 'origins' => array( + array('origin' => 'origin1.phpopencloud.com'), + array('origin' => 'origin2.phpopencloud.com') + ), + 'baz' => array('fooBar' => 'barbarbar') + ); + + $expectedJsonPatch = json_encode(array( + array('op' => 'replace', 'path' => '/baz/foo_bar', 'value' => 'barbarbar'), + array('op' => 'add', 'path' => '/tags/2', 'value' => 'baz'), + array('op' => 'replace', 'path' => '/tags/1', 'value' => 'qux'), + array('op' => 'remove', 'path' => '/domains/1'), + array('op' => 'add', 'path' => '/origins/1', 'value' => array("origin" => "origin2.phpopencloud.com")) + )); + + $actualJsonPatch = $this->persistentResource->generateJsonPatch($updateParams); + $this->assertEquals($expectedJsonPatch, $actualJsonPatch); + } +} diff --git a/tests/OpenCloud/Tests/Common/Service/EndpointTest.php b/tests/OpenCloud/Tests/Common/Service/EndpointTest.php new file mode 100644 index 000000000..babcc7209 --- /dev/null +++ b/tests/OpenCloud/Tests/Common/Service/EndpointTest.php @@ -0,0 +1,105 @@ +addMockSubscriber($this->makeResponse('{"versions":[{"status":"CURRENT","id":"v2.0","links":[{"href":"http://hostport/v2.0","rel":"self" }]}]}', 200)); + + $endpoint = new Endpoint(); + + $expectedUrl = "http://hostport/v2.0"; + $actualUrl = $this->invokeMethod( + $endpoint, + 'getVersionedUrl', + array('http://hostport', 'v2.0', $this->client) + ); + + $this->assertInstanceOf('Guzzle\Http\Url', $actualUrl); + $this->assertEquals($expectedUrl, $actualUrl); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\UnsupportedVersionError + */ + public function testGetVersionedUrlWithVersionLessEndpointSupportedVersionNotFound() + { + $this->addMockSubscriber($this->makeResponse('{"versions":[{"status":"CURRENT","id":"v2.0","links":[{"href":"http://hostport/v2.0","rel":"self" }]}]}', 200)); + + $endpoint = new Endpoint(); + + $this->invokeMethod( + $endpoint, + 'getVersionedUrl', + array('http://hostport', 'v2.1', $this->client) + ); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\UnsupportedVersionError + */ + public function testGetVersionedUrlWithVersionLessEndpointInvalidResponse() + { + $this->addMockSubscriber($this->makeResponse('{}')); + + $endpoint = new Endpoint(); + + $this->invokeMethod( + $endpoint, + 'getVersionedUrl', + array('http://hostport', 'v2.1', $this->client) + ); + } + + public function testGetVersionedUrlWithVersionLessEndpointSupportedVersionNotSpecified() + { + $endpoint = new Endpoint(); + + $expectedUrl = "http://hostport"; + $actualUrl = $this->invokeMethod( + $endpoint, + 'getVersionedUrl', + array($expectedUrl, null, $this->client) + ); + + $this->assertEquals($expectedUrl, $actualUrl); + } + + public function testGetVersionedUrlWithVersionedEndpointUrl() + { + $this->addMockSubscriber($this->makeResponse('{}', 200)); + + $endpoint = new Endpoint(); + + $expectedUrl = "http://hostport/v1"; + $actualUrl = $this->invokeMethod( + $endpoint, + 'getVersionedUrl', + array("http://hostport/v1", null, $this->client) + ); + + $this->assertInstanceOf('Guzzle\Http\Url', $actualUrl); + $this->assertEquals($expectedUrl, $actualUrl); + } +} diff --git a/tests/OpenCloud/Tests/Common/ServiceTest.php b/tests/OpenCloud/Tests/Common/ServiceTest.php index 6ff99ccd1..1e4e25230 100644 --- a/tests/OpenCloud/Tests/Common/ServiceTest.php +++ b/tests/OpenCloud/Tests/Common/ServiceTest.php @@ -32,7 +32,6 @@ class ServiceTest extends \OpenCloud\Tests\OpenCloudTestCase { - private $service; public function setupObjects() diff --git a/tests/OpenCloud/Tests/Compute/Resource/ImageTest.php b/tests/OpenCloud/Tests/Compute/Resource/ImageTest.php index aa4123b6c..c388e8c73 100644 --- a/tests/OpenCloud/Tests/Compute/Resource/ImageTest.php +++ b/tests/OpenCloud/Tests/Compute/Resource/ImageTest.php @@ -22,7 +22,6 @@ class ImageTest extends ComputeTestCase { - public function test_good_image() { $image = new Image($this->service); diff --git a/tests/OpenCloud/Tests/Compute/Resource/KeyPairTest.php b/tests/OpenCloud/Tests/Compute/Resource/KeyPairTest.php index 609fa825e..493f5a9b0 100644 --- a/tests/OpenCloud/Tests/Compute/Resource/KeyPairTest.php +++ b/tests/OpenCloud/Tests/Compute/Resource/KeyPairTest.php @@ -30,7 +30,6 @@ class KeyPairTest extends ComputeTestCase { - public function test_Service_Methods() { $this->assertInstanceOf( diff --git a/tests/OpenCloud/Tests/Compute/Resource/NetworkTest.php b/tests/OpenCloud/Tests/Compute/Resource/NetworkTest.php index 719a8073e..35067e360 100644 --- a/tests/OpenCloud/Tests/Compute/Resource/NetworkTest.php +++ b/tests/OpenCloud/Tests/Compute/Resource/NetworkTest.php @@ -35,7 +35,6 @@ class NetworkTest extends ComputeTestCase { - public function setupObjects() { parent::setupObjects(); @@ -47,6 +46,7 @@ public function test__construct() { $this->assertEquals(NetworkConst::RAX_PUBLIC, $this->network->id); $this->assertInstanceOf('OpenCloud\Compute\Resource\Network', $this->network); + $this->assertInstanceOf('OpenCloud\Networking\Resource\NetworkInterface', $this->network); } public function test_Create() diff --git a/tests/OpenCloud/Tests/Compute/Resource/ServerMetadataTest.php b/tests/OpenCloud/Tests/Compute/Resource/ServerMetadataTest.php index 5a1073112..f0d6a6a23 100644 --- a/tests/OpenCloud/Tests/Compute/Resource/ServerMetadataTest.php +++ b/tests/OpenCloud/Tests/Compute/Resource/ServerMetadataTest.php @@ -21,7 +21,6 @@ class ServerMetadataTest extends ComputeTestCase { - private $metadata; public function setupObjects() diff --git a/tests/OpenCloud/Tests/Compute/Resource/ServerTest.php b/tests/OpenCloud/Tests/Compute/Resource/ServerTest.php index d894e69a4..1c105396d 100644 --- a/tests/OpenCloud/Tests/Compute/Resource/ServerTest.php +++ b/tests/OpenCloud/Tests/Compute/Resource/ServerTest.php @@ -116,6 +116,18 @@ public function test_Rebuild3() $this->assertNotNull($resp->getStatusCode()); } + public function test_Suspend() + { + $resp = $this->server->suspend(); + $this->assertNotNull($resp->getStatusCode()); + } + + public function test_Resume() + { + $resp = $this->server->resume(); + $this->assertNotNull($resp->getStatusCode()); + } + public function test_Delete() { $resp = $this->server->delete(); @@ -308,17 +320,36 @@ public function test_Image_Schedule() public function test_Create_With_Networks() { + $neutronService = $this->client->networkingService(null, 'IAD'); + $neutronNetwork = $neutronService->network(); + $neutronNetwork->setId('12345'); + $this->service->server()->create(array( 'name' => 'personality test 1', 'image' => $this->service->imageList()->first(), 'flavor' => $this->service->flavorList()->first(), 'networks' => array( $this->service->network(Network::RAX_PUBLIC), - $this->service->network() + $this->service->network(), + $neutronNetwork, ) )); } + public function test_Create_With_Ports() + { + $neutronService = $this->client->networkingService(null, 'IAD'); + $port = $neutronService->port(); + $port->setId('foo'); + + $this->service->server()->create(array( + 'name' => 'port test', + 'image' => $this->service->imageList()->first(), + 'flavor' => $this->service->flavorList()->first(), + 'networks' => [$port] + )); + } + /** * @expectedException OpenCloud\Common\Exceptions\InvalidParameterError */ @@ -334,6 +365,45 @@ public function test_Create_Fails_Without_Correct_Networks() )); } + public function test_Create_With_Security_Group_Strings() + { + $new = new PublicServer($this->service); + $new->security_groups[] = 'foo'; + $obj = $new->createJson(); + + $this->assertCount(1, $obj->server->security_groups); + $this->assertEquals((object) array('name' => 'foo'), $obj->server->security_groups[0]); + } + + public function test_Create_With_Security_Group_Objects() + { + $neutronService = $this->client->networkingService(null, 'IAD'); + $securityGroup = $neutronService->securityGroup(); + $securityGroup->setName('foo'); + + $new = new PublicServer($this->service); + $new->security_groups[] = $securityGroup; + $obj = $new->createJson(); + + $this->assertCount(1, $obj->server->security_groups); + $this->assertEquals((object) array('name' => 'foo'), $obj->server->security_groups[0]); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\InvalidParameterError + */ + public function test_Create_Fails_Without_Correct_Security_Groups() + { + $this->service->server()->create(array( + 'name' => 'personality test 1', + 'image' => $this->service->imageList()->first(), + 'flavor' => $this->service->flavorList()->first(), + 'security_groups' => array( + 1234 + ) + )); + } + public function test_Create_With_Bootable_Volume() { $new = new PublicServer($this->service); @@ -364,4 +434,35 @@ public function test_Create_With_Bootable_Volume_Delete_On_Termination() $this->assertEquals(0, $obj->boot_index); $this->assertEquals(true, $obj->delete_on_termination); } + + public function test_Diagnostics() + { + $this->addMockSubscriber($this->getTestFilePath('Diagnostics')); + $diagnostics = $this->server->diagnostics(); + $this->assertInternalType('object', $diagnostics); + $this->assertEquals(524288, $diagnostics->memory); + $this->assertEquals(-1, $diagnostics->vda_errors); + $this->assertEquals(662, $diagnostics->vnet1_tx_packets); + } + + public function test_Start() + { + $this->addMockSubscriber(new \Guzzle\Http\Message\Response(202)); + $this->assertEquals(202, $this->server->start()->getStatusCode()); + } + + public function test_Stop() + { + $this->addMockSubscriber(new \Guzzle\Http\Message\Response(202)); + $this->assertEquals(202, $this->server->stop()->getStatusCode()); + } + + public function test_Create_Availability_Zone() + { + $new = new PublicServer($this->service); + $new->setAvailabilityZone('AZ1'); + $obj = $new->CreateJson(); + + $this->assertEquals('AZ1', $obj->server->availability_zone); + } } diff --git a/tests/OpenCloud/Tests/Compute/Resource/VolumeAttachmentTest.php b/tests/OpenCloud/Tests/Compute/Resource/VolumeAttachmentTest.php index 9f71ea71e..396439045 100644 --- a/tests/OpenCloud/Tests/Compute/Resource/VolumeAttachmentTest.php +++ b/tests/OpenCloud/Tests/Compute/Resource/VolumeAttachmentTest.php @@ -31,7 +31,6 @@ class VolumeAttachmentTest extends ComputeTestCase { - private $attachment; public function setupObjects() diff --git a/tests/OpenCloud/Tests/Compute/ServiceTest.php b/tests/OpenCloud/Tests/Compute/ServiceTest.php index 538206b27..90537ff22 100644 --- a/tests/OpenCloud/Tests/Compute/ServiceTest.php +++ b/tests/OpenCloud/Tests/Compute/ServiceTest.php @@ -29,7 +29,6 @@ class ServiceTest extends ComputeTestCase { - public function test__construct() { $this->assertInstanceOf( @@ -95,5 +94,5 @@ public function testV1Dot1IsSupported() $computeService = $this->getClient()->computeService(null, 'DFW'); $this->assertStringStartsWith('/v1.1', $computeService->getUrl()->getPath()); - } + } } diff --git a/tests/OpenCloud/Tests/Compute/_response/Diagnostics.resp b/tests/OpenCloud/Tests/Compute/_response/Diagnostics.resp new file mode 100644 index 000000000..e9fdec80d --- /dev/null +++ b/tests/OpenCloud/Tests/Compute/_response/Diagnostics.resp @@ -0,0 +1,24 @@ +HTTP/1.1 200 OK +Date: Fri, 15 Nov 2013 14:12:58 GMT +Content-Length: 1364 +Content-Type: application/json +X-Compute-Request-Id: req-164dc435-90c2-48ce-9d69-96f170c518c8 +Server: Jetty(8.0.y.z-SNAPSHOT) + +{ + "cpu0_time": 17300000000, + "memory": 524288, + "vda_errors": -1, + "vda_read": 262144, + "vda_read_req": 112, + "vda_write": 5778432, + "vda_write_req": 488, + "vnet1_rx": 2070139, + "vnet1_rx_drop": 0, + "vnet1_rx_errors": 0, + "vnet1_rx_packets": 26701, + "vnet1_tx": 140208, + "vnet1_tx_drop": 0, + "vnet1_tx_errors": 0, + "vnet1_tx_packets": 662 +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/Compute/_response/Extensions.resp b/tests/OpenCloud/Tests/Compute/_response/Extensions.resp index d1b920829..8474a182c 100644 --- a/tests/OpenCloud/Tests/Compute/_response/Extensions.resp +++ b/tests/OpenCloud/Tests/Compute/_response/Extensions.resp @@ -15,6 +15,14 @@ Server: Jetty(8.0.y.z-SNAPSHOT) "alias": "OS-DCF", "description": "Disk Management Extension." }, + { + "updated": "2013-01-30T00:00:00Z", + "name": "ExtendedAvailabilityZone", + "links": [], + "namespace": "http://docs.openstack.org/compute/ext/extended_availability_zone/api/v2", + "alias": "OS-EXT-AZ", + "description": "Extended Availability Zone support." + }, { "updated": "2013-02-19T00:00:00Z", "name": "ImageSize", @@ -119,6 +127,22 @@ Server: Jetty(8.0.y.z-SNAPSHOT) "alias": "os-keypairs", "description": "Keypair Support." }, + { + "updated": "2011-12-21T00:00:00+00:00", + "name": "ServerDiagnostics", + "links": [], + "namespace": "http://docs.openstack.org/compute/ext/server-diagnostics/api/v1.1", + "alias": "os-server-diagnostics", + "description": "Allow Admins to view server diagnostics through server action." + }, + { + "updated": "2012-01-23T00:00:00+00:00", + "name": "ServerStartStop", + "links": [], + "namespace": "http://docs.openstack.org/compute/ext/servers/api/v1.1", + "alias": "os-server-start-stop", + "description": "Start/Stop instance compute API support." + }, { "updated": "2012-03-07T14:46:43Z", "name": "OSNetworksV2", diff --git a/tests/OpenCloud/Tests/DNS/Resource/DomainTest.php b/tests/OpenCloud/Tests/DNS/Resource/DomainTest.php index c097abe47..a2cba23fb 100644 --- a/tests/OpenCloud/Tests/DNS/Resource/DomainTest.php +++ b/tests/OpenCloud/Tests/DNS/Resource/DomainTest.php @@ -31,7 +31,6 @@ class DomainTest extends DnsTestCase { - public function test__construct() { $this->assertInstanceOf('OpenCloud\DNS\Resource\Domain', $this->domain); diff --git a/tests/OpenCloud/Tests/DNS/Resource/PtrRecordTest.php b/tests/OpenCloud/Tests/DNS/Resource/PtrRecordTest.php index afe42e352..b53335a7d 100644 --- a/tests/OpenCloud/Tests/DNS/Resource/PtrRecordTest.php +++ b/tests/OpenCloud/Tests/DNS/Resource/PtrRecordTest.php @@ -89,4 +89,4 @@ public function test_Load_Balancer_Can_Have_PtrRecords() $this->record->getDeviceParent() ); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/DNS/Resource/RecordTest.php b/tests/OpenCloud/Tests/DNS/Resource/RecordTest.php index 4eb34666b..be73cdda4 100644 --- a/tests/OpenCloud/Tests/DNS/Resource/RecordTest.php +++ b/tests/OpenCloud/Tests/DNS/Resource/RecordTest.php @@ -21,7 +21,6 @@ class RecordTest extends DnsTestCase { - public function test__construct() { $record = $this->domain->record(array( diff --git a/tests/OpenCloud/Tests/DNS/ServiceTest.php b/tests/OpenCloud/Tests/DNS/ServiceTest.php index a8e217bae..9503e0409 100644 --- a/tests/OpenCloud/Tests/DNS/ServiceTest.php +++ b/tests/OpenCloud/Tests/DNS/ServiceTest.php @@ -22,7 +22,6 @@ class ServiceTest extends DnsTestCase { - public function test__construct() { $this->assertInstanceOf('OpenCloud\DNS\Service', $this->service); @@ -41,6 +40,24 @@ public function testDomain() $this->assertInstanceOf('OpenCloud\DNS\Resource\Domain', $this->service->domain()); } + public function testDomainByName() + { + $this->addMockSubscriber($this->makeResponse('{"domains":[{"name":"region2.example.net","id":2725352,"updated":"2011-06-23T20:21:06.000+0000","created":"2011-06-23T19:24:27.000+0000"}],"totalEntries":114}', 200)); + $domain = $this->service->domainByName("region2.example.net"); + + $this->assertInstanceOf('OpenCloud\DNS\Resource\Domain', $domain); + $this->assertEquals("region2.example.net", $domain->getName()); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\DomainNotFoundException + */ + public function testDomainByNameWhenDomainNotFound() + { + $this->addMockSubscriber($this->makeResponse('{"domains":[],"totalEntries":114}', 200)); + $domain = $this->service->domainByName("region2.example.net"); + } + /** * @mockFile Domain_List */ diff --git a/tests/OpenCloud/Tests/Database/DatabaseTestCase.php b/tests/OpenCloud/Tests/Database/DatabaseTestCase.php index 0e8ad75cb..c9cd9417b 100644 --- a/tests/OpenCloud/Tests/Database/DatabaseTestCase.php +++ b/tests/OpenCloud/Tests/Database/DatabaseTestCase.php @@ -18,6 +18,7 @@ namespace OpenCloud\Tests\Database; use OpenCloud\Tests\OpenCloudTestCase; +use OpenCloud\Tests\MockLogger; class DatabaseTestCase extends OpenCloudTestCase { @@ -28,7 +29,9 @@ class DatabaseTestCase extends OpenCloudTestCase public function setupObjects() { - $this->service = $this->getClient()->databaseService(); + $client = $this->getClient(); + $client->setLogger(new MockLogger()); + $this->service = $client->databaseService(); $this->addMockSubscriber($this->getTestFilePath('Instance')); $this->instance = $this->service->instance('foo'); @@ -36,5 +39,11 @@ public function setupObjects() $this->configuration = $this->service->configuration('005a8bb7-a8df-40ee-b0b7-fc144641abc2'); $this->datastore = $this->service->datastore('10000000-0000-0000-0000-000000000001'); $this->datastoreVersion = $this->datastore->version('b00000b0-00b0-0b00-00b0-000b000000bb'); + $this->backup = $this->service->backup(); + } + + protected function assertCriticalMessageWasLogged() + { + $this->assertNotEmpty($this->getClient()->getLogger()->getCriticalLogMessage()); } } diff --git a/tests/OpenCloud/Tests/Database/Resource/BackupTest.php b/tests/OpenCloud/Tests/Database/Resource/BackupTest.php new file mode 100644 index 000000000..bcd5e3c57 --- /dev/null +++ b/tests/OpenCloud/Tests/Database/Resource/BackupTest.php @@ -0,0 +1,66 @@ +assertInstanceOf('OpenCloud\Database\Resource\Backup', $this->backup); + } + + public function testDelete() + { + $this->backup->delete(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\BackupInstanceError + */ + public function test_Create_Fails_Without_InstanceId() + { + $this->assertFalse($this->backup->create(array( + 'name' => 'test', + 'description' => 'test desc' + ))); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\BackupNameError + */ + public function test_Create_Fails_Without_Name() + { + $this->assertFalse($this->backup->create(array( + 'description' => 'test description', + 'instanceId' => '1234' + ))); + } + + public function testCreate() + { + $this->backup->create(array( + 'name' => 'test backup', + 'instanceId' => '1234' + )); + + $this->assertEquals('test backup', $this->backup->name); + $this->assertEquals('1234', $this->backup->instanceId); + } +} diff --git a/tests/OpenCloud/Tests/Database/Resource/ConfigurationTest.php b/tests/OpenCloud/Tests/Database/Resource/ConfigurationTest.php index 38c96f5e7..12c0eb5da 100644 --- a/tests/OpenCloud/Tests/Database/Resource/ConfigurationTest.php +++ b/tests/OpenCloud/Tests/Database/Resource/ConfigurationTest.php @@ -21,7 +21,6 @@ class ConfigurationTest extends DatabaseTestCase { - public function test_Class() { $this->assertInstanceOf('OpenCloud\Database\Resource\Configuration', $this->configuration); @@ -51,6 +50,4 @@ public function testInstanceList() { $this->assertInstanceOf(self::COLLECTION_CLASS, $this->configuration->instanceList()); } - - -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Database/Resource/DatastoreTest.php b/tests/OpenCloud/Tests/Database/Resource/DatastoreTest.php index bf248d120..ade80b778 100644 --- a/tests/OpenCloud/Tests/Database/Resource/DatastoreTest.php +++ b/tests/OpenCloud/Tests/Database/Resource/DatastoreTest.php @@ -21,7 +21,6 @@ class DatastoreTest extends DatabaseTestCase { - public function test_Class() { $this->assertInstanceOf('OpenCloud\Database\Resource\Datastore', $this->datastore); @@ -47,4 +46,4 @@ public function testVersionList() { $this->assertInstanceOf(self::COLLECTION_CLASS, $this->datastore->versionList()); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Database/Resource/DatastoreVersionTest.php b/tests/OpenCloud/Tests/Database/Resource/DatastoreVersionTest.php index 618be4d53..a5cb6ec57 100644 --- a/tests/OpenCloud/Tests/Database/Resource/DatastoreVersionTest.php +++ b/tests/OpenCloud/Tests/Database/Resource/DatastoreVersionTest.php @@ -21,7 +21,6 @@ class DatastoreVersionTest extends DatabaseTestCase { - public function test_Class() { $this->assertInstanceOf('OpenCloud\Database\Resource\DatastoreVersion', $this->datastoreVersion); @@ -42,4 +41,4 @@ public function testDelete() { $this->datastore->delete(); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Database/Resource/InstanceTest.php b/tests/OpenCloud/Tests/Database/Resource/InstanceTest.php index 72f2371da..99805a5be 100644 --- a/tests/OpenCloud/Tests/Database/Resource/InstanceTest.php +++ b/tests/OpenCloud/Tests/Database/Resource/InstanceTest.php @@ -21,7 +21,6 @@ class InstanceTest extends DatabaseTestCase { - public function test_Class() { $this->assertInstanceOf('OpenCloud\Database\Resource\Instance', $this->instance); @@ -32,10 +31,10 @@ public function testUpdateJson() $replacementValues = array( 'configuration' => '005a8bb7-a8df-40ee-b0b7-fc144641abc2' ); - + $method = new \ReflectionMethod('OpenCloud\Database\Resource\Instance', 'updateJson'); $method->setAccessible(true); - + $expected = (object) array( 'instance' => $replacementValues ); @@ -92,4 +91,18 @@ public function testUserList() { $this->assertInstanceOf(self::COLLECTION_CLASS, $this->instance->userList()); } + + public function testBackupList() + { + $this->assertInstanceOf(self::COLLECTION_CLASS, $this->instance->backupList()); + } + + public function testCreateBackup() + { + $backup = $this->instance->createBackup(array( + 'name' => 'test-backup', + 'description' => 'test' + )); + $this->assertInstanceOf('OpenCloud\Database\Resource\Backup', $backup); + } } diff --git a/tests/OpenCloud/Tests/Database/Resource/UserTest.php b/tests/OpenCloud/Tests/Database/Resource/UserTest.php index 04d9189c9..134ff606b 100644 --- a/tests/OpenCloud/Tests/Database/Resource/UserTest.php +++ b/tests/OpenCloud/Tests/Database/Resource/UserTest.php @@ -46,7 +46,7 @@ public function test__construct() 'OpenCloud\Database\Resource\User', $this->user ); - $u = $this->instance->user('glen', array('one', 'two')); + $u = $this->instance->user('glen', ['one', 'two']); $this->assertEquals('glen', $u->name); $this->assertEquals(2, count($u->databases)); } @@ -84,14 +84,14 @@ public function testAddDatabase() public function testCreate() { - $response = $this->user->create(array( + $response = $this->user->create([ 'name' => 'FOOBAR', 'password' => 'BAZ', - 'databases' => array( + 'databases' => [ 'foo', 'baz' - ) - )); + ] + ]); $this->assertLessThan(205, $response->getStatusCode()); $this->assertEquals('FOOBAR', $this->user->getName()); $this->assertEquals('BAZ', $this->user->password); @@ -119,4 +119,15 @@ public function testNameFailsWhenNotSet() { $this->instance->user()->getName(); } + + public function test_It_Grants_Access_To_Db() + { + $this->user->name = 'foo'; + + $response = $this->user->grantDbAccess([ + 'foo', 'bar', 'baz', + ]); + + $this->isResponse($response); + } } diff --git a/tests/OpenCloud/Tests/Database/ServiceTest.php b/tests/OpenCloud/Tests/Database/ServiceTest.php index dcd7a7107..ee1989538 100644 --- a/tests/OpenCloud/Tests/Database/ServiceTest.php +++ b/tests/OpenCloud/Tests/Database/ServiceTest.php @@ -27,9 +27,10 @@ namespace OpenCloud\Tests\Database; +use OpenCloud\Database\Service; + class ServiceTest extends DatabaseTestCase { - public function test__construct() { $this->assertInstanceOf( @@ -72,4 +73,14 @@ public function testDatastoreList() { $this->assertInstanceOf(self::COLLECTION_CLASS, $this->service->datastoreList()); } + + public function testBackup() + { + $this->assertInstanceOf('OpenCloud\Database\Resource\Backup', $this->service->Backup()); + } + + public function testBackupList() + { + $this->assertInstanceOf(self::COLLECTION_CLASS, $this->service->backupList()); + } } diff --git a/tests/OpenCloud/Tests/Identity/Resource/RoleTest.php b/tests/OpenCloud/Tests/Identity/Resource/RoleTest.php index d83105289..bb8bf0198 100644 --- a/tests/OpenCloud/Tests/Identity/Resource/RoleTest.php +++ b/tests/OpenCloud/Tests/Identity/Resource/RoleTest.php @@ -31,4 +31,4 @@ public function test_Methods() $role->setDescription('bar'); $this->assertEquals('bar', $role->getDescription()); } -} +} diff --git a/tests/OpenCloud/Tests/Identity/Resource/TokenTest.php b/tests/OpenCloud/Tests/Identity/Resource/TokenTest.php index ea491f7e2..30fe6ce13 100644 --- a/tests/OpenCloud/Tests/Identity/Resource/TokenTest.php +++ b/tests/OpenCloud/Tests/Identity/Resource/TokenTest.php @@ -35,4 +35,4 @@ public function test_Methods() $tenant->setEnabled(false); $this->assertFalse($tenant->isEnabled()); } -} +} diff --git a/tests/OpenCloud/Tests/Identity/Resource/UserTest.php b/tests/OpenCloud/Tests/Identity/Resource/UserTest.php index 925a625d6..d2c594117 100644 --- a/tests/OpenCloud/Tests/Identity/Resource/UserTest.php +++ b/tests/OpenCloud/Tests/Identity/Resource/UserTest.php @@ -21,7 +21,6 @@ class UserTest extends IdentityTestCase { - public function setupObjects() { parent::setupObjects(); diff --git a/tests/OpenCloud/Tests/Image/Resource/ImageTest.php b/tests/OpenCloud/Tests/Image/Resource/ImageTest.php index 0d8255312..4a7554edc 100644 --- a/tests/OpenCloud/Tests/Image/Resource/ImageTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/ImageTest.php @@ -22,11 +22,19 @@ use OpenCloud\Image\Resource\Schema\Schema; use OpenCloud\Tests\OpenCloudTestCase; +class PublicImage extends Image +{ + public static function getPatchHeaders() + { + return parent::getPatchHeaders(); + } +} + class ImageTest extends OpenCloudTestCase { public function setupObjects() { - $this->image = new Image($this->getClient()->imageService('cloudImages', 'IAD')); + $this->image = new PublicImage($this->getClient()->imageService('cloudImages', 'IAD')); } protected function getSchemaData() @@ -139,4 +147,14 @@ public function test_Delete_Tag() $this->assertInstanceOf('Guzzle\Http\Message\Response', $this->image->deleteTag(12345)); } -} \ No newline at end of file + + public function testGetPatchHeaders() + { + $expectedHeaders = array( + 'Content-Type' => 'application/openstack-images-v2.1-json-patch' + ); + + $image = $this->image; + $this->assertEquals($expectedHeaders, $image::getPatchHeaders()); + } +} diff --git a/tests/OpenCloud/Tests/Image/Resource/JsonPatch/DocumentTest.php b/tests/OpenCloud/Tests/Image/Resource/JsonPatch/DocumentTest.php index cf0084f6b..1b27aa5dc 100644 --- a/tests/OpenCloud/Tests/Image/Resource/JsonPatch/DocumentTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/JsonPatch/DocumentTest.php @@ -50,4 +50,4 @@ public function test_To_String() $this->assertEquals('[{"op": "replace", "path": "/foo", "value": "bar"}]', $document->toString()); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Image/Resource/JsonPatch/EncoderTest.php b/tests/OpenCloud/Tests/Image/Resource/JsonPatch/EncoderTest.php index 2912d34bd..bc4dea8f8 100644 --- a/tests/OpenCloud/Tests/Image/Resource/JsonPatch/EncoderTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/JsonPatch/EncoderTest.php @@ -60,4 +60,4 @@ public function test_Transform() $this->assertEquals('A', Encoder::transform('A')); $this->assertEquals('!!!!', Encoder::transform('!!!!')); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Image/Resource/JsonPatch/OperationTest.php b/tests/OpenCloud/Tests/Image/Resource/JsonPatch/OperationTest.php index d31007c6e..ae1915d9e 100644 --- a/tests/OpenCloud/Tests/Image/Resource/JsonPatch/OperationTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/JsonPatch/OperationTest.php @@ -65,4 +65,4 @@ public function test_Validate_Fails() $operation->setType('foo'); $operation->validate(); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Image/Resource/MemberTest.php b/tests/OpenCloud/Tests/Image/Resource/MemberTest.php index 0937ed74f..d4b106db7 100644 --- a/tests/OpenCloud/Tests/Image/Resource/MemberTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/MemberTest.php @@ -84,4 +84,4 @@ public function test_Delete() $this->assertInstanceOf('Guzzle\Http\Message\Response', $response); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Image/Resource/Schema/PropertyTest.php b/tests/OpenCloud/Tests/Image/Resource/Schema/PropertyTest.php index c4b11e5b0..7eccbef72 100644 --- a/tests/OpenCloud/Tests/Image/Resource/Schema/PropertyTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/Schema/PropertyTest.php @@ -126,4 +126,4 @@ public function test_Get_Path() $this->assertEquals('/id', $property->getPath()); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Image/Resource/Schema/SchemaTest.php b/tests/OpenCloud/Tests/Image/Resource/Schema/SchemaTest.php index 66d16b3fe..9d9b70f0a 100644 --- a/tests/OpenCloud/Tests/Image/Resource/Schema/SchemaTest.php +++ b/tests/OpenCloud/Tests/Image/Resource/Schema/SchemaTest.php @@ -73,4 +73,4 @@ public function test_Deciding_Operation_Type() $property2 = Property::factory(array('type' => 'string', 'name' => 'username')); $this->assertEquals(OperationType::ADD, $schema1->decideOperationType($property2)); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Image/ServiceTest.php b/tests/OpenCloud/Tests/Image/ServiceTest.php index 8b3cfa940..e9fac1023 100644 --- a/tests/OpenCloud/Tests/Image/ServiceTest.php +++ b/tests/OpenCloud/Tests/Image/ServiceTest.php @@ -59,4 +59,4 @@ public function test_Member_Schema() { $this->assertInstanceOf('OpenCloud\Image\Resource\Schema\Schema', $this->service->getMemberSchema()); } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/LoadBalancer/Resource/LoadBalancerTest.php b/tests/OpenCloud/Tests/LoadBalancer/Resource/LoadBalancerTest.php index 97d317d1c..b4a270a8c 100644 --- a/tests/OpenCloud/Tests/LoadBalancer/Resource/LoadBalancerTest.php +++ b/tests/OpenCloud/Tests/LoadBalancer/Resource/LoadBalancerTest.php @@ -243,6 +243,18 @@ public function test_SSL_Termination() ); } + public function test_Certificate_Mapping() + { + $this->assertEquals( + 'https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123456/loadbalancers/2000/ssltermination/certificatemappings', + (string)$this->loadBalancer->certificateMapping()->Url() + ); + $this->assertEquals( + 'https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123456/loadbalancers/2000/ssltermination/certificatemappings/1', + (string)$this->loadBalancer->certificateMapping(1)->Url() + ); + } + public function test_Metadata() { $this->assertEquals( diff --git a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php index 247525033..9beb0c620 100644 --- a/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php +++ b/tests/OpenCloud/Tests/LoadBalancer/ServiceTest.php @@ -27,16 +27,13 @@ namespace OpenCloud\Tests\LoadBalancer; -class ServiceTest extends \OpenCloud\Tests\OpenCloudTestCase -{ - - private $service; - - public function setupObjects() - { - $this->service = $this->getClient()->loadBalancerService('cloudLoadBalancers', 'DFW', 'publicURL'); - } +use Guzzle\Http\Message\Response; +use Guzzle\Plugin\Mock\MockPlugin; +use OpenCloud\Rackspace; +use OpenCloud\Tests\MockSubscriber; +class ServiceTest extends LoadBalancerTestCase +{ public function test__construct() { $this->assertInstanceOf( @@ -53,12 +50,36 @@ public function testLoadBalancer() ); } - public function testLoadBalancerList() + public function test_Listing_Load_Balancers() { - $this->assertInstanceOf( - self::COLLECTION_CLASS, - $this->service->loadBalancerList() - ); + // Load JSON HTTP data + $authData = file_get_contents($this->getTestFilePath('Auth', './')); + $data1 = file_get_contents($this->getTestFilePath('LoadBalancers1')); + $data2 = file_get_contents($this->getTestFilePath('LoadBalancers2')); + $data3 = file_get_contents($this->getTestFilePath('LoadBalancers3')); + + // Populate mock response queue + $mock = new MockPlugin(); + $mock->addResponse(Response::fromMessage($authData)) + ->addResponse(Response::fromMessage($data1)) + ->addResponse(Response::fromMessage($data2)) + ->addResponse(Response::fromMessage($data3)); + + // We need to define our own setup because *jazz hands* + $client = $this->newClient(); + $client->addSubscriber($mock); + $service = $client->loadBalancerService(null, 'IAD'); + + // Ensure that a series of paginated calls return a holistic collection + $lbs = $service->loadBalancerList(false, array('limit' => 2)); + $ids = array(); + foreach ($lbs as $lb) { + $ids[] = $lb->id; + } + + // Check our assumptions + $this->isCollection($lbs); + $this->assertEquals($ids, array(1, 2, 3, 4, 5)); } public function testBillableLoadBalancer() diff --git a/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp new file mode 100644 index 000000000..1827f2b44 --- /dev/null +++ b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers1.resp @@ -0,0 +1,80 @@ +HTTP/1.1 200 OK +Status: 200 OK +Date: Thu, 28 Jul 2011 21:54:21 GMT +X-API-VERSION: 1.0.17 +Content-Type: application/json +Content-Length: 1975 + +{ + "loadBalancers":[ + { + "name":"lb-site1", + "id":1, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":3, + "virtualIps":[ + { + "id":403, + "address":"206.55.130.1", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site2", + "id":2, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site3", + "id":3, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + } + ] +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp new file mode 100644 index 000000000..2ab7b2381 --- /dev/null +++ b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers2.resp @@ -0,0 +1,80 @@ +HTTP/1.1 200 OK +Status: 200 OK +Date: Thu, 28 Jul 2011 21:54:21 GMT +X-API-VERSION: 1.0.17 +Content-Type: application/json +Content-Length: 1975 + +{ + "loadBalancers":[ + { + "name":"lb-site3", + "id":3, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site4", + "id":4, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + }, + { + "name":"lb-site5", + "id":5, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + } + ] +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp new file mode 100644 index 000000000..554a4430d --- /dev/null +++ b/tests/OpenCloud/Tests/LoadBalancer/_response/LoadBalancers3.resp @@ -0,0 +1,34 @@ +HTTP/1.1 200 OK +Status: 200 OK +Date: Thu, 28 Jul 2011 21:54:21 GMT +X-API-VERSION: 1.0.17 +Content-Type: application/json +Content-Length: 1975 + +{ + "loadBalancers":[ + { + "name":"lb-site5", + "id":5, + "protocol":"HTTP", + "port":80, + "algorithm":"RANDOM", + "status":"ACTIVE", + "nodeCount":4, + "virtualIps":[ + { + "id":401, + "address":"206.55.130.2", + "type":"PUBLIC", + "ipVersion":"IPV4" + } + ], + "created":{ + "time":"2010-11-30T03:23:42Z" + }, + "updated":{ + "time":"2010-11-30T03:23:44Z" + } + } + ] +} \ No newline at end of file diff --git a/tests/OpenCloud/Tests/MockLogger.php b/tests/OpenCloud/Tests/MockLogger.php new file mode 100644 index 000000000..9aca3dd68 --- /dev/null +++ b/tests/OpenCloud/Tests/MockLogger.php @@ -0,0 +1,35 @@ +criticalLogMessage; + } + + public function getCriticalLogMessage() + { + return $this->criticalLogMessage; + } +} diff --git a/tests/OpenCloud/Tests/MockSubscriber.php b/tests/OpenCloud/Tests/MockSubscriber.php index 7cb85acf0..d55d1e438 100644 --- a/tests/OpenCloud/Tests/MockSubscriber.php +++ b/tests/OpenCloud/Tests/MockSubscriber.php @@ -64,4 +64,4 @@ public function onRequestBeforeSend(Event $event) $event->stopPropagation(); } } -} \ No newline at end of file +} diff --git a/tests/OpenCloud/Tests/Networking/NetworkingTestCase.php b/tests/OpenCloud/Tests/Networking/NetworkingTestCase.php new file mode 100644 index 000000000..399094b6e --- /dev/null +++ b/tests/OpenCloud/Tests/Networking/NetworkingTestCase.php @@ -0,0 +1,61 @@ +service = $this->getClient()->networkingService(); + } + + protected function assertIsService($object) + { + $this->assertInstanceOf('OpenCloud\Networking\Service', $object); + } + + protected function assertIsNetwork($object) + { + $this->assertInstanceOf('OpenCloud\Networking\Resource\Network', $object); + } + + protected function assertIsSubnet($object) + { + $this->assertInstanceOf('OpenCloud\Networking\Resource\Subnet', $object); + } + + protected function assertIsPort($object) + { + $this->assertInstanceOf('OpenCloud\Networking\Resource\Port', $object); + } + + protected function assertIsSecurityGroup($object) + { + $this->assertInstanceOf('OpenCloud\Networking\Resource\SecurityGroup', $object); + } + + protected function assertIsSecurityGroupRule($object) + { + $this->assertInstanceOf('OpenCloud\Networking\Resource\SecurityGroupRule', $object); + } +} diff --git a/tests/OpenCloud/Tests/Networking/ServiceTest.php b/tests/OpenCloud/Tests/Networking/ServiceTest.php new file mode 100644 index 000000000..f2ab2cbfe --- /dev/null +++ b/tests/OpenCloud/Tests/Networking/ServiceTest.php @@ -0,0 +1,195 @@ +getClient()->networkingService(null, 'IAD'); + $this->assertIsService($service); + } + + public function testCreateNetwork() + { + $this->assertIsNetwork($this->service->createNetwork(array( + 'name' => 'network1' + ))); + } + + public function testCreateNetworks() + { + $this->addMockSubscriber($this->makeResponse('{"networks":[{"admin_state_up":true,"id":"e6031bc2-901a-4c66-82da-f4c32ed89406","name":"sample_network_1","shared":false,"status":"ACTIVE","subnets":[],"tenant_id":"d19231fc08ec4bc4829b668040d34512"},{"admin_state_up":false,"id":"64239a54-dcc4-4b39-920b-b37c2144effa","name":"sample_network_2","shared":false,"status":"ACTIVE","subnets":[],"tenant_id":"d19231fc08ec4bc4829b668040d34512"}]}')); + + $createdNetworks = $this->service->createNetworks(array( + array( + 'name' => 'sample_network_1' + ), + array( + 'name' => 'sample_network_2' + ) + )); + $this->isCollection($createdNetworks); + $this->assertIsNetwork($createdNetworks->getElement(0)); + } + + public function testListNetworks() + { + $this->addMockSubscriber($this->makeResponse('{"networks":[{"admin_state_up":true,"id":"00000000-0000-0000-0000-000000000000","name":"public","shared":true,"status":"ACTIVE","subnets":[],"tenant_id":"rackspace"},{"admin_state_up":true,"id":"11111111-1111-1111-1111-111111111111","name":"private","shared":true,"status":"ACTIVE","subnets":[],"tenant_id":"rackspace"},{"admin_state_up":true,"id":"2993e407-5531-4ca8-9d2a-0d13b5cac904","name":"RackNet","shared":false,"status":"ACTIVE","subnets":["017d8997-70ec-4448-91d9-a8097d6d60f3"],"tenant_id":"123456"}]}')); + + $networks = $this->service->listNetworks(); + $this->isCollection($networks); + $this->assertIsNetwork($networks->getElement(0)); + } + + public function testGetNetwork() + { + $this->addMockSubscriber($this->makeResponse('{"network":{"admin_state_up":true,"id":"4d4e772a-98e7-4409-8a3c-4fed4324da26","name":"sameer-3","shared":false,"status":"ACTIVE","subnets":[],"tenant_id":"546428"}}')); + + $network = $this->service->getNetwork('4d4e772a-98e7-4409-8a3c-4fed4324da26'); + $this->assertIsNetwork($network); + $this->assertEquals('sameer-3', $network->getName()); + } + + public function testCreateSubnet() + { + $this->assertIsSubnet($this->service->createSubnet()); + } + + public function testCreateSubnets() + { + $this->addMockSubscriber($this->makeResponse('{"subnets":[{"cidr":"192.168.199.0/24","ip_version":4,"network_id":"e6031bc2-901a-4c66-82da-f4c32ed89406"},{"cidr":"10.56.4.0/22","ip_version":4,"network_id":"64239a54-dcc4-4b39-920b-b37c2144effa"}]}')); + + $createdSubnets = $this->service->createSubnets(array( + array( + 'cidr' => '192.168.199.0/24' + ), + array( + 'cidr' => '10.56.4.0/22' + ) + )); + $this->isCollection($createdSubnets); + $this->assertIsSubnet($createdSubnets->getElement(0)); + } + + public function testListSubnets() + { + $this->addMockSubscriber($this->makeResponse('{"subnets":[{"allocation_pools":[{"end":"192.168.9.254","start":"192.168.9.1"}],"cidr":"192.168.9.0/24","dns_nameservers":[],"enable_dhcp":false,"gateway_ip":null,"host_routes":[],"id":"f975defc-637d-4e2a-858b-c6cc4cec3951","ip_version":4,"name":"","network_id":"0ebf6a10-5fc1-4f13-aca9-be0a2a00b1ac","tenant_id":"123456"}]}')); + + $subnets = $this->service->listSubnets(); + $this->isCollection($subnets); + $this->assertIsSubnet($subnets->getElement(0)); + } + + public function testGetSubnet() + { + $this->addMockSubscriber($this->makeResponse('{"subnet":{"name":"my_subnet","enable_dhcp":false,"network_id":"d32019d3-bc6e-4319-9c1d-6722fc136a22","tenant_id":"4fd44f30292945e481c7b8a0c8908869","dns_nameservers":[],"allocation_pools":[{"start":"192.0.0.2","end":"192.255.255.254"}],"host_routes":[],"ip_version":4,"gateway_ip":"192.0.0.1","cidr":"192.0.0.0/8","id":"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"}}')); + + $subnet = $this->service->getSubnet('54d6f61d-db07-451c-9ab3-b9609b6b6f0b'); + $this->assertIsSubnet($subnet); + $this->assertEquals('my_subnet', $subnet->getName()); + } + + public function testCreatePort() + { + $this->assertIsPort($this->service->createPort()); + } + + public function testCreatePorts() + { + $this->addMockSubscriber($this->makeResponse('{"ports":[{"admin_state_up":true,"device_id":"24df1d04-d5cb-41e1-8de5-61ed77c558df","name":"port1","network_id":"64239a54-dcc4-4b39-920b-b37c2144effa","security_groups":["dbc107f4-afcd-4d5a-9352-f68f82241d5b"]},{"admin_state_up":false,"name":"port2","network_id":"e6031bc2-901a-4c66-82da-f4c32ed89406","security_groups":["8bf3f7cc-8471-40b1-815f-9da47e79775b","dbc107f4-afcd-4d5a-9352-f68f82241d5b"]}]}')); + + $createdPorts = $this->service->createPorts(array( + array( + 'name' => 'port1' + ), + array( + 'name' => 'port2' + ) + )); + $this->isCollection($createdPorts); + $this->assertIsPort($createdPorts->getElement(0)); + } + + public function testListPorts() + { + $this->addMockSubscriber($this->makeResponse('{"ports":[{"admin_state_up":true,"device_id":"","device_owner":null,"fixed_ips":[{"ip_address":"192.168.3.11","subnet_id":"739ecc58-f9a0-4145-8a06-cd415e6e5c8d"}],"id":"10ba23f5-bb70-4fd7-a118-83f89b62e340","mac_address":"BE:CB:FE:00:00:EE","name":"port1","network_id":"6406ed30-193a-4958-aae5-7c05268d332b","security_groups":[],"status":"ACTIVE","tenant_id":"123456"}]}')); + + $ports = $this->service->listPorts(); + $this->isCollection($ports); + $this->assertIsPort($ports->getElement(0)); + } + + public function testGetPort() + { + $this->addMockSubscriber($this->makeResponse('{"port":{"admin_state_up":true,"device_id":"","device_owner":null,"fixed_ips":[{"ip_address":"192.168.3.11","subnet_id":"739ecc58-f9a0-4145-8a06-cd415e6e5c8d"}],"id":"10ba23f5-bb70-4fd7-a118-83f89b62e340","mac_address":"BE:CB:FE:00:00:EE","name":"port1","network_id":"6406ed30-193a-4958-aae5-7c05268d332b","security_groups":[],"status":"ACTIVE","tenant_id":"123456"}}')); + + $port = $this->service->getPort('10ba23f5-bb70-4fd7-a118-83f89b62e340'); + $this->assertIsPort($port); + $this->assertEquals('port1', $port->getName()); + } + + public function testCreateSecurityGroup() + { + $this->assertIsSecurityGroup($this->service->createSecurityGroup()); + } + + public function testListSecurityGroups() + { + $this->addMockSubscriber($this->makeResponse('{"security_groups":[{"description":"default","id":"85cc3048-abc3-43cc-89b3-377341426ac5","name":"default","security_group_rules":[{"direction":"egress","ethertype":"IPv6","id":"3c0e45ff-adaf-4124-b083-bf390e5482ff","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"egress","ethertype":"IPv4","id":"93aa42e5-80db-4581-9391-3a608bd0e448","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"ingress","ethertype":"IPv6","id":"c0b09f00-1d49-4e64-a0a7-8a186d928138","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"ingress","ethertype":"IPv4","id":"f7d45c89-008e-4bab-88ad-d6811724c51c","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"}],"tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"}]}')); + + $securityGroups = $this->service->listSecurityGroups(); + $this->isCollection($securityGroups); + $this->assertIsSecurityGroup($securityGroups->getElement(0)); + } + + public function testGetSecurityGroup() + { + $this->addMockSubscriber($this->makeResponse('{"security_group":{"description":"default","id":"85cc3048-abc3-43cc-89b3-377341426ac5","name":"default","security_group_rules":[{"direction":"egress","ethertype":"IPv6","id":"3c0e45ff-adaf-4124-b083-bf390e5482ff","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"egress","ethertype":"IPv4","id":"93aa42e5-80db-4581-9391-3a608bd0e448","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"ingress","ethertype":"IPv6","id":"c0b09f00-1d49-4e64-a0a7-8a186d928138","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"ingress","ethertype":"IPv4","id":"f7d45c89-008e-4bab-88ad-d6811724c51c","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"}],"tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"}}')); + + $securityGroup = $this->service->getSecurityGroup('85cc3048-abc3-43cc-89b3-377341426ac5'); + $this->assertIsSecurityGroup($securityGroup); + $this->assertEquals('default', $securityGroup->getName()); + } + + public function testCreateSecurityGroupRule() + { + $this->assertIsSecurityGroupRule($this->service->createSecurityGroupRule()); + } + + public function testListSecurityGroupRules() + { + $this->addMockSubscriber($this->makeResponse('{"security_group_rules":[{"direction":"egress","ethertype":"IPv6","id":"3c0e45ff-adaf-4124-b083-bf390e5482ff","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"egress","ethertype":"IPv4","id":"93aa42e5-80db-4581-9391-3a608bd0e448","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"ingress","ethertype":"IPv6","id":"c0b09f00-1d49-4e64-a0a7-8a186d928138","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"},{"direction":"ingress","ethertype":"IPv4","id":"f7d45c89-008e-4bab-88ad-d6811724c51c","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"}]}')); + + $securityGroupRules = $this->service->listSecurityGroupRules(); + $this->isCollection($securityGroupRules); + $this->assertIsSecurityGroupRule($securityGroupRules->getElement(0)); + } + + public function testGetSecurityGroupRule() + { + $this->addMockSubscriber($this->makeResponse('{"security_group_rule":{"direction":"egress","ethertype":"IPv6","id":"3c0e45ff-adaf-4124-b083-bf390e5482ff","port_range_max":null,"port_range_min":null,"protocol":null,"remote_group_id":null,"remote_ip_prefix":null,"security_group_id":"85cc3048-abc3-43cc-89b3-377341426ac5","tenant_id":"e4f50856753b4dc6afee5fa6b9b6c550"}}')); + + $securityGroupRule = $this->service->getSecurityGroupRule('3c0e45ff-adaf-4124-b083-bf390e5482ff'); + $this->assertIsSecurityGroupRule($securityGroupRule); + $this->assertEquals('egress', $securityGroupRule->getDirection()); + } +} diff --git a/tests/OpenCloud/Tests/ObjectStore/ObjectStoreTestCase.php b/tests/OpenCloud/Tests/ObjectStore/ObjectStoreTestCase.php index 9640777cc..3c3c995c4 100644 --- a/tests/OpenCloud/Tests/ObjectStore/ObjectStoreTestCase.php +++ b/tests/OpenCloud/Tests/ObjectStore/ObjectStoreTestCase.php @@ -42,7 +42,12 @@ public function setupObjects() $this->addMockSubscriber($response1); - $response2 = new Response(204, array( + $this->container = $this->service->getContainer('foo'); + } + + protected function setupCdnContainerMockResponse() + { + $response = new Response(204, array( 'X-Cdn-Ssl-Uri' => 'https://83c49b9a2f7ad18250b3-346eb45fd42c58ca13011d659bfc1ac1.ssl.cf0.rackcdn.com', 'X-Ttl' => '259200', 'X-Cdn-Uri' => 'http://081e40d3ee1cec5f77bf-346eb45fd42c58ca13011d659bfc1ac1.r49.cf0.rackcdn.com', @@ -52,8 +57,6 @@ public function setupObjects() 'X-Trans-Id' => 'tx82a6752e00424edb9c46fa2573132e2c' )); - $this->addMockSubscriber($response2); - - $this->container = $this->service->getContainer('foo'); + $this->addMockSubscriber($response); } -} +} diff --git a/tests/OpenCloud/Tests/ObjectStore/Resource/ContainerTest.php b/tests/OpenCloud/Tests/ObjectStore/Resource/ContainerTest.php index 8dfd1da5f..2b02418a0 100644 --- a/tests/OpenCloud/Tests/ObjectStore/Resource/ContainerTest.php +++ b/tests/OpenCloud/Tests/ObjectStore/Resource/ContainerTest.php @@ -20,6 +20,7 @@ use Guzzle\Http\Message\Response; use OpenCloud\Common\Constants\Size; use OpenCloud\Tests\ObjectStore\ObjectStoreTestCase; +use OpenCloud\ObjectStore\Enum\ReturnType; class ContainerTest extends ObjectStoreTestCase { @@ -50,6 +51,8 @@ public function test_Get_Container() $this->assertEquals('3846773', $container->getBytesUsed()); $this->assertFalse($container->hasLogRetention()); + $this->setupCdnContainerMockResponse(); + $cdn = $container->getCdn(); $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\CDNContainer', $cdn); $this->assertEquals('tx82a6752e00424edb9c46fa2573132e2c', $cdn->getTransId()); @@ -97,7 +100,10 @@ public function test_NonCDN_Container() public function test_Delete() { $container = $this->container; + + $this->addMockSubscriber(new Response(204, array('X-Container-Object-Count' => 5))); $this->addMockSubscriber($this->makeResponse('[]', 200)); + $response = $container->delete(true); $this->isResponse($response); } @@ -111,13 +117,40 @@ public function test_Delete_NonEmpty_Container() $this->addMockSubscriber($this->makeResponse('[]', 409)); $container->delete(); } + + public function test_Delete_Object() + { + $container = $this->container; + $this->addMockSubscriber($this->makeResponse('[]', 204)); + $container->deleteObject("someObject"); + } + + /** + * @expectedException \Guzzle\Http\Exception\BadResponseException + */ + public function test_Delete_Object_With_Failure() + { + $container = $this->container; + $this->addMockSubscriber($this->makeResponse('[]', 500)); + $container->deleteObject("someObject"); + } + + /** + * @expectedException \Guzzle\Http\Exception\BadResponseException + */ + public function test_Delete_NonExisting_Object() + { + $container = $this->container; + $this->addMockSubscriber($this->makeResponse('[]', 404)); + $container->deleteObject("someObject"); + } + public function test_Object_List() { $container = $this->container; $this->addMockSubscriber($this->makeResponse('[{"name":"test_obj_1","hash":"4281c348eaf83e70ddce0e07221c3d28","bytes":14,"content_type":"application\/octet-stream","last_modified":"2009-02-03T05:26:32.612278"},{"name":"test_obj_2","hash":"b039efe731ad111bc1b0ef221c3849d0","bytes":64,"content_type":"application\/octet-stream","last_modified":"2009-02-03T05:26:32.612278"}]', 200)); - $list = $container->objectList(); $this->assertInstanceOf(self::COLLECTION_CLASS, $list); $this->assertEquals('test_obj_1', $list->first()->getName()); @@ -137,6 +170,8 @@ public function test_Misc_Operations() $container->disableLogging() ); + $this->setupCdnContainerMockResponse(); + $this->assertInstanceOf( 'Guzzle\Http\Message\Response', $container->getCdn()->setStaticIndexPage('index.html') @@ -222,6 +257,39 @@ public function test_Upload_Multiple() )); } + public function test_Upload_Multiple_Return_DataObject_Array() + { + $tempFileName = tempnam(sys_get_temp_dir(), "php-opencloud-test-"); + + $tempFile = fopen($tempFileName, 'w+'); + fwrite($tempFile, 'BAZQUX'); + + $container = $this->container; + + $dataObjects = $container->uploadObjects(array( + array('name' => 'test1', 'body' => 'FOOBAR'), + array('name' => 'test2', 'path' => $tempFileName), + array('name' => 'test2', 'body' => 'BARBAR') + ), array(), ReturnType::DATA_OBJECT_ARRAY); + fclose($tempFile); + unlink($tempFileName); + + $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\DataObject', $dataObjects[0]); + $this->assertEquals('test1', $dataObjects[0]->getName()); + $this->assertInstanceOf('Guzzle\Http\EntityBody', $dataObjects[0]->getContent()); + $this->assertEquals('FOOBAR', (string) $dataObjects[0]->getContent()); + + $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\DataObject', $dataObjects[1]); + $this->assertEquals('test2', $dataObjects[1]->getName()); + $this->assertInstanceOf('Guzzle\Http\EntityBody', $dataObjects[1]->getContent()); + $this->assertEquals('BAZQUX', (string) $dataObjects[1]->getContent()); + + $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\DataObject', $dataObjects[2]); + $this->assertEquals('test2', $dataObjects[2]->getName()); + $this->assertInstanceOf('Guzzle\Http\EntityBody', $dataObjects[2]->getContent()); + $this->assertEquals('BARBAR', (string) $dataObjects[2]->getContent()); + } + public function test_Upload() { $this->assertInstanceOf( diff --git a/tests/OpenCloud/Tests/ObjectStore/Resource/DataObjectTest.php b/tests/OpenCloud/Tests/ObjectStore/Resource/DataObjectTest.php index 343a3ae4c..5aee9cd81 100644 --- a/tests/OpenCloud/Tests/ObjectStore/Resource/DataObjectTest.php +++ b/tests/OpenCloud/Tests/ObjectStore/Resource/DataObjectTest.php @@ -17,12 +17,15 @@ namespace OpenCloud\Tests\ObjectStore\Resource; +use Guzzle\Http\Message\Response; +use OpenCloud\Common\Constants\Header; use OpenCloud\ObjectStore\Constants\UrlType; +use OpenCloud\ObjectStore\Exception\ObjectNotEmptyException; +use OpenCloud\Tests\MockSubscriber; use OpenCloud\Tests\ObjectStore\ObjectStoreTestCase; class DataObjectTest extends ObjectStoreTestCase { - public function test_Pseudo_Dirs() { $this->addMockSubscriber($this->makeResponse('[{"subdir": "foo"}]')); @@ -69,7 +72,7 @@ public function test_Copy() } /** - * @expectedException OpenCloud\Common\Exceptions\NoNameError + * @expectedException \OpenCloud\Common\Exceptions\NoNameError */ public function test_Copy_Fails() { @@ -77,16 +80,46 @@ public function test_Copy_Fails() } /** - * @expectedException OpenCloud\Common\Exceptions\InvalidArgumentError + * @expectedException \OpenCloud\Common\Exceptions\InvalidArgumentError */ public function test_Temp_Url_Fails_With_Incorrect_Method() { $this->container->dataObject('foobar')->getTemporaryUrl(1000, 'DELETE'); } + public function test_Temp_Url_Inherits_Url_Type() + { + $service = $this->getClient()->objectStoreService(null, 'IAD', 'internalURL'); + $object = $service->getContainer('foo')->dataObject('bar'); + + $this->addMockSubscriber(new Response(204, ['X-Account-Meta-Temp-URL-Key' => 'secret'])); + + $tempUrl = $object->getTemporaryUrl(60, 'GET'); + + // Check that internal URLs are used + $this->assertContains('snet-storage', $tempUrl); + } + + public function test_temp_urls_can_be_forced_to_use_public_urls() + { + $service = $this->getClient()->objectStoreService(null, 'IAD', 'internalURL'); + $object = $service->getContainer('foo')->dataObject('bar'); + + $this->addMockSubscriber(new Response(204, ['X-Account-Meta-Temp-URL-Key' => 'secret'])); + + $tempUrl = $object->getTemporaryUrl(60, 'GET', true); + + // Check that internal URLs are NOT used + $this->assertNotContains('snet-storage', $tempUrl); + + // Check that the URL contains the required file path + $this->assertContains('/foo/bar', $tempUrl); + } + public function test_Purge() { $object = $this->container->dataObject('foobar'); + $this->setupCdnContainerMockResponse(); $this->assertInstanceOf( 'Guzzle\Http\Message\Response', $object->purge('test@example.com') @@ -97,9 +130,88 @@ public function test_Public_Urls() { $object = $this->container->dataObject('foobar'); + $this->setupCdnContainerMockResponse(); $this->assertNotNull($object->getPublicUrl()); $this->assertNotNull($object->getPublicUrl(UrlType::SSL)); $this->assertNotNull($object->getPublicUrl(UrlType::STREAMING)); $this->assertNotNull($object->getPublicUrl(UrlType::IOS_STREAMING)); } + + public function test_Symlink_To() + { + $targetName = 'new_container/new_object'; + $this->addMockSubscriber(new Response(200, array(Header::X_OBJECT_MANIFEST => $targetName))); + $object = $this->container->dataObject('foobar'); + $this->assertInstanceOf('Guzzle\Http\Message\Response', $object->createSymlinkTo($targetName)); + $this->assertEquals($targetName, $object->getManifest()); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\NoNameError + */ + public function test_Symlink_To_Fails_With_NoName() + { + $object = $this->container->dataObject()->createSymlinkTo(null); + } + + /** + * @expectedException OpenCloud\ObjectStore\Exception\ObjectNotEmptyException + */ + public function test_Symlink_To_Fails_With_NotEmpty() + { + $this->addMockSubscriber(new Response(200, array(Header::CONTENT_LENGTH => 100))); + $object = $this->container->dataObject('foobar')->createSymlinkTo('new_container/new_object'); + } + + public function test_Symlink_From() + { + $symlinkName = 'new_container/new_object'; + + // We have to fill the mock response queue to properly get the correct X-Object-Manifest header + // Container\dataObject( ) + // - Container\refresh( ) + $this->addMockSubscriber(new Response(200)); + // DataObject\createSymlinkFrom( ) + // - Container\createRefreshRequest( ) + $this->addMockSubscriber(new Response(200)); + // - CDNContainer\createRefreshRequest( ) + $this->addMockSubscriber(new Response(200)); + // - Container\objectExists( ) + $this->addMockSubscriber(new Response(200)); + // - Container\getPartialObject( ) + $this->addMockSubscriber(new Response(200)); + // - Container\uploadObject( ) + $this->addMockSubscriber(new Response(200, array(Header::X_OBJECT_MANIFEST => $symlinkName))); + + $object = $this->container->dataObject('foobar')->createSymlinkFrom($symlinkName); + $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\DataObject', $object); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\NoNameError + */ + public function test_Symlink_From_Fails_With_NoName() + { + $object = $this->container->dataObject()->createSymlinkFrom(null); + } + + /** + * @expectedException OpenCloud\ObjectStore\Exception\ObjectNotEmptyException + */ + public function test_Symlink_From_Fails_With_NotEmpty() + { + // We have to fill the mock response queue to properly get the correct Content-Length header + // Container\dataObject( ) + // - Container\refresh( ) + $this->addMockSubscriber(new Response(200)); + // DataObject\createSymlinkFrom( ) + // - Container\createRefreshRequest( ) + $this->addMockSubscriber(new Response(200)); + // - Container\objectExists( ) + $this->addMockSubscriber(new Response(200)); + // - Container\getPartialObject( ) + $this->addMockSubscriber(new Response(200, array(Header::CONTENT_LENGTH => 100))); + + $object = $this->container->dataObject('foobar')->createSymlinkFrom('new_container/new_object'); + } } diff --git a/tests/OpenCloud/Tests/ObjectStore/Resource/TransferTest.php b/tests/OpenCloud/Tests/ObjectStore/Resource/TransferTest.php index 14349ab75..cf08b8aea 100644 --- a/tests/OpenCloud/Tests/ObjectStore/Resource/TransferTest.php +++ b/tests/OpenCloud/Tests/ObjectStore/Resource/TransferTest.php @@ -23,7 +23,6 @@ class TransferTest extends ObjectStoreTestCase { - public function test_Consecutive_Transfer() { $options = array('objectName' => 'NEW_OBJECT'); diff --git a/tests/OpenCloud/Tests/ObjectStore/ServiceTest.php b/tests/OpenCloud/Tests/ObjectStore/ServiceTest.php index 232391bcc..f5f371f22 100644 --- a/tests/OpenCloud/Tests/ObjectStore/ServiceTest.php +++ b/tests/OpenCloud/Tests/ObjectStore/ServiceTest.php @@ -25,12 +25,12 @@ */ namespace OpenCloud\Tests\ObjectStore; +use Guzzle\Http\Message\Response; use OpenCloud\ObjectStore\Constants\UrlType; use OpenCloud\ObjectStore\Service; class ServiceTest extends ObjectStoreTestCase { - public function test__construct() { $service = $this->getClient()->objectStoreService('cloudFiles', 'DFW'); @@ -99,6 +99,48 @@ public function test_Bad_Container_Name_Long() $this->service->createContainer(str_repeat('a', Service::MAX_CONTAINER_NAME_LENGTH + 1)); } + /** + * @expectedException OpenCloud\Common\Exceptions\InvalidArgumentError + */ + public function test_Get_Bad_Container_Name_Empty() + { + $this->service->getContainer(''); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\InvalidArgumentError + */ + public function test_Get_Bad_Container_Name_Slashes() + { + $this->service->getContainer('foo/bar'); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\InvalidArgumentError + */ + public function test_Get_Bad_Container_Name_Long() + { + $this->service->getContainer(str_repeat('a', Service::MAX_CONTAINER_NAME_LENGTH + 1)); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\InvalidArgumentError + */ + public function test_Get_Bad_Container_Name_Float() + { + $this->service->getContainer(4.5); + } + + public function test_Get_Container_String() + { + $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\Container', $this->service->getContainer('foo')); + } + + public function test_Get_Container_Integer() + { + $this->assertInstanceOf('OpenCloud\ObjectStore\Resource\Container', $this->service->getContainer(1)); + } + public function test_Bulk_Extract() { $response = $this->service->bulkExtract('fooBarContainer', 'CONTENT', UrlType::TAR); @@ -138,6 +180,19 @@ public function test_Bad_Bulk_Delete() $this->service->bulkDelete(array('nonEmptyContainer')); } + public function test_Batch_Delete_Returns_Array_Of_Responses() + { + $responses = array_fill(0, 2, new Response(200)); + + foreach ($responses as $response) { + $this->addMockSubscriber($response); + } + + $paths = array_fill(0, 15000, '/foo/bar'); + + $this->assertEquals($responses, $this->service->batchDelete($paths)); + } + public function test_Accounts() { $account = $this->service->getAccount(); diff --git a/tests/OpenCloud/Tests/ObjectStore/Upload/DirectorySyncTest.php b/tests/OpenCloud/Tests/ObjectStore/Upload/DirectorySyncTest.php new file mode 100644 index 000000000..b95ad2ea9 --- /dev/null +++ b/tests/OpenCloud/Tests/ObjectStore/Upload/DirectorySyncTest.php @@ -0,0 +1,78 @@ +prophet = new Prophet(); + } + + public function test_it_uploads_to_a_container() + { + $baseUrl = 'foo.com/bar'; + + $containerMock = $this->prophet->prophesize('OpenCloud\ObjectStore\Resource\Container'); + $iteratorMock = $this->prophet->prophesize('OpenCloud\Common\Collection\PaginatedIterator'); + + $iteratorMock->rewind()->shouldBeCalled(); + $iteratorMock->populateAll()->shouldBeCalled(); + $iteratorMock->valid()->willReturn(false); + $iteratorMock->search(Argument::type('callable'))->willReturn(false); + + $containerMock->getUrl()->willReturn(Url::factory($baseUrl)); + + $guzzleMock = $this->prophet->prophesize('Guzzle\Http\Client'); + + $guzzleMock->put($baseUrl . '/test1', [], Argument::type('Guzzle\Http\EntityBody'))->shouldBeCalled(); + $guzzleMock->send(Argument::that(function ($array) { return count($array) === 1; }))->shouldBeCalled(); + + $containerMock->getClient()->willReturn($guzzleMock->reveal()); + + $sync = new DirectorySync(); + $sync->setBasePath(__DIR__ . '/fixtures'); + $sync->setContainer($containerMock->reveal()); + $sync->setRemoteFiles($iteratorMock->reveal()); + + $sync->execute(); + } + + public function test_it_uploads_to_a_nested_sub_dir_in_a_container() + { + $baseUrl = 'foo.com/bar'; + + $containerMock = $this->prophet->prophesize('OpenCloud\ObjectStore\Resource\Container'); + $iteratorMock = $this->prophet->prophesize('OpenCloud\Common\Collection\PaginatedIterator'); + + $iteratorMock->rewind()->shouldBeCalled(); + $iteratorMock->populateAll()->shouldBeCalled(); + $iteratorMock->valid()->willReturn(false); + $iteratorMock->search(Argument::type('callable'))->willReturn(false); + + $containerMock->getUrl()->willReturn(Url::factory($baseUrl)); + + $guzzleMock = $this->prophet->prophesize('Guzzle\Http\Client'); + + $guzzleMock->put($baseUrl . '/sub-dir/test1', [], Argument::type('Guzzle\Http\EntityBody'))->shouldBeCalled(); + $guzzleMock->send(Argument::that(function ($array) { return count($array) === 1; }))->shouldBeCalled(); + + $containerMock->getClient()->willReturn($guzzleMock->reveal()); + + $sync = new DirectorySync(); + $sync->setBasePath(__DIR__ . '/fixtures'); + $sync->setContainer($containerMock->reveal()); + $sync->setRemoteFiles($iteratorMock->reveal()); + $sync->setTargetDir('sub-dir'); + + $sync->execute(); + } +} diff --git a/docs/userguide/DNS/Subdomains.md b/tests/OpenCloud/Tests/ObjectStore/Upload/fixtures/test1 similarity index 100% rename from docs/userguide/DNS/Subdomains.md rename to tests/OpenCloud/Tests/ObjectStore/Upload/fixtures/test1 diff --git a/tests/OpenCloud/Tests/OpenCloudTestCase.php b/tests/OpenCloud/Tests/OpenCloudTestCase.php index 04d60a716..8d7582c1f 100644 --- a/tests/OpenCloud/Tests/OpenCloudTestCase.php +++ b/tests/OpenCloud/Tests/OpenCloudTestCase.php @@ -38,17 +38,10 @@ abstract class OpenCloudTestCase extends \PHPUnit_Framework_TestCase public function newClient() { - $client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( + return new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array( 'username' => 'foo', 'apiKey' => 'bar' )); - - $client->addSubscriber(new MockSubscriber()); - //$client->addSubscriber(LogPlugin::getDebugPlugin()); - - $client->authenticate(); - - return $client; } public function getClient() @@ -59,6 +52,10 @@ public function getClient() public function setUp() { $this->client = $this->newClient(); + + $this->client->addSubscriber(new MockSubscriber()); + $this->client->authenticate(); + $this->setupObjects(); $this->handleMockSubscribers(); } @@ -124,4 +121,22 @@ public function isCollection($object) { $this->assertInstanceOf(self::COLLECTION_CLASS, $object); } + + /** + * Call protected/private method of a class. + * + * @param object &$object Instantiated object that we will run method on. + * @param string $methodName Method name to call + * @param array $parameters Array of parameters to pass into method. + * + * @return mixed Method return. + */ + public function invokeMethod(&$object, $methodName, array $parameters = array()) + { + $reflection = new \ReflectionClass(get_class($object)); + $method = $reflection->getMethod($methodName); + $method->setAccessible(true); + + return $method->invokeArgs($object, $parameters); + } } diff --git a/tests/OpenCloud/Tests/OpenStackTest.php b/tests/OpenCloud/Tests/OpenStackTest.php index a2e6f9bf3..8ff20892a 100644 --- a/tests/OpenCloud/Tests/OpenStackTest.php +++ b/tests/OpenCloud/Tests/OpenStackTest.php @@ -184,4 +184,39 @@ public function test_Import_Credentials_Numeric_Tenant() $this->assertEquals('{expiration}', $this->client->getExpiration()); $this->assertEquals($randomNumericTenant, $this->client->getTenant()); } -} \ No newline at end of file + + public function testLoggerServiceInjection() + { + // Create a new client, pass stub via constructor options argument + $stubLogger = $this->getMock('Psr\Log\NullLogger'); + $client = new OpenStack(Rackspace::US_IDENTITY_ENDPOINT, $this->credentials, array( + 'logger' => $stubLogger, + )); + $client->addSubscriber(new MockSubscriber()); + + // Test all OpenStack factory methods on proper Logger service injection + $service = $client->objectStoreService('cloudFiles', 'DFW'); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $service->getCdnService(); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $client->computeService('cloudServersOpenStack', 'DFW'); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $client->orchestrationService(null, 'DFW'); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $client->volumeService('cloudBlockStorage', 'DFW'); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $client->identityService(); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $client->imageService('cloudImages', 'IAD'); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + + $service = $client->networkingService(null, 'IAD'); + $this->assertContains("Mock_NullLogger", get_class($service->getLogger())); + } +} diff --git a/tests/OpenCloud/Tests/Orchestration/OrchestrationTestCase.php b/tests/OpenCloud/Tests/Orchestration/OrchestrationTestCase.php new file mode 100644 index 000000000..6bca04448 --- /dev/null +++ b/tests/OpenCloud/Tests/Orchestration/OrchestrationTestCase.php @@ -0,0 +1,77 @@ +service = $this->getClient()->orchestrationService(); + + $this->addMockSubscriber($this->makeResponse('{"engine":{"revision":"2014.j3-20141003-1139"},"fusion-api":{"revision":"j1-20140915-10d9ee4-98"},"api":{"revision":"2014.j3-20141003-1139"}}')); + $this->buildInfo = $this->service->getBuildInfo(); + + $this->addMockSubscriber($this->makeResponse('{"attributes":{"an_attribute":{"description":"An attribute description ."}},"properties":{"a_property":{"update_allowed":false,"required":true,"type":"string","description":"A resource description."}},"resource_type":"OS::Nova::Server"}')); + $this->resourceType = $this->service->getResourceType("OS::Nova::Server"); + + $this->addMockSubscriber($this->makeResponse('{"stack":{"capabilities":[],"creation_time":"2014-06-03T20:59:46Z","description":"sample stack","disable_rollback":"True","id":"3095aefc-09fb-4bc7-b1f0-f21a304e864c","links":[{"href":"http://192.168.123.200:8004/v1/eb1c63a4f77141548385f113a28f0f52/stacks/simple_stack/3095aefc-09fb-4bc7-b1f0-f21a304e864c","rel":"self"}],"notification_topics":[],"outputs":[],"parameters":{"OS::stack_id":"3095aefc-09fb-4bc7-b1f0-f21a304e864c","OS::stack_name":"simple_stack"},"stack_name":"simple_stack","stack_status":"CREATE_COMPLETE","stack_status_reason":"Stack CREATE completed successfully","template_description":"sample stack","timeout_mins":"","updated_time":""}}')); + $this->stack = $this->service->getStack('simple_stack'); + + $this->addMockSubscriber($this->makeResponse('{"resource":{"resource_name":"MySqlCloudDatabaseServer","description":"","links":[{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxxx21-9xx9-4xxxe-bxxf-a7fxxxxx68/resources/MySqlCloudDatabaseServer","rel":"self"},{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxxx1-9xx9-4xxe-bxxf-a7fxxxxxx68","rel":"stack"}],"logical_resource_id":"MySqlCloudDatabaseServer","resource_status":"CREATE_COMPLETE","updated_time":"2014-02-05T19:20:31Z","required_by":[],"resource_status_reason":"state changed","physical_resource_id":"98xxx0-cxx8-4xxe-bxx5-3fxxxx11","resource_type":"OS::Trove::Instance"}}')); + $this->resource = $this->stack->getResource('MySqlCloudDatabaseServer'); + } + + protected function assertIsService($object) + { + $this->assertInstanceOf('OpenCloud\Orchestration\Service', $object); + } + + protected function assertIsBuildInfo($object) + { + $this->assertInstanceOf('OpenCloud\Orchestration\Resource\BuildInfo', $object); + } + + protected function assertIsEvent($object) + { + $this->assertInstanceOf('OpenCloud\Orchestration\Resource\Event', $object); + } + + protected function assertIsResource($object) + { + $this->assertInstanceOf('OpenCloud\Orchestration\Resource\Resource', $object); + } + + protected function assertIsResourceType($object) + { + $this->assertInstanceOf('OpenCloud\Orchestration\Resource\ResourceType', $object); + } + + protected function assertIsStack($object) + { + $this->assertInstanceOf('OpenCloud\Orchestration\Resource\Stack', $object); + } +} diff --git a/tests/OpenCloud/Tests/Orchestration/Resource/BuildInfoTest.php b/tests/OpenCloud/Tests/Orchestration/Resource/BuildInfoTest.php new file mode 100644 index 000000000..9c990af14 --- /dev/null +++ b/tests/OpenCloud/Tests/Orchestration/Resource/BuildInfoTest.php @@ -0,0 +1,48 @@ +buildInfo->create(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\UpdateError + */ + public function testCannotUpdate() + { + $this->buildInfo->update(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\DeleteError + */ + public function testCannotDelete() + { + $this->buildInfo->delete(); + } +} diff --git a/tests/OpenCloud/Tests/Orchestration/Resource/ResourceTest.php b/tests/OpenCloud/Tests/Orchestration/Resource/ResourceTest.php new file mode 100644 index 000000000..6b34a2997 --- /dev/null +++ b/tests/OpenCloud/Tests/Orchestration/Resource/ResourceTest.php @@ -0,0 +1,75 @@ +resource->create(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\UpdateError + */ + public function testCannotUpdate() + { + $this->resource->update(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\DeleteError + */ + public function testCannotDelete() + { + $this->resource->delete(); + } + + public function testGetMetadata() + { + $this->addMockSubscriber($this->makeResponse('{"metadata":{"foo":"bar","baz":17}}')); + $metadata = $this->resource->getMetadata(); + $this->assertEquals("bar", $metadata->foo); + } + + public function testListEvents() + { + $this->addMockSubscriber($this->makeResponse('{"events":[{"resource_name":"mysql_server","event_time":"2014-07-23T08:14:47Z","links":[{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server/events/474bfdf0-a450-46ec-a78a-0c7faa404073","rel":"self"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server","rel":"resource"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5","rel":"stack"}],"logical_resource_id":"mysql_server","resource_status":"CREATE_FAILED","resource_status_reason":"NotFound: Subnet f8a699d0-3537-429e-87a5-6b5a8d0c2bf0 could not be found","physical_resource_id":null,"id":"474bfdf0-a450-46ec-a78a-0c7faa404073"},{"resource_name":"mysql_server","event_time":"2014-07-23T08:14:47Z","links":[{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server/events/66fa95b6-e6f8-4f05-b1af-e828f5aba04c","rel":"self"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server","rel":"resource"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5","rel":"stack"}],"logical_resource_id":"mysql_server","resource_status":"CREATE_IN_PROGRESS","resource_status_reason":"state changed","physical_resource_id":null,"id":"66fa95b6-e6f8-4f05-b1af-e828f5aba04c"}]}')); + + $events = $this->resource->listEvents(); + $this->isCollection($events); + + $firstEvent = $events->getElement(0); + $this->assertIsEvent($firstEvent); + $this->assertEquals('474bfdf0-a450-46ec-a78a-0c7faa404073', $firstEvent->getId()); + } + + public function testGetEvent() + { + $this->addMockSubscriber($this->makeResponse('{"event":{"event_time":"2014-01-31T20:08:15Z","id":"f4874455-6505-42b4-af84-114bba2483a5","links":[{"href":"http://hostname/v1/1234/stacks/mystack/56789/resources/lb/events/f4874455-6505-42b4-af84-114bba2483a5","rel":"self"},{"href":"http://hostname/v1/1234/stacks/mystack/56789/resources/lb","rel":"resource"},{"href":"http://hostname/v1/1234/stacks/mystack/56789","rel":"stack"}],"logical_resource_id":"lb","physical_resource_id":"098765","resource_name":"lb","resource_properties":{"accessList":null,"algorithm":"LEAST_CONNECTIONS","connectionLogging":null,"connectionThrottle":{"maxConnectionRate":50,"maxConnections":50,"minConnections":50,"rateInterval":50},"contentCaching":"ENABLED","errorPage":null,"halfClosed":false,"healthMonitor":{"attemptsBeforeDeactivation":3,"bodyRegex":".","delay":10,"hostHeader":null,"path":"/","statusRegex":".","timeout":10,"type":"HTTP"},"metadata":null,"name":"lb-Wordpress Webserver","nodes":[{"addresses":["1.2.3.4","4.5.6.7"],"condition":"ENABLED","port":80,"type":null,"weight":null}],"port":80,"protocol":"HTTP","sessionPersistence":"HTTP_COOKIE","sslTermination":null,"timeout":120,"virtualIps":[{"ipVersion":"IPV4","type":"PUBLIC"}]},"resource_status":"CREATE_COMPLETE","resource_status_reason":"state changed","resource_type":"Rackspace::Cloud::LoadBalancer"}}')); + + $event = $this->resource->getEvent('f4874455-6505-42b4-af84-114bba2483a5'); + $this->assertEquals('Rackspace::Cloud::LoadBalancer', $event->getResourceType()); + } +} diff --git a/tests/OpenCloud/Tests/Orchestration/Resource/ResourceTypeTest.php b/tests/OpenCloud/Tests/Orchestration/Resource/ResourceTypeTest.php new file mode 100644 index 000000000..0261beb9c --- /dev/null +++ b/tests/OpenCloud/Tests/Orchestration/Resource/ResourceTypeTest.php @@ -0,0 +1,56 @@ +resourceType->create(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\UpdateError + */ + public function testCannotUpdate() + { + $this->resourceType->update(); + } + + /** + * @expectedException OpenCloud\Common\Exceptions\DeleteError + */ + public function testCannotDelete() + { + $this->resourceType->delete(); + } + + public function testGetTemplate() + { + $template = '{"HeatTemplateFormatVersion":"2012-12-12","Outputs":{"private_key":{"Description":"The private key if it has been saved.","Value":"{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}"},"public_key":{"Description":"The public key.","Value":"{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}"}},"Parameters":{"name":{"Description":"The name of the key pair.","Type":"String"},"public_key":{"Description":"The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.","Type":"String"},"save_private_key":{"AllowedValues":["True","true","False","false"],"Default":false,"Description":"True if the system should remember a generated private key; False otherwise.","Type":"String"}},"Resources":{"KeyPair":{"Properties":{"name":{"Ref":"name"},"public_key":{"Ref":"public_key"},"save_private_key":{"Ref":"save_private_key"}},"Type":"OS::Nova::KeyPair"}}}'; + $this->addMockSubscriber($this->makeResponse($template)); + + $this->assertEquals($template, $this->resourceType->getTemplate()); + } +} diff --git a/tests/OpenCloud/Tests/Orchestration/Resource/StackTest.php b/tests/OpenCloud/Tests/Orchestration/Resource/StackTest.php new file mode 100644 index 000000000..3c05e7735 --- /dev/null +++ b/tests/OpenCloud/Tests/Orchestration/Resource/StackTest.php @@ -0,0 +1,149 @@ + 'foobar', + 'templateUrl' => 'https://github.com/ycombinator/drupal-multi/template.yml', + 'parameters' => array( + 'flavor_id' => 'general1-1', + 'db_name' => 'drupaldb', + 'db_user' => 'drupaldbuser' + ), + 'timeoutMins' => 5 + ); + + $stack = new PublicStack($this->service); + $stack->create($createParams); + $createJson = $stack->createJson(); + + $expectedObj = (object) array( + 'stack_name' => 'foobar', + 'template_url' => 'https://github.com/ycombinator/drupal-multi/template.yml', + 'parameters' => array( + 'flavor_id' => 'general1-1', + 'db_name' => 'drupaldb', + 'db_user' => 'drupaldbuser' + ), + 'timeout_mins' => 5 + ); + + $this->assertEquals($expectedObj, $createJson); + } + + public function testUpdateJson() + { + $updateParams = array( + 'templateUrl' => 'https://github.com/ycombinator/drupal-multi/template.yml', + 'parameters' => array( + 'flavor_id' => 'general1-1', + 'db_name' => 'drupaldb', + 'db_user' => 'drupalwebuser' + ), + 'timeoutMins' => 10 + ); + + $stack = new PublicStack($this->service); + $stack->update($updateParams); + $updateJson = $stack->updateJson(); + + $expectedObj = (object) array( + 'template_url' => 'https://github.com/ycombinator/drupal-multi/template.yml', + 'parameters' => array( + 'flavor_id' => 'general1-1', + 'db_name' => 'drupaldb', + 'db_user' => 'drupalwebuser' + ), + 'timeout_mins' => 10 + ); + + $this->assertEquals($expectedObj, $updateJson); + } + + public function testAbandonStack() + { + $expectedAbandonStackData = '{"status":"COMPLETE","name":"g","dry_run":true,"template":{"outputs":{"instance_ip":{"value":{"str_replace":{"params":{"username":"ec2-user","hostname":{"get_attr":["server","first_address"]}},"template":"ssh username@hostname"}}}},"heat_template_version":"2013-05-23","resources":{"server":{"type":"OS::Nova::Server","properties":{"key_name":{"get_param":"key_name"},"image":{"get_param":"image"},"flavor":{"get_param":"flavor"}}}},"parameters":{"key_name":{"default":"heat_key","type":"string"},"image":{"default":"Ubuntu 12.04 LTS (Precise Pangolin)","type":"string"},"flavor":{"default":"1 GB Performance","type":"string"}}},"action":"CREATE","id":"16934ca3-40e0-4fb2-a289-a700662ec05a","resources":{"server":{"status":"COMPLETE","name":"server","resource_data":{},"resource_id":"39d5dad7-7d7a-4cc8-bd84-851e9e2ff4ea","action":"CREATE","type":"OS::Nova::Server","metadata":{}}}}'; + $this->addMockSubscriber($this->makeResponse($expectedAbandonStackData)); + + $actualAbandonStackData = $this->stack->abandon(); + $this->assertEquals($expectedAbandonStackData, $actualAbandonStackData); + } + + public function testListResources() + { + $this->addMockSubscriber($this->makeResponse('{"resources":[{"resource_name":"MySqlCloudDatabaseServer","links":[{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxxx1-9xx9-4xxe-bxxf-a7xxxxxd99068/resources/MySqlCloudDatabaseServer","rel":"self"},{"href":"http:s//dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxxx1-9xx9-4xxe-bxxf-a7xxxxx068","rel":"stack"}],"logical_resource_id":"MySqlCloudDatabaseServer","resource_status_reason":"state changed","updated_time":"2014-02-05T19:20:31Z","required_by":[],"resource_status":"CREATE_COMPLETE","physical_resource_id":"984xxxxxe0-c7x8-4x6e-be15-3f0xxxxx711","resource_type":"OS::Trove::Instance"}]}')); + + $resources = $this->stack->listResources(); + $this->isCollection($resources); + + $firstResource = $resources->getElement(0); + $this->assertIsResource($firstResource); + $this->assertEquals('MySqlCloudDatabaseServer', $firstResource->getName()); + } + + public function testGetResource() + { + $this->addMockSubscriber($this->makeResponse('{"resource":{"resource_name":"MySqlCloudDatabaseServer","description":"A MySQL DB instance","links":[{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxxx21-9xx9-4xxxe-bxxf-a7fxxxxx68/resources/MySqlCloudDatabaseServer","rel":"self"},{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxxx1-9xx9-4xxe-bxxf-a7fxxxxxx68","rel":"stack"}],"logical_resource_id":"MySqlCloudDatabaseServer","resource_status":"CREATE_COMPLETE","updated_time":"2014-02-05T19:20:31Z","required_by":[],"resource_status_reason":"state changed","physical_resource_id":"98xxx0-cxx8-4xxe-bxx5-3fxxxx11","resource_type":"OS::Trove::Instance"}}')); + + $resource = $this->stack->getResource('MySqlCloudDatabaseServer'); + $this->assertIsResource($resource); + $this->assertEquals('A MySQL DB instance', $resource->getDescription()); + } + + public function testListEvents() + { + $this->addMockSubscriber($this->makeResponse('{"events":[{"resource_name":"mysql_server","event_time":"2014-07-23T08:14:47Z","links":[{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server/events/474bfdf0-a450-46ec-a78a-0c7faa404073","rel":"self"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server","rel":"resource"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5","rel":"stack"}],"logical_resource_id":"mysql_server","resource_status":"CREATE_FAILED","resource_status_reason":"NotFound: Subnet f8a699d0-3537-429e-87a5-6b5a8d0c2bf0 could not be found","physical_resource_id":null,"id":"474bfdf0-a450-46ec-a78a-0c7faa404073"},{"resource_name":"mysql_server","event_time":"2014-07-23T08:14:47Z","links":[{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server/events/66fa95b6-e6f8-4f05-b1af-e828f5aba04c","rel":"self"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5/resources/mysql_server","rel":"resource"},{"href":"http://192.168.123.200:8004/v1/dc4b074874244f7693dd65583733a758/stacks/teststack/db467ed1-50b5-4a3e-aeb1-396ff1d151c5","rel":"stack"}],"logical_resource_id":"mysql_server","resource_status":"CREATE_IN_PROGRESS","resource_status_reason":"state changed","physical_resource_id":null,"id":"66fa95b6-e6f8-4f05-b1af-e828f5aba04c"}]}')); + + $events = $this->stack->listEvents(); + $this->isCollection($events); + + $firstEvent = $events->getElement(0); + $this->assertIsEvent($firstEvent); + $this->assertEquals('474bfdf0-a450-46ec-a78a-0c7faa404073', $firstEvent->getId()); + } + + public function testGetTemplate() + { + $expectedTemplateStr = '{"description":"Heat Orchestration Template that spins up a single server","heat_template_version":"2013-05-23","parameters":{"compute_flavor":{"constraints":[{"allowed_values":["1 GB Performance","2 GB Performance","4 GB Performance","8 GB Performance","16 GB Performance"],"description":"Must be a valid Rackspace Cloud Server flavor."}],"default":"2 GB Performance","description":"flavor id for the compute instance","type":"String"},"compute_image":{"constraints":[{"allowed_values":["Ubuntu 13.10 (Saucy Salamander)","Ubuntu 12.10 (Quantal Quetzal)"],"description":"Must be a valid Rackspace Cloud Server image name."}],"default":"Ubuntu 13.10 (Saucy Salamander)","description":"The Image to use for the host OS.","type":"String"}},"resources":{"server_instance":{"type":"OS::Nova::Server","properties":{"flavor":{"get_param":"compute_flavor"},"image":{"get_param":"compute_image"},"name":"Single Node Compute Instance"}}}}'; + + $this->addMockSubscriber($this->makeResponse($expectedTemplateStr)); + + $actualTemplateStr = $this->stack->getStackTemplate(); + $this->assertEquals($expectedTemplateStr, $actualTemplateStr); + } +} diff --git a/tests/OpenCloud/Tests/Orchestration/ServiceTest.php b/tests/OpenCloud/Tests/Orchestration/ServiceTest.php new file mode 100644 index 000000000..b0f4ef95e --- /dev/null +++ b/tests/OpenCloud/Tests/Orchestration/ServiceTest.php @@ -0,0 +1,118 @@ +getClient()->orchestrationService(null, 'DFW'); + $this->assertIsService($service); + } + + public function testPreviewStack() + { + $this->assertIsStack($this->service->previewStack()); + } + + public function testCreateStack() + { + $this->assertIsStack($this->service->createStack()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testAdoptStackWithoutAdoptStackData() + { + $this->service->adoptStack(); + } + + public function testAdoptStackWithAdoptStackData() + { + $this->assertIsStack($this->service->adoptStack(array('adoptStackData' => 'foobar'))); + } + + public function testListStacks() + { + $this->addMockSubscriber($this->makeResponse('{"stacks":[{"description":"HEAT template for deploying a multi-node wordpress deployment on Rackspace Cloud\nusing Cloud Servers, Cloud Load Balancers and Cloud Databases. This version uses\na user-defined template resource to specify the implementation of the web-heads\n","links":[{"href":"http:\/\/xxxxx\/v1\/xxxx\/stacks\/xxxx\/11cd9b5e-c7ff-43b5-bff8-b0e7429cd87e","rel":"self"}],"stack_status_reason":"Resource suspend failed: Error: State invalid for suspend","stack_name":"timswp6","creation_time":"2014-01-30T20:47:57Z","updated_time":"2014-02-03T18:04:39Z","stack_status":"SUSPEND_FAILED","id":"11cd9b5e-c7ff-43b5-bff8-b0e7429cd87e"},{"description":"HEAT template for deploying a multi-node wordpress deployment on Rackspace Cloud\nusing Cloud Servers, Cloud Load Balancers and Cloud Databases. This version uses\na user-defined template resource to specify the implementation of the web-heads\n","links":[{"href":"http:\/\/xxxx\/v1\/xxxx\/stacks\/xxxx\/1b2ed5de-9b8c-43fa-9392-1da17b5dee7c","rel":"self"}],"stack_status_reason":"Stack create completed successfully","stack_name":"timswp5","creation_time":"2014-01-30T18:18:12Z","updated_time":"2014-01-30T18:42:07Z","stack_status":"CREATE_COMPLETE","id":"1b2ed5de-9b8c-43fa-9392-1da17b5dee7c"}]}')); + + $stacks = $this->service->listStacks(); + $this->isCollection($stacks); + $this->assertIsStack($stacks->getElement(0)); + } + + public function testGetStackByName() + { + $this->addMockSubscriber($this->makeResponse('{"stack":{"disable_rollback":true,"description":"MYSQL server cloud database instance running on Rackspace cloud","parameters":{"instance_name":"testdb","OS::stack_id":"87xxx21-9db9-49be-bc4f-a7f2exxxx68","OS::stack_name":"trove2"},"stack_status_reason":"Stack create completed successfully","stack_name":"trove2","outputs":[],"creation_time":"2014-02-05T19:18:56Z","links":[{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxx21-9db9-49be-bc4f-a7f2exxxx68","rel":"self"}],"capabilities":[],"notification_topics":[],"timeout_mins":60,"stack_status":"CREATE_COMPLETE","updated_time":"2014-02-05T19:20:31Z","id":"879xxx21-9db9-49be-bc4f-a7f2exxxx9068","template_description":"MYSQL server cloud database instance running on Rackspace cloud"}}')); + + $stack = $this->service->getStack('foobar'); + $this->assertIsStack($stack); + $this->assertEquals('MYSQL server cloud database instance running on Rackspace cloud', $stack->getDescription()); + } + + public function testGetStackByNameAndId() + { + $this->addMockSubscriber($this->makeResponse('{"stack":{"disable_rollback":true,"description":"MYSQL server cloud database instance running on Rackspace cloud","parameters":{"instance_name":"testdb","OS::stack_id":"87xxx21-9db9-49be-bc4f-a7f2exxxx68","OS::stack_name":"trove2"},"stack_status_reason":"Stack create completed successfully","stack_name":"trove2","outputs":[],"creation_time":"2014-02-05T19:18:56Z","links":[{"href":"https://dfw.orchestration.rackspacecloud.com/v1/tenant_id/stacks/trove2/87xxx21-9db9-49be-bc4f-a7f2exxxx68","rel":"self"}],"capabilities":[],"notification_topics":[],"timeout_mins":60,"stack_status":"CREATE_COMPLETE","updated_time":"2014-02-05T19:20:31Z","id":"879xxx21-9db9-49be-bc4f-a7f2exxxx9068","template_description":"MYSQL server cloud database instance running on Rackspace cloud"}}')); + + $stack = $this->service->getStack('foobar', 1234); + $this->assertIsStack($stack); + $this->assertEquals('MYSQL server cloud database instance running on Rackspace cloud', $stack->getDescription()); + } + + public function testListResourceTypes() + { + $this->addMockSubscriber($this->makeResponse('{"resource_types":["OS::Nova::Server","OS::Heat::RandomString","OS::Swift::Container","Rackspace::Cloud::Server","OS::Heat::ChefSolo","Rackspace::AutoScale::WebHook","Rackspace::AutoScale::Group","Rackspace::Cloud::Network","OS::Cinder::Volume","Rackspace::Cloud::WinServer","Rackspace::Cloud::LoadBalancer","OS::Heat::ResourceGroup","Rackspace::AutoScale::ScalingPolicy","Rackspace::Cloud::DNS","OS::Trove::Instance","OS::Nova::FloatingIPAssociation","OS::Cinder::VolumeAttachment","OS::Nova::FloatingIP","OS::Nova::KeyPair"]}')); + + $resourceTypes = $this->service->listResourceTypes(); + $this->isCollection($resourceTypes); + $this->assertIsResourceType($resourceTypes->getElement(0)); + } + + public function testGetResourceType() + { + $this->addMockSubscriber($this->makeResponse('{"attributes":{"an_attribute":{"description":"An attribute description ."}},"properties":{"a_property":{"update_allowed":false,"required":true,"type":"string","description":"A resource description."}},"resource_type":"OS::Nova::Server"}')); + + $resourceType = $this->service->getResourceType('OS::Nova::Server'); + $this->assertIsResourceType($resourceType); + $this->assertEquals('OS::Nova::Server', $resourceType->getResourceType()); + } + + public function testGetBuildInfo() + { + $this->addMockSubscriber($this->makeResponse('{"engine":{"revision":"2014.j3-20141003-1139"},"fusion-api":{"revision":"j1-20140915-10d9ee4-98"},"api":{"revision":"2014.j3-20141003-1139"}}')); + + $buildInfo = $this->service->getBuildInfo(); + $this->assertIsBuildInfo($buildInfo); + $this->assertEquals('2014.j3-20141003-1139', $buildInfo->getApi()->revision); + } + + public function testValidateInvalidTemplate() + { + $this->addMockSubscriber($this->makeResponse('{"explanation":"Template version not specified","code":400}', 400)); + try { + $this->service->validateTemplate(array('template' => 'foobar: baz')); + $this->fail("InvalidTemplateError exception should have been thrown!"); + } catch (InvalidTemplateError $e) { + $this->assertEquals("Template version not specified", $e->getMessage()); + } + } +} diff --git a/tests/OpenCloud/Tests/Queues/Resource/QueueTest.php b/tests/OpenCloud/Tests/Queues/Resource/QueueTest.php index ada7f0b26..5f8e4206d 100644 --- a/tests/OpenCloud/Tests/Queues/Resource/QueueTest.php +++ b/tests/OpenCloud/Tests/Queues/Resource/QueueTest.php @@ -31,7 +31,6 @@ class QueueTest extends QueuesTestCase { - public function test_Create() { $this->addMockSubscriber($this->makeResponse(null, 201)); @@ -123,7 +122,7 @@ public function test_Get_Message() public function test_List_Message() { $this->assertInstanceOf( - self::COLLECTION_CLASS, + 'OpenCloud\Queues\Collection\MessageIterator', $this->queue->setName('foo')->listMessages(array( 'ids' => array(100, 901, 58) )) @@ -166,7 +165,6 @@ public function test_Getting_Claim() public function test_List_Messages_Boolean_Casting() { - // Test true (boolean) casts to "true" (string) $messages = $this->queue->listMessages(array('echo' => true)); $options = $messages->getOptions(); @@ -186,6 +184,5 @@ public function test_List_Messages_Boolean_Casting() $messages = $this->queue->listMessages(array('echo' => 'false')); $options = $messages->getOptions(); $this->assertEquals('false', $options['baseUrl']->getQuery()->get('echo')); - - } + } } diff --git a/tests/OpenCloud/Tests/Queues/ServiceTest.php b/tests/OpenCloud/Tests/Queues/ServiceTest.php index b7f5e3e2c..7864e6770 100644 --- a/tests/OpenCloud/Tests/Queues/ServiceTest.php +++ b/tests/OpenCloud/Tests/Queues/ServiceTest.php @@ -19,7 +19,6 @@ class ServiceTest extends QueuesTestCase { - public function test_ClientId() { $rand = sha1(rand(1, 9999)); diff --git a/tests/OpenCloud/Tests/RackspaceTest.php b/tests/OpenCloud/Tests/RackspaceTest.php index b24f082f6..7cf37f183 100644 --- a/tests/OpenCloud/Tests/RackspaceTest.php +++ b/tests/OpenCloud/Tests/RackspaceTest.php @@ -17,6 +17,7 @@ namespace OpenCloud\Tests; +use OpenCloud\Tests\MockLogger; class RackspaceTest extends OpenCloudTestCase { @@ -31,10 +32,18 @@ public function test_Credentials() public function test_Factory_Methods() { + // Inject mock logger + $oldLogger = $this->getClient()->getLogger(); + $this->getClient()->setLogger(new MockLogger()); + $this->assertInstanceOf( 'OpenCloud\Database\Service', $this->getClient()->databaseService('cloudDatabases', 'DFW') ); + + // Re-inject old logger + $this->getClient()->setLogger($oldLogger); + $this->assertInstanceOf( 'OpenCloud\LoadBalancer\Service', $this->getClient()->loadBalancerService('cloudLoadBalancers', 'DFW') diff --git a/tests/OpenCloud/Tests/VersionTest.php b/tests/OpenCloud/Tests/VersionTest.php index d7501c309..e7ecc1b9e 100644 --- a/tests/OpenCloud/Tests/VersionTest.php +++ b/tests/OpenCloud/Tests/VersionTest.php @@ -36,4 +36,4 @@ public function test_Guzzle_Version() { $this->assertNotNull(Version::getGuzzleVersion()); } -} +} diff --git a/tests/OpenCloud/Tests/Volume/Resource/SnapshotTest.php b/tests/OpenCloud/Tests/Volume/Resource/SnapshotTest.php index 8ea4b45b4..8fc0b39ab 100644 --- a/tests/OpenCloud/Tests/Volume/Resource/SnapshotTest.php +++ b/tests/OpenCloud/Tests/Volume/Resource/SnapshotTest.php @@ -21,7 +21,6 @@ class SnapshotTest extends VolumeTestCase { - private $snapshot; public function setupObjects() @@ -65,8 +64,8 @@ public function testResourceName() */ public function testUpdateDisallowedProperties() { - $this->volume->rename(array( + $this->volume->rename(array( 'volume_id' => 'abcd-ef12' - )); + )); } } diff --git a/tests/OpenCloud/Tests/Volume/Resource/VolumeTest.php b/tests/OpenCloud/Tests/Volume/Resource/VolumeTest.php index db182db20..3b2667c67 100644 --- a/tests/OpenCloud/Tests/Volume/Resource/VolumeTest.php +++ b/tests/OpenCloud/Tests/Volume/Resource/VolumeTest.php @@ -66,8 +66,8 @@ public function testResourceName() */ public function testUpdateDisallowedProperties() { - $this->volume->rename(array( + $this->volume->rename(array( 'size' => 314 - )); + )); } } diff --git a/tests/OpenCloud/Tests/Volume/Resource/VolumeTypeTest.php b/tests/OpenCloud/Tests/Volume/Resource/VolumeTypeTest.php index 0b8eae1f0..a8730c8ad 100644 --- a/tests/OpenCloud/Tests/Volume/Resource/VolumeTypeTest.php +++ b/tests/OpenCloud/Tests/Volume/Resource/VolumeTypeTest.php @@ -21,7 +21,6 @@ class VolumeTypeTest extends VolumeTestCase { - private $volumeType; public function setupObjects() diff --git a/tests/OpenCloud/Tests/Volume/ServiceTest.php b/tests/OpenCloud/Tests/Volume/ServiceTest.php index dd6ebb179..d2569cbb2 100644 --- a/tests/OpenCloud/Tests/Volume/ServiceTest.php +++ b/tests/OpenCloud/Tests/Volume/ServiceTest.php @@ -19,7 +19,6 @@ class ServiceTest extends VolumeTestCase { - public function test__construct() { $this->assertInstanceOf( diff --git a/tests/OpenCloud/Tests/Volume/VolumeTestCase.php b/tests/OpenCloud/Tests/Volume/VolumeTestCase.php index 657f46755..e956631f7 100644 --- a/tests/OpenCloud/Tests/Volume/VolumeTestCase.php +++ b/tests/OpenCloud/Tests/Volume/VolumeTestCase.php @@ -33,4 +33,4 @@ public function setupObjects() $this->addMockSubscriber($this->getTestFilePath('Volume')); $this->volume = $this->service->volume('foo'); } -} +} diff --git a/tests/OpenCloud/Tests/_response/Auth.resp b/tests/OpenCloud/Tests/_response/Auth.resp index d0f978eba..add5174dc 100644 --- a/tests/OpenCloud/Tests/_response/Auth.resp +++ b/tests/OpenCloud/Tests/_response/Auth.resp @@ -8,4 +8,414 @@ vary: Accept, Accept-Encoding, X-Auth-Token VIA: 1.0 Repose (Repose/2.3.5) Front-End-Https: on -{"access":{"token":{"id":"cc81a27bf50249e5b5878d8b51f2eea6","expires":"2013-11-13T10:49:29.409Z","tenant":{"id":"123456","name":"123456"},"RAX-AUTH:authenticatedBy":["APIKEY"]},"serviceCatalog":[{"name":"cloudFilesCDN","endpoints":[{"region":"ORD","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/cdn2.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"DFW","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/cdn1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"SYD","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/cdn4.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"IAD","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/cdn5.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"HKG","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/cdn6.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"}],"type":"rax:object-cdn"},{"name":"cloudFiles","endpoints":[{"region":"ORD","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/storage101.ord1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","internalURL":"https:\/\/snet-storage101.ord1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"SYD","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/storage101.syd2.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","internalURL":"https:\/\/snet-storage101.syd2.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"DFW","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/storage101.dfw1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","internalURL":"https:\/\/snet-storage101.dfw1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"IAD","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/storage101.iad3.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","internalURL":"https:\/\/snet-storage101.iad3.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"},{"region":"HKG","tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","publicURL":"https:\/\/storage101.hkg1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","internalURL":"https:\/\/snet-storage101.hkg1.clouddrive.com\/v1\/MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa"}],"type":"object-store"},{"name":"cloudLoadBalancers","endpoints":[{"region":"DFW","tenantId":"123456","publicURL":"https:\/\/dfw.loadbalancers.api.rackspacecloud.com\/v1.0\/123456"},{"region":"ORD","tenantId":"123456","publicURL":"https:\/\/ord.loadbalancers.api.rackspacecloud.com\/v1.0\/123456"},{"region":"SYD","tenantId":"123456","publicURL":"https:\/\/syd.loadbalancers.api.rackspacecloud.com\/v1.0\/123456"},{"region":"IAD","tenantId":"123456","publicURL":"https:\/\/iad.loadbalancers.api.rackspacecloud.com\/v1.0\/123456"},{"region":"HKG","tenantId":"123456","publicURL":"https:\/\/hkg.loadbalancers.api.rackspacecloud.com\/v1.0\/123456"}],"type":"rax:load-balancer"},{"name": "cloudImages","endpoints": [{"region": "IAD","tenantId": "123456","publicURL": "https://iad.images.api.rackspacecloud.com/v2/123456"}],"type": "image"},{"name":"autoscale","endpoints":[{"region":"ORD","tenantId":"123456","publicURL":"https:\/\/ord.autoscale.api.rackspacecloud.com\/v1.0\/123456"},{"region":"DFW","tenantId":"123456","publicURL":"https:\/\/dfw.autoscale.api.rackspacecloud.com\/v1.0\/123456"}],"type":"rax:autoscale"},{"name":"cloudBlockStorage","endpoints":[{"region":"DFW","tenantId":"123456","publicURL":"https:\/\/dfw.blockstorage.api.rackspacecloud.com\/v1\/123456"},{"region":"ORD","tenantId":"123456","publicURL":"https:\/\/ord.blockstorage.api.rackspacecloud.com\/v1\/123456"},{"region":"IAD","tenantId":"123456","publicURL":"https:\/\/iad.blockstorage.api.rackspacecloud.com\/v1\/123456"},{"region":"SYD","tenantId":"123456","publicURL":"https:\/\/syd.blockstorage.api.rackspacecloud.com\/v1\/123456"},{"region":"HKG","tenantId":"123456","publicURL":"https:\/\/hkg.blockstorage.api.rackspacecloud.com\/v1\/123456"}],"type":"volume"},{"name":"cloudMonitoring","endpoints":[{"tenantId":"123456","publicURL":"https:\/\/monitoring.api.rackspacecloud.com\/v1.0\/123456"}],"type":"rax:monitor"},{"name":"cloudServersOpenStack","endpoints":[{"region":"ORD","tenantId":"123456","publicURL":"https:\/\/ord.servers.api.rackspacecloud.com\/v2\/123456","versionInfo":"https:\/\/ord.servers.api.rackspacecloud.com\/v2","versionList":"https:\/\/ord.servers.api.rackspacecloud.com\/","versionId":"2"},{"region":"DFW","tenantId":"123456","publicURL":"https:\/\/dfw.servers.api.rackspacecloud.com\/v2\/123456","versionInfo":"https:\/\/dfw.servers.api.rackspacecloud.com\/v2","versionList":"https:\/\/dfw.servers.api.rackspacecloud.com\/","versionId":"2"},{"region":"SYD","tenantId":"123456","publicURL":"https:\/\/syd.servers.api.rackspacecloud.com\/v2\/123456","versionInfo":"https:\/\/syd.servers.api.rackspacecloud.com\/v2","versionList":"https:\/\/syd.servers.api.rackspacecloud.com\/","versionId":"2"},{"region":"IAD","tenantId":"123456","publicURL":"https:\/\/iad.servers.api.rackspacecloud.com\/v2\/123456","versionInfo":"https:\/\/iad.servers.api.rackspacecloud.com\/v2","versionList":"https:\/\/iad.servers.api.rackspacecloud.com\/","versionId":"2"},{"region":"HKG","tenantId":"123456","publicURL":"https:\/\/hkg.servers.api.rackspacecloud.com\/v2\/123456","versionInfo":"https:\/\/hkg.servers.api.rackspacecloud.com\/v2","versionList":"https:\/\/hkg.servers.api.rackspacecloud.com\/","versionId":"2"}],"type":"compute"},{"name":"cloudQueues","endpoints":[{"region":"DFW","tenantId":"123456","publicURL":"https:\/\/dfw.queues.api.rackspacecloud.com\/v1\/123456","internalURL":"https:\/\/snet-dfw.queues.api.rackspacecloud.com\/v1\/123456"},{"region":"ORD","tenantId":"123456","publicURL":"https:\/\/ord.queues.api.rackspacecloud.com\/v1\/123456","internalURL":"https:\/\/snet-ord.queues.api.rackspacecloud.com\/v1\/123456"},{"region":"SYD","tenantId":"123456","publicURL":"https:\/\/syd.queues.api.rackspacecloud.com\/v1\/123456","internalURL":"https:\/\/snet-syd.queues.api.rackspacecloud.com\/v1\/123456"},{"region":"IAD","tenantId":"123456","publicURL":"https:\/\/iad.queues.api.rackspacecloud.com\/v1\/123456","internalURL":"https:\/\/snet-iad.queues.api.rackspacecloud.com\/v1\/123456"},{"region":"HKG","tenantId":"123456","publicURL":"https:\/\/hkg.queues.api.rackspacecloud.com\/v1\/123456","internalURL":"https:\/\/snet-hkg.queues.api.rackspacecloud.com\/v1\/123456"}],"type":"rax:queues"},{"name":"cloudDatabases","endpoints":[{"region":"SYD","tenantId":"123456","publicURL":"https:\/\/syd.databases.api.rackspacecloud.com\/v1.0\/123456"},{"region":"ORD","tenantId":"123456","publicURL":"https:\/\/ord.databases.api.rackspacecloud.com\/v1.0\/123456"},{"region":"DFW","tenantId":"123456","publicURL":"https:\/\/dfw.databases.api.rackspacecloud.com\/v1.0\/123456"},{"region":"IAD","tenantId":"123456","publicURL":"https:\/\/iad.databases.api.rackspacecloud.com\/v1.0\/123456"},{"region":"HKG","tenantId":"123456","publicURL":"https:\/\/hkg.databases.api.rackspacecloud.com\/v1.0\/123456"}],"type":"rax:database"},{"name":"cloudBackup","endpoints":[{"tenantId":"123456","publicURL":"https:\/\/backup.api.rackspacecloud.com\/v1.0\/123456"}],"type":"rax:backup"},{"name":"cloudServers","endpoints":[{"tenantId":"123456","publicURL":"https:\/\/servers.api.rackspacecloud.com\/v1.0\/123456","versionInfo":"https:\/\/servers.api.rackspacecloud.com\/v1.0","versionList":"https:\/\/servers.api.rackspacecloud.com\/","versionId":"1.0"}],"type":"compute"},{"name":"cloudDNS","endpoints":[{"tenantId":"123456","publicURL":"https:\/\/dns.api.rackspacecloud.com\/v1.0\/123456"}],"type":"rax:dns"}],"user":{"id":"10048286","roles":[{"id":"10000150","description":"Checkmate Access role","name":"checkmate"},{"id":"3","description":"User Admin Role.","name":"identity:user-admin"},{"tenantId":"MossoCloudFS_b42b6e1f-9ec5-4003-91f6-a7667ac19cfa","id":"5","description":"A Role that allows a user access to keystone Service methods","name":"object-store:default"},{"tenantId":"123456","id":"6","description":"A Role that allows a user access to keystone Service methods","name":"compute:default"}],"name":"jamiehannaford1","RAX-AUTH:defaultRegion":"DFW"}}} \ No newline at end of file +{ + "access": { + "serviceCatalog": [ + { + "endpoints": [ + { + "publicURL": "https://cdn2.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "ORD", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "publicURL": "https://cdn1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "DFW", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "publicURL": "https://cdn4.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "SYD", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "publicURL": "https://cdn5.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "IAD", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "publicURL": "https://cdn6.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "HKG", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + } + ], + "name": "cloudFilesCDN", + "type": "rax:object-cdn" + }, + { + "endpoints": [ + { + "internalURL": "https://snet-storage101.ord1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "publicURL": "https://storage101.ord1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "ORD", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "internalURL": "https://snet-storage101.syd2.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "publicURL": "https://storage101.syd2.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "SYD", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "internalURL": "https://snet-storage101.dfw1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "publicURL": "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "DFW", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "internalURL": "https://snet-storage101.iad3.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "publicURL": "https://storage101.iad3.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "IAD", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "internalURL": "https://snet-storage101.hkg1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "publicURL": "https://storage101.hkg1.clouddrive.com/v1/MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "region": "HKG", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + } + ], + "name": "cloudFiles", + "type": "object-store" + }, + { + "endpoints": [ + { + "publicURL": "https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/123456", + "region": "DFW", + "tenantId": "123456" + }, + { + "publicURL": "https://ord.loadbalancers.api.rackspacecloud.com/v1.0/123456", + "region": "ORD", + "tenantId": "123456" + }, + { + "publicURL": "https://syd.loadbalancers.api.rackspacecloud.com/v1.0/123456", + "region": "SYD", + "tenantId": "123456" + }, + { + "publicURL": "https://iad.loadbalancers.api.rackspacecloud.com/v1.0/123456", + "region": "IAD", + "tenantId": "123456" + }, + { + "publicURL": "https://hkg.loadbalancers.api.rackspacecloud.com/v1.0/123456", + "region": "HKG", + "tenantId": "123456" + } + ], + "name": "cloudLoadBalancers", + "type": "rax:load-balancer" + }, + { + "endpoints": [ + { + "publicURL": "https://iad.images.api.rackspacecloud.com/v2/123456", + "region": "IAD", + "tenantId": "123456" + } + ], + "name": "cloudImages", + "type": "image" + }, + { + "endpoints": [ + { + "publicURL": "https://ord.autoscale.api.rackspacecloud.com/v1.0/123456", + "region": "ORD", + "tenantId": "123456" + }, + { + "publicURL": "https://dfw.autoscale.api.rackspacecloud.com/v1.0/123456", + "region": "DFW", + "tenantId": "123456" + } + ], + "name": "autoscale", + "type": "rax:autoscale" + }, + { + "endpoints": [ + { + "publicURL": "https://dfw.blockstorage.api.rackspacecloud.com/v1/123456", + "region": "DFW", + "tenantId": "123456" + }, + { + "publicURL": "https://ord.blockstorage.api.rackspacecloud.com/v1/123456", + "region": "ORD", + "tenantId": "123456" + }, + { + "publicURL": "https://iad.blockstorage.api.rackspacecloud.com/v1/123456", + "region": "IAD", + "tenantId": "123456" + }, + { + "publicURL": "https://syd.blockstorage.api.rackspacecloud.com/v1/123456", + "region": "SYD", + "tenantId": "123456" + }, + { + "publicURL": "https://hkg.blockstorage.api.rackspacecloud.com/v1/123456", + "region": "HKG", + "tenantId": "123456" + } + ], + "name": "cloudBlockStorage", + "type": "volume" + }, + { + "endpoints": [ + { + "publicURL": "https://monitoring.api.rackspacecloud.com/v1.0/123456", + "tenantId": "123456" + } + ], + "name": "cloudMonitoring", + "type": "rax:monitor" + }, + { + "endpoints": [ + { + "publicURL": "https://ord.servers.api.rackspacecloud.com/v2/123456", + "region": "ORD", + "tenantId": "123456", + "versionId": "2", + "versionInfo": "https://ord.servers.api.rackspacecloud.com/v2", + "versionList": "https://ord.servers.api.rackspacecloud.com/" + }, + { + "publicURL": "https://dfw.servers.api.rackspacecloud.com/v2/123456", + "region": "DFW", + "tenantId": "123456", + "versionId": "2", + "versionInfo": "https://dfw.servers.api.rackspacecloud.com/v2", + "versionList": "https://dfw.servers.api.rackspacecloud.com/" + }, + { + "publicURL": "https://syd.servers.api.rackspacecloud.com/v2/123456", + "region": "SYD", + "tenantId": "123456", + "versionId": "2", + "versionInfo": "https://syd.servers.api.rackspacecloud.com/v2", + "versionList": "https://syd.servers.api.rackspacecloud.com/" + }, + { + "publicURL": "https://iad.servers.api.rackspacecloud.com/v2/123456", + "region": "IAD", + "tenantId": "123456", + "versionId": "2", + "versionInfo": "https://iad.servers.api.rackspacecloud.com/v2", + "versionList": "https://iad.servers.api.rackspacecloud.com/" + }, + { + "publicURL": "https://hkg.servers.api.rackspacecloud.com/v2/123456", + "region": "HKG", + "tenantId": "123456", + "versionId": "2", + "versionInfo": "https://hkg.servers.api.rackspacecloud.com/v2", + "versionList": "https://hkg.servers.api.rackspacecloud.com/" + } + ], + "name": "cloudServersOpenStack", + "type": "compute" + }, + { + "endpoints": [ + { + "internalURL": "https://snet-dfw.queues.api.rackspacecloud.com/v1/123456", + "publicURL": "https://dfw.queues.api.rackspacecloud.com/v1/123456", + "region": "DFW", + "tenantId": "123456" + }, + { + "internalURL": "https://snet-ord.queues.api.rackspacecloud.com/v1/123456", + "publicURL": "https://ord.queues.api.rackspacecloud.com/v1/123456", + "region": "ORD", + "tenantId": "123456" + }, + { + "internalURL": "https://snet-syd.queues.api.rackspacecloud.com/v1/123456", + "publicURL": "https://syd.queues.api.rackspacecloud.com/v1/123456", + "region": "SYD", + "tenantId": "123456" + }, + { + "internalURL": "https://snet-iad.queues.api.rackspacecloud.com/v1/123456", + "publicURL": "https://iad.queues.api.rackspacecloud.com/v1/123456", + "region": "IAD", + "tenantId": "123456" + }, + { + "internalURL": "https://snet-hkg.queues.api.rackspacecloud.com/v1/123456", + "publicURL": "https://hkg.queues.api.rackspacecloud.com/v1/123456", + "region": "HKG", + "tenantId": "123456" + } + ], + "name": "cloudQueues", + "type": "rax:queues" + }, + { + "endpoints": [ + { + "publicURL": "https://syd.databases.api.rackspacecloud.com/v1.0/123456", + "region": "SYD", + "tenantId": "123456" + }, + { + "publicURL": "https://ord.databases.api.rackspacecloud.com/v1.0/123456", + "region": "ORD", + "tenantId": "123456" + }, + { + "publicURL": "https://dfw.databases.api.rackspacecloud.com/v1.0/123456", + "region": "DFW", + "tenantId": "123456" + }, + { + "publicURL": "https://iad.databases.api.rackspacecloud.com/v1.0/123456", + "region": "IAD", + "tenantId": "123456" + }, + { + "publicURL": "https://hkg.databases.api.rackspacecloud.com/v1.0/123456", + "region": "HKG", + "tenantId": "123456" + } + ], + "name": "cloudDatabases", + "type": "rax:database" + }, + { + "endpoints": [ + { + "publicURL": "https://backup.api.rackspacecloud.com/v1.0/123456", + "tenantId": "123456" + } + ], + "name": "cloudBackup", + "type": "rax:backup" + }, + { + "endpoints": [ + { + "publicURL": "https://servers.api.rackspacecloud.com/v1.0/123456", + "tenantId": "123456", + "versionId": "1.0", + "versionInfo": "https://servers.api.rackspacecloud.com/v1.0", + "versionList": "https://servers.api.rackspacecloud.com/" + } + ], + "name": "cloudServers", + "type": "compute" + }, + { + "endpoints": [ + { + "publicURL": "https://dns.api.rackspacecloud.com/v1.0/123456", + "tenantId": "123456" + } + ], + "name": "cloudDNS", + "type": "rax:dns" + }, + { + "endpoints": [ + { + "publicUrl": "https://syd.orchestration.api.rackspacecloud.com/v1/123456", + "region": "SYD", + "tenantId": "123456" + }, + { + "publicURL": "https://iad.orchestration.api.rackspacecloud.com/v1/123456", + "region": "IAD", + "tenantId": "123456" + }, + { + "publicURL": "https://ord.orchestration.api.rackspacecloud.com/v1/123456", + "region": "ORD", + "tenantId": "123456" + }, + { + "publicURL": "https://dfw.orchestration.api.rackspacecloud.com/v1/123456", + "region": "DFW", + "tenantId": "123456" + } + ], + "name": "cloudOrchestration", + "type": "orchestration" + }, + { + "name": "cloudNetworks", + "endpoints": [ + { + "region": "IAD", + "tenantId": "123456", + "publicURL": "https://iad.networks.api.rackspacecloud.com/v2.0" + }, + { + "region": "DFW", + "tenantId": "123456", + "publicURL": "https://dfw.networks.api.rackspacecloud.com/v2.0" + } + ], + "type": "network" + }, + { + "name": "rackCDN", + "endpoints": [ + { + "tenantId": "123456", + "publicURL": "https://global.cdn.api.rackspacecloud.com/v1.0/123456", + "internalURL": "https://global.cdn.api.rackspacecloud.com/v1.0/123456" + } + ], + "type": "rax:cdn" + } + ], + "token": { + "RAX-AUTH:authenticatedBy": [ + "APIKEY" + ], + "expires": "2013-11-13T10:49:29.409Z", + "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "tenant": { + "id": "123456", + "name": "123456" + } + }, + "user": { + "RAX-AUTH:defaultRegion": "DFW", + "id": "10048286", + "name": "jamiehannaford1", + "roles": [ + { + "description": "Checkmate Access role", + "id": "10000150", + "name": "checkmate" + }, + { + "description": "User Admin Role.", + "id": "3", + "name": "identity:user-admin" + }, + { + "description": "A Role that allows a user access to keystone Service methods", + "id": "5", + "name": "object-store:default", + "tenantId": "MossoCloudFS_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "description": "A Role that allows a user access to keystone Service methods", + "id": "6", + "name": "compute:default", + "tenantId": "123456" + } + ] + } + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index eca206a70..08888c4d1 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -17,4 +17,4 @@ require __DIR__ . '/../vendor/autoload.php'; -define('ROOT_TEST_DIR', __DIR__ . '/OpenCloud/Tests/'); \ No newline at end of file +define('ROOT_TEST_DIR', __DIR__ . '/OpenCloud/Tests/');