├── tests ├── __init__.py ├── unit │ ├── __init__.py │ ├── base_test.py │ ├── test_service_catalog.py │ ├── test_exceptions.py │ └── test_cloud_cdn.py └── integrated │ ├── __init__.py │ └── test_module.py ├── pyrax ├── version.py ├── identity │ ├── __init__.py │ └── keystone_identity.py ├── service_catalog.py └── http.py ├── setup.cfg ├── TODO ├── MANIFEST.in ├── .coveragerc ├── .gitignore ├── .travis.yml ├── tox.ini ├── CONTRIBUTING.rst ├── Makefile ├── samples ├── cloud_loadbalancers │ ├── list_algorithms.py │ ├── list_protocols.py │ ├── create_node.py │ ├── create_vip.py │ ├── node_condition.py │ ├── create_lb.py │ ├── get_lb_attributes.py │ ├── content_caching.py │ ├── metadata.py │ ├── session_persistence.py │ ├── get_usage.py │ ├── ssl_termination.py │ └── add_remove_node.py ├── cloudservers │ ├── list_images.py │ ├── list_flavors.py │ ├── create_server.py │ ├── create_image.py │ ├── delete_image.py │ ├── create_with_meta_and_files.py │ ├── reboot.py │ └── delete_server.py ├── cloud_databases │ ├── list_flavors.py │ ├── create_instance.py │ ├── delete_instance.py │ ├── add_database.py │ └── add_user.py ├── images │ ├── list_images.py │ ├── list_tasks.py │ ├── list_image_members.py │ ├── accept_images.py │ ├── list_images_filtered.py │ ├── add_image_member.py │ ├── delete_image_member.py │ ├── export_task.py │ └── import_task.py ├── auth_direct.py ├── queueing │ ├── list_queues.py │ ├── create_queue.py │ ├── delete_queue.py │ ├── list_claims.py │ ├── post_message.py │ ├── list_messages.py │ ├── delete_message.py │ ├── delete_messages.py │ └── claim_messages.py ├── cloud_dns │ ├── delete_all_ptr_records.py │ ├── create_domain.py │ ├── delete_domain.py │ ├── iterate_domains.py │ ├── update_domain.py │ ├── add_ptr_records.py │ ├── list_ptr_records.py │ ├── list_domains.py │ ├── delete_all_subdomains.py │ ├── delete_all_records.py │ ├── update_ptr_record.py │ ├── add_records.py │ ├── create_subdomain.py │ ├── list_records.py │ └── list_subdomains.py ├── cloud_blockstorage │ ├── create_volume.py │ ├── delete_volume.py │ ├── create_snapshot.py │ └── attach_detach_volume.py ├── cloud_networks │ ├── create_network.py │ ├── delete_network.py │ └── create_bastion.py ├── cloudfiles │ ├── store_with_etag.py │ ├── create_container.py │ ├── store_object.py │ ├── container_cdn.py │ ├── upload_file.py │ ├── delete_objects.py │ ├── fetch_objects.py │ ├── container_metadata.py │ ├── object_metadata.py │ ├── temporary_url.py │ ├── get_objects.py │ └── upload_folder.py ├── auth_creds_file.py ├── cloud_monitoring │ ├── create_entity.py │ ├── util.py │ ├── create_alarm.py │ ├── create_check.py │ └── create_notification.py └── autoscale │ ├── delete_scaling_group.py │ ├── add_policy.py │ ├── delete_policy.py │ ├── add_webhook.py │ └── delete_webhook.py ├── pyrax.spec.in ├── HACKING.rst ├── setup.py ├── docs └── installing_pyrax.md └── README.rst /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/integrated/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyrax/version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | version = "1.9.6" 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [install] 2 | optimize = 1 3 | 4 | [wheel] 5 | universal = 1 6 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * Cloud Backups 2 | * Add Cloud Files container sync 3 | * Add support for Cloud Networks virtual interfaces 4 | 5 | * Python 3 compatibility 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst RELEASENOTES.md LICENSE 2 | recursive-include docs *.md 3 | recursive-include samples *.py 4 | recursive-include tests *.py 5 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | */python?.?/* 4 | */lib-python/?.?/*.py 5 | */lib_pypy/_*.py 6 | */site-packages/* 7 | */unittest2/* 8 | */fakes.py 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | rpm-build/ 4 | rpms/ 5 | *~ 6 | .DS_Store 7 | *.swp 8 | *.pyc 9 | *.pyo 10 | *.egg* 11 | .tox 12 | .coveralls.yml 13 | .coverage 14 | pyrax.spec 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | - 2.7 5 | - pypy 6 | 7 | install: 8 | - pip install -U setuptools tox coveralls 9 | 10 | script: 11 | - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then tox -e pep8,py27; fi 12 | - if [[ "$TRAVIS_PYTHON_VERSION" == "pypy" ]]; then tox -e pep8,pypy; fi 13 | 14 | after_success: 15 | - coveralls 16 | -------------------------------------------------------------------------------- /pyrax/identity/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import glob 4 | import os 5 | opth = os.path 6 | 7 | fpath = opth.abspath(__file__) 8 | path = opth.dirname(fpath) 9 | pypath = opth.join(path, "*.py") 10 | pyfiles = glob.glob(pypath) 11 | fnames = [opth.basename(pyfile) for pyfile in pyfiles] 12 | __all__ = [opth.splitext(fname)[0] for fname in fnames 13 | if not fname.startswith("_")] 14 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = pep8, py27, pypy 3 | 4 | [testenv] 5 | deps = 6 | mock 7 | nose 8 | coverage 9 | 10 | commands = 11 | {envpython} -V 12 | {envbindir}/nosetests -v -w tests/unit --with-cover --cover-package=pyrax --cover-erase --cover-branch 13 | 14 | [testenv:pep8] 15 | deps = 16 | pep8 17 | 18 | commands = 19 | {envbindir}/pep8 -r --show-source --max-line-length=84 --ignore=E123,E124,E126,E127,E128,E303,E302 pyrax/ 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | Please submit an issue before submitting a pull request so we can determine 2 | whether or not the change may be accepted. Pyrax is in the process of being 3 | deprecated in favor of the OpenStack SDK. We will announce the process and 4 | timelines for this deprecation as soon as we can. 5 | 6 | Once a pull request has been deemed the right approach, please be sure that 7 | *all* pull requests are made against the **working** branch of the project, 8 | as we reserve the **master** branch for full releases. 9 | 10 | For style guidelines, please see the `HACKING `_ document in the 11 | root of this repository. 12 | 13 | If you find any bugs, or have ideas for improving pyrax, please create an issue 14 | at: 15 | 16 | https://github.com/rackspace/pyrax/issues 17 | 18 | Thanks! 19 | -------------------------------------------------------------------------------- /pyrax/identity/keystone_identity.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import absolute_import 4 | 5 | import pyrax 6 | from ..base_identity import BaseIdentity 7 | from .. import exceptions as exc 8 | 9 | 10 | class KeystoneIdentity(BaseIdentity): 11 | """ 12 | Implements the Keystone-specific behaviors for Identity. In most 13 | cases you will want to create specific subclasses to implement the 14 | _get_auth_endpoint() method if you want to use something other 15 | than the config file to control your auth endpoint. 16 | """ 17 | 18 | _default_region = "RegionOne" 19 | 20 | def _get_auth_endpoint(self): 21 | ep = self._auth_endpoint or pyrax.get_setting("auth_endpoint") 22 | if ep is None: 23 | raise exc.EndpointNotDefined("No auth endpoint has been specified.") 24 | return ep 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PACKAGE := $(shell basename *.spec .spec) 2 | ARCH = noarch 3 | RPMBUILD = rpmbuild --define "_topdir %(pwd)/rpm-build" \ 4 | --define "_builddir %{_topdir}" \ 5 | --define "_rpmdir %(pwd)/rpms" \ 6 | --define "_srcrpmdir %{_rpmdir}" \ 7 | --define "_sourcedir %{_topdir}" 8 | PYTHON = $(which python) 9 | 10 | all: rpms 11 | 12 | clean: 13 | rm -rf dist/ build/ rpm-build/ rpms/ 14 | rm -rf docs/*.gz MANIFEST *~ 15 | find . -name '*.pyc' -exec rm -f {} \; 16 | 17 | build: clean 18 | python setup.py build -f 19 | 20 | install: build 21 | python setup.py install -f 22 | 23 | reinstall: uninstall install 24 | 25 | uninstall: clean 26 | rm -f /usr/bin/${PACKAGE} 27 | rm -rf /usr/lib/python2.*/site-packages/${PACKAGE} 28 | 29 | uninstall_rpms: clean 30 | rpm -e ${PACKAGE} 31 | 32 | sdist: 33 | python setup.py sdist 34 | 35 | prep_rpmbuild: build sdist 36 | mkdir -p rpm-build 37 | mkdir -p rpms 38 | cp dist/*.gz rpm-build/ 39 | 40 | rpms: prep_rpmbuild 41 | ${RPMBUILD} -ba ${PACKAGE}.spec 42 | 43 | srpm: prep_rpmbuild 44 | ${RPMBUILD} -bs ${PACKAGE}.spec 45 | -------------------------------------------------------------------------------- /tests/unit/base_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import json 5 | import time 6 | import unittest 7 | 8 | 9 | TIMING_FILE = ".testtimes.json" 10 | 11 | 12 | class BaseTest(unittest.TestCase): 13 | def __init__(self, *args, **kwargs): 14 | super(BaseTest, self).__init__(*args, **kwargs) 15 | self.timing = False 16 | # Create the output file if it doesn't exist 17 | with open(TIMING_FILE, "a") as jj: 18 | pass 19 | 20 | def setUp(self): 21 | if self.timing: 22 | self.begun = time.time() 23 | super(BaseTest, self).setUp() 24 | 25 | def tearDown(self): 26 | if self.timing: 27 | elapsed = time.time() - self.begun 28 | with open(TIMING_FILE, "r") as jj: 29 | try: 30 | times = json.load(jj) 31 | except ValueError: 32 | times = [] 33 | times.append((elapsed, self._testMethodName)) 34 | with open(TIMING_FILE, "w") as jj: 35 | json.dump(times, jj) 36 | super(BaseTest, self).tearDown() 37 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/list_algorithms.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | 29 | # Get available algorithms 30 | print("Algorithms:", clb.algorithms) 31 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/list_protocols.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | 29 | # Get available protocols 30 | print("Protocols:", clb.protocols) 31 | -------------------------------------------------------------------------------- /samples/cloudservers/list_images.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cs = pyrax.cloudservers 28 | 29 | imgs = cs.images.list() 30 | for img in imgs: 31 | print("Name: %s\n ID: %s" % (img.name, img.id)) 32 | -------------------------------------------------------------------------------- /tests/integrated/test_module.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import unittest 6 | 7 | import pyrax 8 | 9 | 10 | # This file needs to contain the actual credentials for a 11 | # valid Rackspace Cloud account. 12 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 13 | 14 | 15 | class TestCase(unittest.TestCase): 16 | def setUp(self): 17 | pyrax.set_credential_file(creds_file) 18 | 19 | def tearDown(self): 20 | pyrax.clear_credentials() 21 | 22 | def test_cloudservers_images(self): 23 | imgs = pyrax.cloudservers.images.list() 24 | self.assert_(isinstance(imgs, list)) 25 | 26 | def test_cloudfiles_base_container(self): 27 | conts = pyrax.cloudfiles.get_all_containers() 28 | self.assert_(isinstance(conts, list)) 29 | 30 | def test_cloud_loadbalancers(self): 31 | lbs = pyrax.cloud_loadbalancers.list() 32 | self.assert_(isinstance(lbs, list)) 33 | 34 | def test_cloud_db(self): 35 | flavors = pyrax.cloud_databases.list_flavors() 36 | self.assert_(isinstance(flavors, list)) 37 | 38 | 39 | if __name__ == "__main__": 40 | unittest.main() 41 | -------------------------------------------------------------------------------- /samples/cloud_databases/list_flavors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | cdb = pyrax.cloud_databases 30 | 31 | flavors = cdb.list_flavors() 32 | print() 33 | print("Available Flavors:") 34 | for flavor in flavors: 35 | print("Name: %s; RAM: %s, ID: %s" % (flavor.name, flavor.ram, flavor.id)) 36 | print() 37 | -------------------------------------------------------------------------------- /samples/cloudservers/list_flavors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cs = pyrax.cloudservers 28 | 29 | flvs = cs.list_flavors() 30 | for flv in flvs: 31 | print("Name:", flv.name) 32 | print(" ID:", flv.id) 33 | print(" RAM:", flv.ram) 34 | print(" Disk:", flv.disk) 35 | print(" VCPUs:", flv.vcpus) 36 | print() 37 | -------------------------------------------------------------------------------- /samples/images/list_images.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | imgs = pyrax.images 28 | 29 | images = imgs.list() 30 | 31 | if not images: 32 | print("No images exist.") 33 | exit() 34 | print("There are %s images:" % len(images)) 35 | for image in images: 36 | print(" (%s) %s (ID=%s)" % (image.visibility, image.name, image.id)) 37 | -------------------------------------------------------------------------------- /samples/auth_direct.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | 28 | # Pass credentials directly (replace with your credentials) 29 | print("Pass directly:") 30 | try: 31 | pyrax.set_credentials("real_username", "real_api_key") 32 | except exc.AuthenticationFailed: 33 | print("Did you remember to replace the credentials with your actual", end=' ') 34 | print("username and api_key?") 35 | print("authenticated =", pyrax.identity.authenticated) 36 | print() 37 | -------------------------------------------------------------------------------- /samples/queueing/list_queues.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | pq = pyrax.queues 28 | 29 | queues = pq.list() 30 | if not queues: 31 | print("No queues have been created.") 32 | exit() 33 | num_queues = len(queues) 34 | if num_queues == 1: 35 | print("There is one queue defined:") 36 | else: 37 | print("There are %s queueis defined:" % num_queues) 38 | for queue in queues: 39 | print(" %s" % queue.name) 40 | -------------------------------------------------------------------------------- /samples/cloud_dns/delete_all_ptr_records.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | cs = pyrax.cloudservers 33 | 34 | # Be sure to substitute an actual server ID here 35 | server_id = "00000000-0000-0000-0000-000000000000" 36 | server = cs.servers.get(server_id) 37 | 38 | ret = dns.delete_ptr_records(server) 39 | print() 40 | print(ret) 41 | print() 42 | -------------------------------------------------------------------------------- /samples/cloud_dns/create_domain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | dns = pyrax.cloud_dns 31 | 32 | domain_name = "abc.example.edu" 33 | try: 34 | dom = dns.create(name=domain_name, emailAddress="sample@example.edu", 35 | ttl=900, comment="sample domain") 36 | except exc.DomainCreationFailed as e: 37 | print("Domain creation failed:", e) 38 | print("Domain created:", dom) 39 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/create_node.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | 29 | # You need to specify an address, port and condition 30 | node = clb.Node(address="10.1.1.1", port=80, condition="DISABLED") 31 | print("Node:", node 32 | ) 33 | # Actually, 'condition' is optional; it will default to 'ENABLED'. 34 | node_default = clb.Node(address="10.1.1.2", port=80) 35 | print("Node(using default condition):", node_default) 36 | -------------------------------------------------------------------------------- /samples/queueing/create_queue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | name = six.moves.input("Enter the name for your queue: ") 32 | if not name: 33 | exit() 34 | 35 | try: 36 | queue = pq.create(name) 37 | msg = "The queue '%s' has been created." % queue.name 38 | except exc.DuplicateQueue: 39 | msg = "A queue with the name '%s' already exists." % name 40 | print(msg) 41 | -------------------------------------------------------------------------------- /samples/cloud_dns/delete_domain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | 33 | domain_name = "abc.example.edu" 34 | try: 35 | dom = dns.find(name=domain_name) 36 | except exc.NotFound: 37 | print("There is no DNS information for the domain '%s'." % domain_name) 38 | sys.exit() 39 | 40 | dom.delete() 41 | print("The domain '%s' was successfully deleted." % domain_name) 42 | -------------------------------------------------------------------------------- /samples/cloud_blockstorage/create_volume.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cbs = pyrax.cloud_blockstorage 28 | vol_name = pyrax.utils.random_ascii(length=8) 29 | 30 | sata_vol = cbs.create(name="my_standard_volume", size=500, volume_type="SATA") 31 | ssd_vol = cbs.create(name="my_fast_volume", size=500, volume_type="SSD") 32 | 33 | print("SATA:", sata_vol) 34 | print() 35 | print("SSD:", ssd_vol) 36 | print() 37 | print("To delete these volumes, run 'delete_volume.py'") 38 | print() 39 | -------------------------------------------------------------------------------- /samples/images/list_tasks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | imgs = pyrax.images 28 | 29 | print("This will loop through all current tasks.") 30 | tasks = imgs.list_tasks() 31 | for task in tasks: 32 | print() 33 | print("Task ID=%s" % task.id) 34 | print(" Type: %s" % task.type) 35 | print(" Status: %s" % task.status) 36 | print(" Message: %s" % task.message) 37 | print(" Created: %s" % task.created_at) 38 | print(" Expires: %s" % task.expires_at) 39 | -------------------------------------------------------------------------------- /samples/cloud_networks/create_network.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | from pyrax import utils 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | cnw = pyrax.cloud_networks 29 | new_network_name = "SAMPLE_NETWORK" 30 | new_network_cidr = "192.168.0.0/24" 31 | 32 | # List initial status 33 | nets = cnw.list() 34 | for net in nets: 35 | print("Network: %s; cidr=%s; id=%s" % (net.label, net.cidr, net.id)) 36 | print() 37 | 38 | # Add the new network 39 | new_net = cnw.create(new_network_name, cidr=new_network_cidr) 40 | print("NEW NET", new_net) 41 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/create_vip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | 29 | # You can specify a type, address, IP version, and ID 30 | # None are required; defaults are: 31 | # type: PUBLIC 32 | # address: None 33 | # ip_version: IPV4 34 | # id: None 35 | 36 | vip = clb.VirtualIP() 37 | print("Virtual IP (using defaults):", vip 38 | ) 39 | vip = clb.VirtualIP(type="SERVICENET", address="1.2.3.4", ipVersion="IPV4", id=999) 40 | print("Virtual IP (using supplied values):", vip) 41 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/node_condition.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | 29 | lb = clb.list()[0] 30 | # Initial state 31 | print("Initial:", [(node.id, node.condition) for node in lb.nodes] 32 | ) 33 | # Toggle the first node's condition between ENABLED and DISABLED 34 | node = lb.nodes[0] 35 | node.condition = "DISABLED" if node.condition == "ENABLED" else "ENABLED" 36 | node.update() 37 | 38 | # After toggling 39 | print("Toggled:", [(node.id, node.condition) for node in lb.nodes]) 40 | -------------------------------------------------------------------------------- /samples/cloud_dns/iterate_domains.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | dns = pyrax.cloud_dns 31 | 32 | def print_domain(domain): 33 | print("Domain:", domain.name) 34 | print(" email:", domain.emailAddress) 35 | print(" created:", domain.created) 36 | print() 37 | 38 | count = 0 39 | 40 | iterator = dns.get_domain_iterator() 41 | for domain in iterator: 42 | count += 1 43 | print_domain(domain) 44 | 45 | print("There were a total of %s domain(s)." % count) 46 | -------------------------------------------------------------------------------- /samples/cloudfiles/store_with_etag.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cf = pyrax.cloudfiles 28 | 29 | cont_name = pyrax.utils.random_ascii(8) 30 | obj_name = pyrax.utils.random_ascii(8) 31 | cont = cf.create_container(cont_name) 32 | 33 | content = "This is a random collection of words." 34 | chksum = pyrax.utils.get_checksum(content) 35 | obj = cf.store_object(cont, obj_name, content, etag=chksum) 36 | print("Calculated checksum:", chksum) 37 | print(" Stored object etag:", obj.etag 38 | ) 39 | # Clean up 40 | cont.delete(True) 41 | -------------------------------------------------------------------------------- /samples/cloudfiles/create_container.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cf = pyrax.cloudfiles 28 | 29 | cont_name = pyrax.utils.random_ascii(8) 30 | print("Creating container with random name:", cont_name) 31 | cont = cf.create_container(cont_name) 32 | print("New Container") 33 | print("Name:", cont.name) 34 | print("# of objects:", cont.object_count) 35 | print() 36 | print("All Containers") 37 | print("list_containers:", cf.list_containers()) 38 | print("get_all_containers:", cf.get_all_containers() 39 | ) 40 | # Clean up 41 | cont.delete() 42 | -------------------------------------------------------------------------------- /samples/cloud_dns/update_domain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | 33 | domain_name = "abc.example.edu" 34 | try: 35 | dom = dns.find(name=domain_name) 36 | except exc.NotFound: 37 | print("There is no DNS information for the domain '%s'." % domain_name) 38 | sys.exit() 39 | 40 | print("Original TTL for '%s': %s" % (domain_name, dom.ttl)) 41 | # Add 10 minutes 42 | new_ttl = dom.ttl + 600 43 | dom.update(ttl=new_ttl) 44 | dom.reload() 45 | print("New TTL: %s" % dom.ttl) 46 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/create_lb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | lb_name = pyrax.utils.random_ascii(length=8) 29 | 30 | # You may have to adjust the address of the node to something on 31 | # the same internal network as your load balancer. 32 | node = clb.Node(address="10.177.1.1", port=80, condition="ENABLED") 33 | vip = clb.VirtualIP(type="PUBLIC") 34 | lb = clb.create(lb_name, port=80, protocol="HTTP", nodes=[node], virtual_ips=[vip]) 35 | 36 | print("Node:", node.to_dict()) 37 | print("Virtual IP:", vip.to_dict()) 38 | print() 39 | print("Load Balancer:", lb) 40 | -------------------------------------------------------------------------------- /samples/auth_creds_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | 28 | # Use a credential file in the format: 29 | # [rackspace_cloud] 30 | # username = myusername 31 | # api_key = 01234567890abcdef 32 | print() 33 | print("Using credentials file") 34 | # Note: you can name this file whatever you like. 35 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 36 | try: 37 | pyrax.set_credential_file(creds_file) 38 | except exc.AuthenticationFailed: 39 | print("Did you remember to replace the credential file with your actual", 40 | end=' ') 41 | print("username and api_key?") 42 | print("authenticated =", pyrax.identity.authenticated) 43 | print() 44 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/get_lb_attributes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | clb = pyrax.cloud_loadbalancers 30 | 31 | try: 32 | lb = clb.list()[0] 33 | except IndexError: 34 | print("You do not have any load balancers yet.") 35 | print("Please create one and then re-run this script.") 36 | sys.exit() 37 | 38 | print("Load Balancer:", lb) 39 | print("Name:", lb.name) 40 | print("ID:", lb.id) 41 | print("Status:", lb.status) 42 | print("Nodes:", lb.nodes) 43 | print("Virtual IPs:", lb.virtual_ips) 44 | print("Algorithm:", lb.algorithm) 45 | print("Protocol:", lb.protocol) 46 | -------------------------------------------------------------------------------- /samples/cloud_blockstorage/delete_volume.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cbs = pyrax.cloud_blockstorage 28 | 29 | # This assumes that you have are deleting the volumes named 'my_fast_volume' 30 | # and 'my_standard_volume' that were created in create_volume.py. 31 | for nm in ("my_fast_volume", "my_standard_volume"): 32 | try: 33 | vol = cbs.findall(name=nm)[0] 34 | except IndexError: 35 | print("There is no volume named '%s'. Skipping..." % nm) 36 | vol = None 37 | if vol: 38 | print("Deleting", vol) 39 | vol.delete() 40 | print() 41 | print("Done.") 42 | print() 43 | -------------------------------------------------------------------------------- /samples/images/list_image_members.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | imgs = pyrax.images 28 | 29 | print("This will loop through all your private images and list the members for " 30 | "each.") 31 | images = imgs.list(visibility="private") 32 | if not images: 33 | print("No images exist.") 34 | exit() 35 | for image in images: 36 | members = imgs.list_image_members(image) 37 | if not members: 38 | print("Image %s: no members" % image.id) 39 | else: 40 | print("Image %s:" % image.id) 41 | for member in members: 42 | print(" %s (%s)" % (member.id, member.status)) 43 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/content_caching.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | clb = pyrax.cloud_loadbalancers 30 | 31 | try: 32 | lb = clb.list()[0] 33 | except IndexError: 34 | print("You do not have any load balancers yet.") 35 | print("Please create one and then re-run this script.") 36 | sys.exit() 37 | 38 | print("Load Balancer:", lb) 39 | orig = lb.content_caching 40 | print("Current setting of content caching:", orig) 41 | print() 42 | if orig: 43 | print("Turning off...") 44 | else: 45 | print("Turning on...") 46 | lb.content_caching = not orig 47 | print("New setting of content caching:", lb.content_caching) 48 | -------------------------------------------------------------------------------- /samples/cloud_monitoring/create_entity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | cm = pyrax.cloud_monitoring 30 | cs = pyrax.cloudservers 31 | 32 | # Create an entity based on an existing server 33 | servers = cs.servers.list() 34 | if not servers: 35 | print("You must have at least one server to run this sample code.") 36 | exit() 37 | server = servers[0] 38 | ip = server.accessIPv4 39 | ent = cm.create_entity(name="sample_entity", ip_addresses={"main": ip}, 40 | metadata={"note": "Sample enitity for server '%s'" % server.name}) 41 | 42 | print("Name:", ent.name) 43 | print("ID:", ent.id) 44 | print("IPs:", ent.ip_addresses) 45 | print("Meta:", ent.metadata) 46 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/metadata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | clb = pyrax.cloud_loadbalancers 28 | 29 | lb = clb.list()[0] 30 | orig_meta = lb.get_metadata() 31 | print("Initial metadata:", orig_meta) 32 | lb.set_metadata({"a": "one", "b": "two", "c": "three"}) 33 | print("New metadata:", lb.get_metadata()) 34 | lb.update_metadata({"d": "four"}) 35 | print("Updated metadata:", lb.get_metadata()) 36 | lb.set_metadata({"e": "five"}) 37 | print("After set_metadata:", lb.get_metadata()) 38 | lb.delete_metadata() 39 | print("After delete_metadata:", lb.get_metadata()) 40 | if orig_meta: 41 | lb.set_metadata(orig_meta) 42 | print("After restoring original metadata:", lb.get_metadata()) 43 | -------------------------------------------------------------------------------- /samples/cloud_networks/delete_network.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | from pyrax import exc 24 | from pyrax import utils 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | 30 | pyrax.set_http_debug(True) 31 | 32 | cnw = pyrax.cloud_networks 33 | network_name = "SAMPLE_NETWORK" 34 | 35 | # Get the network created in the create_network sample script 36 | try: 37 | net = cnw.find_network_by_label(network_name) 38 | except exc.NetworkNotFound: 39 | msg = ("The sample network was not found. Please run the 'create_network' " 40 | "script before running this script.") 41 | print(msg) 42 | exit() 43 | 44 | print("Sample network:") 45 | print(net) 46 | print() 47 | net.delete() 48 | print("The network has been deleted.") 49 | -------------------------------------------------------------------------------- /samples/cloudservers/create_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cs = pyrax.cloudservers 28 | server_name = pyrax.utils.random_ascii(8) 29 | 30 | ubu_image = [img for img in cs.images.list() 31 | if "14.04" in img.name 32 | and "PVHVM" in img.name][0] 33 | print("Ubuntu Image:", ubu_image) 34 | flavor_1GB = [flavor for flavor in cs.flavors.list() 35 | if flavor.ram == 1024][0] 36 | print("1024 Flavor:", flavor_1GB) 37 | server = cs.servers.create(server_name, ubu_image.id, flavor_1GB.id) 38 | print("Name:", server.name) 39 | print("ID:", server.id) 40 | print("Status:", server.status) 41 | print("Admin Password:", server.adminPass) 42 | print("Networks:", server.networks) 43 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/session_persistence.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | clb = pyrax.cloud_loadbalancers 30 | 31 | try: 32 | lb = clb.list()[0] 33 | except IndexError: 34 | print("You do not have any load balancers yet.") 35 | print("Please create one and then re-run this script.") 36 | sys.exit() 37 | 38 | print("Load Balancer:", lb) 39 | orig = lb.session_persistence 40 | print("Current setting of session persistence:", orig or '""') 41 | print() 42 | if orig: 43 | print("Clearing...") 44 | lb.session_persistence = "" 45 | else: 46 | print("Setting persistence to HTTP_COOKIE...") 47 | lb.session_persistence = "HTTP_COOKIE" 48 | print("New setting of session persistence:", lb.session_persistence or '""') 49 | -------------------------------------------------------------------------------- /samples/cloud_dns/add_ptr_records.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | cs = pyrax.cloudservers 33 | 34 | # Substitute an actual server ID here 35 | server_id = "00000000-0000-0000-0000-000000000000" 36 | server = cs.servers.get(server_id) 37 | 38 | # Substitute your actual domain name and IP addresses here 39 | domain_name = "abc.example.edu" 40 | ipv4_rec = {"name": domain_name, 41 | "type": "PTR", 42 | "data": "1.2.3.4", 43 | "ttl": 7200} 44 | ipv6_rec = {"name": domain_name, 45 | "type": "PTR", 46 | "data": "2001:000::0", 47 | "ttl": 7200} 48 | 49 | recs = dns.add_ptr_records(server, [ipv4_rec, ipv6_rec]) 50 | print(recs) 51 | print() 52 | -------------------------------------------------------------------------------- /samples/queueing/delete_queue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | queues = pq.list() 32 | if not queues: 33 | print("There are no queues to delete.") 34 | exit() 35 | 36 | print("Queues:") 37 | for pos, queue in enumerate(queues): 38 | print("%s - %s" % (pos, queue.name)) 39 | snum = six.moves.input("Enter the number of the queue to delete: ") 40 | if not snum: 41 | exit() 42 | try: 43 | num = int(snum) 44 | except ValueError: 45 | print("'%s' is not a valid number." % snum) 46 | exit() 47 | if not 0 <= num < len(queues): 48 | print("'%s' is not a valid queue number." % snum) 49 | exit() 50 | pq.delete(queues[num]) 51 | print("Queue '%s' has been deleted." % queue.name) 52 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/get_usage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import datetime 22 | import os 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | clb = pyrax.cloud_loadbalancers 30 | 31 | # Get load balancer usage 32 | usage = clb.get_usage() 33 | print("Usage for Account:", usage["accountId"]) 34 | print() 35 | print("Account Usage Records") 36 | print("-" * 30) 37 | au_recs = usage["accountUsage"] 38 | for rec_key in au_recs.keys()[:5]: 39 | recs = au_recs[rec_key] 40 | if len(recs) > 5: 41 | print("(only the first 5 records...)") 42 | print(recs[:5]) 43 | print() 44 | print("Load Balancer Usage Records") 45 | print("-" * 30) 46 | lb_recs = usage["loadBalancerUsages"] 47 | if len(lb_recs) > 5: 48 | print("(only the first 5 records...)") 49 | for rec in lb_recs[:5]: 50 | print(rec) 51 | print() 52 | -------------------------------------------------------------------------------- /samples/cloudservers/create_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | cs = pyrax.cloudservers 29 | servers = cs.servers.list() 30 | srv_dict = {} 31 | print("Select a server from which an image will be created.") 32 | for pos, srv in enumerate(servers): 33 | print("%s: %s" % (pos, srv.name)) 34 | srv_dict[str(pos)] = srv.id 35 | selection = None 36 | while selection not in srv_dict: 37 | if selection is not None: 38 | print(" -- Invalid choice") 39 | selection = six.moves.input("Enter the number for your choice: ") 40 | 41 | server_id = srv_dict[selection] 42 | print() 43 | nm = six.moves.input("Enter a name for the image: ") 44 | 45 | img_id = cs.servers.create_image(server_id, nm) 46 | 47 | print("Image '%s' is being created. Its ID is: %s" % (nm, img_id)) 48 | -------------------------------------------------------------------------------- /samples/cloud_dns/list_ptr_records.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | cs = pyrax.cloudservers 33 | 34 | # Be sure to substitute an actual server ID here 35 | server_id = "00000000-0000-0000-0000-000000000000" 36 | server = cs.servers.get(server_id) 37 | 38 | ptr_records = dns.list_ptr_records(server) 39 | if ptr_records: 40 | for ptr_record in ptr_records: 41 | print("PTR Record:") 42 | print(" ID:", ptr_record.id) 43 | print(" name:", ptr_record.name) 44 | print(" data:", ptr_record.data) 45 | print(" TTL:", ptr_record.ttl) 46 | print(" comment:", ptr_record.comment) 47 | else: 48 | print("There are no PTR records for device '%s'." % server) 49 | print() 50 | -------------------------------------------------------------------------------- /samples/cloud_dns/list_domains.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | dns = pyrax.cloud_dns 31 | 32 | PAGE_SIZE = 10 33 | count = 0 34 | 35 | def print_domains(domains): 36 | for domain in domains: 37 | print("Domain:", domain.name) 38 | print(" email:", domain.emailAddress) 39 | print(" created:", domain.created) 40 | print() 41 | 42 | domains = dns.list(limit=PAGE_SIZE) 43 | count += len(domains) 44 | print_domains(domains) 45 | 46 | # Loop until all domains are printed 47 | while True: 48 | try: 49 | domains = dns.list_next_page() 50 | count += len(domains) 51 | except exc.NoMoreResults: 52 | break 53 | print_domains(domains) 54 | 55 | print("There were a total of %s domain(s)." % count) 56 | -------------------------------------------------------------------------------- /samples/cloud_dns/delete_all_subdomains.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | 33 | domain_name = "abc.example.edu" 34 | count = 0 35 | try: 36 | dom = dns.find(name=domain_name) 37 | except exc.NotFound: 38 | print("There is no DNS information for the domain '%s'." % domain_name) 39 | sys.exit() 40 | 41 | sub_iter = dns.get_subdomain_iterator(dom) 42 | for sub in sub_iter: 43 | sub.delete() 44 | count += 1 45 | 46 | if not count: 47 | print("There were no subdomains to delete.") 48 | else: 49 | if count == 1: 50 | print("The one subdomain of '%s' has been deleted." % domain_name) 51 | else: 52 | print("All %s subdomains of '%s' have been deleted." % (count, domain_name)) 53 | print() 54 | -------------------------------------------------------------------------------- /samples/cloudfiles/store_object.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cf = pyrax.cloudfiles 28 | 29 | cont_name = pyrax.utils.random_ascii(8) 30 | cont = cf.create_container(cont_name) 31 | obj_name = pyrax.utils.random_ascii(8) 32 | 33 | text = "This is some text containing unicode like é, ü and ˚¬∆ç" 34 | obj = cf.store_object(cont, obj_name, text) 35 | 36 | # Verify that the object is there 37 | print("Stored Object Name:", obj.name) 38 | print("Size:", obj.total_bytes 39 | ) 40 | # Make sure that the content stored is identical 41 | stored_text = obj.get() 42 | print("Original text:", text) 43 | print(" Stored text:", stored_text) 44 | if stored_text == text: 45 | print("Stored text is identical") 46 | else: 47 | print("Difference detected!") 48 | print("Original:", text) 49 | print("Stored:", stored_text 50 | ) 51 | # Clean up 52 | cont.delete(True) 53 | -------------------------------------------------------------------------------- /pyrax.spec.in: -------------------------------------------------------------------------------- 1 | %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} 2 | 3 | Name: pyrax 4 | Version: @VERSION@ 5 | Release: @RELEASE@%{?dist} 6 | Summary: Python language bindings for OpenStack Clouds 7 | 8 | License: ASLv2 9 | URL: https://github.com/rackerlabs/pyrax 10 | Source0: %{name}-%{version}.tar.gz 11 | 12 | BuildArch: noarch 13 | BuildRequires: python-setuptools 14 | BuildRequires: python-mock 15 | Requires: python-novaclient >= 2.13.0 16 | Requires: python-swiftclient >= 1.5.0 17 | Requires: python-httplib2 18 | Requires: python-keyring 19 | 20 | 21 | %description 22 | A library for working with most OpenStack-based cloud deployments, though it 23 | originally targeted the Rackspace public cloud. For example, the code for 24 | cloudfiles contains the ability to publish your content on Rackspace's CDN 25 | network, even though CDN support is not part of OpenStack Swift. But if you 26 | don't use any of the CDN-related code, your app will work fine on any 27 | standard Swift deployment. 28 | 29 | 30 | %package rackspace 31 | Summary: Bring in the bits that work with Rackspace's Cloud 32 | Requires: pyrax 33 | Requires: rackspace-novaclient 34 | 35 | %description rackspace 36 | The Rackspace Cloud has additional libraries that are required to access 37 | all the things. This package just makes sure they are available for pyrax. 38 | 39 | %prep 40 | %setup -q 41 | 42 | 43 | %build 44 | 45 | 46 | %install 47 | rm -rf $RPM_BUILD_ROOT 48 | %{__python} setup.py install --root $RPM_BUILD_ROOT 49 | 50 | %files 51 | %{python_sitelib}/* 52 | #%{_bindir}/ 53 | 54 | %changelog 55 | * Fri Sep 6 2013 Greg Swift - 1.5.0-1 56 | - Initial spec 57 | -------------------------------------------------------------------------------- /samples/cloudservers/delete_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cs = pyrax.cloudservers 31 | all_images = cs.images.list() 32 | images = [img for img in all_images if hasattr(img, "server")] 33 | if not images: 34 | print("There are no images to delete. Create one, and then re-run this script.") 35 | print() 36 | sys.exit() 37 | img_dict = {} 38 | print("Select an image to delete:") 39 | for pos, img in enumerate(images): 40 | print("%s: %s" % (pos, img.name)) 41 | img_dict[str(pos)] = img 42 | selection = None 43 | while selection not in img_dict: 44 | if selection is not None: 45 | print(" -- Invalid choice") 46 | selection = six.moves.input("Enter the number for your choice: ") 47 | 48 | image = img_dict.get(selection) 49 | cs.images.delete(image.id) 50 | print("Image '%s' has been deleted." % image.name) 51 | -------------------------------------------------------------------------------- /tests/unit/test_service_catalog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import unittest 5 | 6 | from mock import MagicMock as Mock 7 | 8 | import six 9 | 10 | import pyrax.utils as utils 11 | import pyrax.exceptions as exc 12 | from pyrax import service_catalog 13 | 14 | from pyrax import fakes 15 | 16 | fake_url = "http://example.com" 17 | 18 | 19 | class ServiceCatalogTest(unittest.TestCase): 20 | def __init__(self, *args, **kwargs): 21 | super(ServiceCatalogTest, self).__init__(*args, **kwargs) 22 | 23 | def setUp(self): 24 | self.service_catalog = service_catalog.ServiceCatalog( 25 | fakes.fake_identity_response) 26 | 27 | def tearDown(self): 28 | self.service_catalog = None 29 | 30 | def test_get_token(self): 31 | sc = self.service_catalog 32 | tok = sc.get_token() 33 | self.assertEqual(len(tok), 36) 34 | 35 | def test_url_for_no_catalog(self): 36 | sc = self.service_catalog 37 | sc.catalog = {"access": {}} 38 | ret = sc.url_for() 39 | self.assertIsNone(ret) 40 | 41 | def test_url_for_no_match(self): 42 | sc = self.service_catalog 43 | self.assertRaises(exc.EndpointNotFound, sc.url_for, 44 | service_type="test") 45 | 46 | def test_url_for_ambiguous(self): 47 | sc = self.service_catalog 48 | self.assertRaises(exc.AmbiguousEndpoints, sc.url_for, 49 | service_type="object-store") 50 | 51 | def test_url_for_object_store(self): 52 | sc = self.service_catalog 53 | ret = sc.url_for(service_type="object-store", attr="region", 54 | filter_value="DFW") 55 | self.assertTrue(isinstance(ret, six.string_types)) 56 | self.assertTrue("http" in ret) 57 | 58 | 59 | if __name__ == "__main__": 60 | unittest.main() 61 | -------------------------------------------------------------------------------- /samples/cloud_dns/delete_all_records.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | 33 | domain_name = "abc.example.edu" 34 | count = 0 35 | try: 36 | dom = dns.find(name=domain_name) 37 | except exc.NotFound: 38 | print("There is no DNS information for the domain '%s'." % domain_name) 39 | sys.exit() 40 | 41 | sub_iter = dns.get_record_iterator(dom) 42 | for sub in sub_iter: 43 | if sub.type == "NS": 44 | # Don't delete these; they are required 45 | continue 46 | sub.delete() 47 | count += 1 48 | 49 | if not count: 50 | print("There were no non-NS records to delete.") 51 | else: 52 | if count == 1: 53 | print("The one non-NS record for '%s' has been deleted." % domain_name) 54 | else: 55 | print("All %s non-NS records for '%s' have been deleted." % (count, 56 | domain_name)) 57 | print() 58 | -------------------------------------------------------------------------------- /samples/cloud_dns/update_ptr_record.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | dns = pyrax.cloud_dns 32 | cs = pyrax.cloudservers 33 | 34 | # Be sure to substitute an actual server ID here 35 | server_id = "00000000-0000-0000-0000-000000000000" 36 | server = cs.servers.get(server_id) 37 | 38 | domain_name = "abc.example.edu" 39 | records = dns.list_ptr_records(server) 40 | if not records: 41 | print("There are no PTR records for device '%s' to update." % server) 42 | sys.exit() 43 | rec = records[0] 44 | orig_ttl = rec.ttl 45 | orig_data = rec.data 46 | # Add 5 minutes 47 | new_ttl = orig_ttl + 300 48 | resp = dns.update_ptr_record(server, rec, domain_name, ttl=new_ttl, 49 | data=orig_data, comment="TTL has been increased") 50 | 51 | if resp: 52 | print("Original TTL:", orig_ttl) 53 | print("New TTL:", new_ttl) 54 | else: 55 | print("Update failed.") 56 | print() 57 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/ssl_termination.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | clb = pyrax.cloud_loadbalancers 30 | 31 | try: 32 | lb = clb.list()[0] 33 | except IndexError: 34 | print("You do not have any load balancers yet.") 35 | print("Please create one and then re-run this script.") 36 | sys.exit() 37 | 38 | orig = lb.get_ssl_termination() 39 | print("Current setting of SSL Termination:", orig) 40 | print() 41 | 42 | if orig: 43 | print("Updating SSL Termination info...") 44 | curr_enabled = orig["enabled"] 45 | new_enabled = not curr_enabled 46 | lb.update_ssl_termination(enabled=new_enabled) 47 | else: 48 | print("Adding SSL Termination info...") 49 | lb.add_ssl_termination(securePort=443, secureTrafficOnly=False, 50 | certificate="dummy_certificate", privatekey="dummy_private_key") 51 | print() 52 | print("New setting of SSL Termination:", lb.get_ssl_termination()) 53 | -------------------------------------------------------------------------------- /samples/cloud_databases/create_instance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cdb = pyrax.cloud_databases 31 | instance_name = pyrax.utils.random_ascii(8) 32 | 33 | flavors = cdb.list_flavors() 34 | nm = six.moves.input("Enter a name for your new instance: ") 35 | print() 36 | print("Available Flavors:") 37 | for pos, flavor in enumerate(flavors): 38 | print("%s: %s, %s" % (pos, flavor.name, flavor.ram)) 39 | 40 | flav = int(six.moves.input("Select a Flavor for your new instance: ")) 41 | try: 42 | selected = flavors[flav] 43 | except IndexError: 44 | print("Invalid selection; exiting.") 45 | sys.exit() 46 | 47 | print() 48 | sz = int(six.moves.input("Enter the volume size in GB (1-50): ")) 49 | 50 | instance = cdb.create(nm, flavor=selected, volume=sz) 51 | print("Name:", instance.name) 52 | print("ID:", instance.id) 53 | print("Status:", instance.status) 54 | print("Flavor:", instance.flavor.name) 55 | -------------------------------------------------------------------------------- /samples/cloud_monitoring/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import sys 22 | import six 23 | 24 | def option_chooser(options, attr=None): 25 | """Given an iterable, enumerate its contents for a user to choose from. 26 | If the optional `attr` is not None, that attribute in each iterated 27 | object will be printed. 28 | 29 | This function will exit the program if the user chooses the escape option. 30 | """ 31 | for num, option in enumerate(options): 32 | if attr: 33 | print("%s: %s" % (num, getattr(option, attr))) 34 | else: 35 | print("%s: %s" % (num, option)) 36 | # Add an escape option 37 | escape_opt = num + 1 38 | print("%s: I want to exit!" % escape_opt) 39 | choice = six.moves.input("Selection: ") 40 | try: 41 | ichoice = int(choice) 42 | if ichoice > escape_opt: 43 | raise ValueError 44 | except ValueError: 45 | print("Valid entries are the numbers 0-%s. Received '%s'." % (escape_opt, 46 | choice)) 47 | sys.exit() 48 | 49 | if ichoice == escape_opt: 50 | print("Bye!") 51 | sys.exit() 52 | 53 | return ichoice 54 | -------------------------------------------------------------------------------- /samples/cloud_databases/delete_instance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cdb = pyrax.cloud_databases 31 | 32 | instances = cdb.list() 33 | if not instances: 34 | print("There are no cloud database instances to delete.") 35 | sys.exit() 36 | 37 | print() 38 | print("Available Instances:") 39 | for pos, inst in enumerate(instances): 40 | print("%s: %s (%s, RAM=%s, volume=%s) Status=%s" % (pos, inst.name, 41 | inst.flavor.name, inst.flavor.ram, inst.volume.size, inst.status)) 42 | try: 43 | sel = int(six.moves.input("Enter the number of the instance to delete: ")) 44 | except ValueError: 45 | print() 46 | print("Invalid (non-numeric) entry.") 47 | print() 48 | sys.exit() 49 | try: 50 | del_inst = instances[sel] 51 | except IndexError: 52 | print() 53 | print("Invalid selection.") 54 | print() 55 | sys.exit() 56 | 57 | del_inst.delete() 58 | print() 59 | print("Instance %s has been deleted." % del_inst.name) 60 | print() 61 | -------------------------------------------------------------------------------- /samples/autoscale/delete_scaling_group.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | au = pyrax.autoscale 29 | cs = pyrax.cloudservers 30 | 31 | # Get the current scaling groups 32 | sgs = au.list() 33 | if not sgs: 34 | print("There are no scaling groups defined.") 35 | exit() 36 | 37 | print() 38 | print("Available Scaling Groups:") 39 | for pos, sg in enumerate(sgs): 40 | print("%s - %s" % (pos, sg.name)) 41 | answer = six.moves.input("Enter the number of the scaling group to delete: ") 42 | if not answer: 43 | print("Nothing entered; exiting.") 44 | exit() 45 | try: 46 | intanswer = int(answer) 47 | except ValueError: 48 | print("'%s' is not a valid number; exiting." % answer) 49 | exit() 50 | if not 0 <= intanswer < len(sgs): 51 | print("The number '%s' does not correspond to any scaling group." % answer) 52 | exit() 53 | 54 | sg_del = sgs[intanswer] 55 | sg_del.update(min_entities=0, max_entities=0) 56 | sg_del.delete() 57 | print("Scaling group '%s' has been deleted." % sg_del.name) 58 | -------------------------------------------------------------------------------- /samples/images/accept_images.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | imgs = pyrax.images 29 | imgs.http_log_debug = True 30 | 31 | print("Listing images with pending status...") 32 | images = imgs.list(visibility="shared", member_status="pending") 33 | 34 | if not images: 35 | print("No pending images found") 36 | exit() 37 | 38 | for pos, image in enumerate(images): 39 | new_status = None 40 | print("[%s] - %s" % (pos, image.name)) 41 | choice = six.moves.input("Would you like to accept, reject or skip? " 42 | "('a', 'r', or 's'): ") 43 | if choice == 'a': 44 | new_status = 'accepted' 45 | elif choice == 'r': 46 | new_status = 'rejected' 47 | 48 | if new_status is not None: 49 | print("[%s] - %s : Updating status to %s" % (pos, image.name, new_status)) 50 | imgs.update_image_member(image.id, new_status) 51 | print("[%s] - %s : has been updated" % (pos, image.name)) 52 | else: 53 | print("[%s] - %s : Skipping update" % (pos, image.name)) 54 | -------------------------------------------------------------------------------- /samples/cloudservers/create_with_meta_and_files.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cs = pyrax.cloudservers 28 | 29 | ubu_image = [img for img in cs.images.list() 30 | if "12.04" in img.name][0] 31 | flavor_1GB = [flavor for flavor in cs.flavors.list() 32 | if flavor.ram == 1024][0] 33 | 34 | meta = {"test_key": "test_value", 35 | "meaning_of_life": "42", 36 | } 37 | 38 | content = """This is the contents of the text file. 39 | It has several lines of text. 40 | 41 | And it even has a blank line.""" 42 | 43 | files = {"/root/testfile": content} 44 | 45 | server = cs.servers.create("meta_server", ubu_image.id, flavor_1GB.id, 46 | meta=meta, files=files) 47 | print("Name:", server.name) 48 | print("ID:", server.id) 49 | print("Admin Password:", server.adminPass) 50 | print("Metadata:", server.metadata) 51 | print() 52 | print("When the server becomes active, shell in as root with the admin password.") 53 | print("Verify that the file '/root/testfile' exists, and contains the exact " 54 | "content") 55 | print("that was defined above.") 56 | print() 57 | -------------------------------------------------------------------------------- /samples/cloudfiles/container_cdn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cf = pyrax.cloudfiles 28 | 29 | cont_name = pyrax.utils.random_ascii() 30 | cont = cf.create_container(cont_name) 31 | print("Container:", cont) 32 | print("Before Making Public") 33 | print("cdn_enabled", cont.cdn_enabled) 34 | print("cdn_ttl", cont.cdn_ttl) 35 | print("cdn_log_retention", cont.cdn_log_retention) 36 | print("cdn_uri", cont.cdn_uri) 37 | print("cdn_ssl_uri", cont.cdn_ssl_uri) 38 | print("cdn_streaming_uri", cont.cdn_streaming_uri) 39 | print("cdn_ios_uri", cont.cdn_ios_uri 40 | ) 41 | # Make it public 42 | cont.make_public(ttl=1200) 43 | 44 | # Now re-check the container's attributes 45 | cont = cf.get_container(cont_name) 46 | print() 47 | print("After Making Public") 48 | print("cdn_enabled", cont.cdn_enabled) 49 | print("cdn_ttl", cont.cdn_ttl) 50 | print("cdn_log_retention", cont.cdn_log_retention) 51 | print("cdn_uri", cont.cdn_uri) 52 | print("cdn_ssl_uri", cont.cdn_ssl_uri) 53 | print("cdn_streaming_uri", cont.cdn_streaming_uri) 54 | print("cdn_ios_uri", cont.cdn_ios_uri 55 | ) 56 | # clean up 57 | cont.delete() 58 | -------------------------------------------------------------------------------- /samples/cloudfiles/upload_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | import pyrax.utils as utils 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cf = pyrax.cloudfiles 31 | 32 | cont_name = pyrax.utils.random_ascii(8) 33 | cont = cf.create_container(cont_name) 34 | 35 | text = """First Line 36 | Indented Second Line 37 | Last Line""" 38 | # pyrax has a utility for creating temporary local files that clean themselves up. 39 | with utils.SelfDeletingTempfile() as tmpname: 40 | print("Creating text file with the following content:") 41 | print("-" * 44) 42 | print(text) 43 | print("-" * 44) 44 | with open(tmpname, "w") as tmp: 45 | tmp.write(text) 46 | nm = os.path.basename(tmpname) 47 | print() 48 | print("Uploading file: %s" % nm) 49 | cf.upload_file(cont, tmpname, content_type="text/text") 50 | # Let's verify that the file is there 51 | obj = cont.get_object(nm) 52 | print() 53 | print("Stored Object:", obj) 54 | print("Retrieved Content:") 55 | print("-" * 44) 56 | # Get the contents 57 | print(obj.get()) 58 | print("-" * 44 59 | ) 60 | # Clean up 61 | cont.delete(True) 62 | -------------------------------------------------------------------------------- /samples/cloud_blockstorage/create_snapshot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cbs = pyrax.cloud_blockstorage 31 | vol_name = pyrax.utils.random_ascii(length=8) 32 | vol = cbs.create(name="sample_volume", size=500, volume_type="SATA") 33 | 34 | snap = vol.create_snapshot("sample_snap") 35 | 36 | print("Volume:", vol) 37 | print("Snapshot:", snap) 38 | print() 39 | print("You have to wait until the snapshot finishes being created before") 40 | print("it can be deleted. Press Ctrl-C to interrupt.") 41 | try: 42 | pyrax.utils.wait_until(snap, "status", "available", attempts=0, verbose=True) 43 | except KeyboardInterrupt: 44 | print() 45 | print("Process interrupted.") 46 | print("Be sure to manually delete this snapshot when it completes.") 47 | sys.exit(0) 48 | print() 49 | print("Deleting snapshot...") 50 | snap.delete() 51 | try: 52 | vol.delete() 53 | except exc.VolumeNotAvailable: 54 | print("Could not delete volume; snapshot deletion has not completed yet.") 55 | print("Please be sure to delete the volume manually.") 56 | print() 57 | print("Done.") 58 | -------------------------------------------------------------------------------- /samples/cloudfiles/delete_objects.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import time 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cf = pyrax.cloudfiles 31 | 32 | cont_name = pyrax.utils.random_ascii(8) 33 | cont = cf.create_container(cont_name) 34 | fname = "soon_to_vanish.txt" 35 | text = "X" * 2056 36 | 37 | # Create a file in the container 38 | cont.store_object(fname, text) 39 | 40 | # Verify that it's there. 41 | obj = cont.get_object(fname) 42 | print("Object present, size =", obj.total_bytes 43 | ) 44 | # Delete it! 45 | obj.delete() 46 | start = time.time() 47 | 48 | # See if it's still there; if not, this should raise an exception 49 | # Generally this happens quickly, but an object may appear to remain 50 | # in a container for a short period of time after calling delete(). 51 | while obj: 52 | try: 53 | obj = cont.get_object(fname) 54 | print("...still there...") 55 | time.sleep(0.5) 56 | except exc.NoSuchObject: 57 | obj = None 58 | print("Object '%s' has been deleted" % fname) 59 | print("It took %4.2f seconds to appear as deleted." % (time.time() - start) 60 | ) 61 | # Clean up 62 | cont.delete(True) 63 | -------------------------------------------------------------------------------- /tests/unit/test_exceptions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import pickle 5 | import unittest 6 | 7 | from mock import MagicMock as Mock 8 | 9 | import pyrax.utils as utils 10 | import pyrax.exceptions as exc 11 | 12 | from pyrax import fakes 13 | 14 | fake_url = "http://example.com" 15 | 16 | 17 | class ExceptionsTest(unittest.TestCase): 18 | def __init__(self, *args, **kwargs): 19 | super(ExceptionsTest, self).__init__(*args, **kwargs) 20 | 21 | def setUp(self): 22 | pass 23 | 24 | def tearDown(self): 25 | pass 26 | 27 | def test_from_response_no_body(self): 28 | fake_resp = fakes.FakeResponse() 29 | fake_resp.status_code = 666 30 | ret = exc.from_response(fake_resp, None) 31 | self.assertTrue(isinstance(ret, exc.ClientException)) 32 | self.assertEqual(ret.code, fake_resp.status_code) 33 | 34 | def test_from_response_with_body(self): 35 | fake_resp = fakes.FakeResponse() 36 | fake_resp.status_code = 666 37 | fake_body = {"error": { 38 | "message": "fake_message", 39 | "details": "fake_details"}} 40 | ret = exc.from_response(fake_resp, fake_body) 41 | self.assertTrue(isinstance(ret, exc.ClientException)) 42 | self.assertEqual(ret.code, fake_resp.status_code) 43 | self.assertEqual(ret.message, "fake_message") 44 | self.assertEqual(ret.details, "fake_details") 45 | self.assertTrue("HTTP 666" in str(ret)) 46 | 47 | def test_pickle(self): 48 | error = exc.NotFound(42, 'message', 'details', 0xDEADBEEF) 49 | 50 | pickled_error = pickle.dumps(error, -1) 51 | unpickled_error = pickle.loads(pickled_error) 52 | 53 | self.assertIsInstance(unpickled_error, exc.NotFound) 54 | self.assertEqual(unpickled_error.code, 42) 55 | self.assertEqual(unpickled_error.message, 'message') 56 | self.assertEqual(unpickled_error.details, 'details') 57 | self.assertEqual(unpickled_error.request_id, 0xDEADBEEF) 58 | 59 | 60 | if __name__ == "__main__": 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /samples/images/list_images_filtered.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | imgs = pyrax.images 28 | 29 | print("Filtering on visibility='private'") 30 | images = imgs.list(visibility="private") 31 | if not images: 32 | print("No images exist.") 33 | exit() 34 | print("There are %s images with visibility='private':" % len(images)) 35 | for image in images: 36 | print(" (%s) %s (ID=%s)" % (image.visibility, image.name, image.id)) 37 | 38 | print("-" * 66) 39 | print("Filtering on name='Ubuntu 13.10 (Saucy Salamander)'") 40 | images = imgs.list(name="Ubuntu 13.10 (Saucy Salamander)") 41 | if not images: 42 | print("No images exist.") 43 | exit() 44 | print("There are %s images with name=Ubuntu 13.10 (Saucy Salamander):" % 45 | len(images)) 46 | for image in images: 47 | print(" (%s) %s (ID=%s)" % (image.visibility, image.name, image.id)) 48 | 49 | print("-" * 66) 50 | print("Filtering on size_min > 1000000000") 51 | images = imgs.list(size_min=1000000000) 52 | if not images: 53 | print("No images exist.") 54 | exit() 55 | print("There are %s images with size_min > 1000000000:" % len(images)) 56 | for image in images: 57 | print(" (%s) %s (ID=%s)" % (image.size, image.name, image.id)) 58 | -------------------------------------------------------------------------------- /samples/cloud_dns/add_records.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | import pyrax.exceptions as exc 27 | 28 | 29 | pyrax.set_setting("identity_type", "rackspace") 30 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 31 | pyrax.set_credential_file(creds_file) 32 | dns = pyrax.cloud_dns 33 | 34 | domain_name = "abc.example.edu" 35 | 36 | try: 37 | dom = dns.find(name=domain_name) 38 | except exc.NotFound: 39 | answer = six.moves.input("The domain '%s' was not found. Do you want to create " 40 | "it? [y/n]" % domain_name) 41 | if not answer.lower().startswith("y"): 42 | sys.exit() 43 | try: 44 | dom = dns.create(name=domain_name, emailAddress="sample@example.edu", 45 | ttl=900, comment="sample domain") 46 | except exc.DomainCreationFailed as e: 47 | print("Domain creation failed:", e) 48 | print("Domain created:", dom) 49 | print() 50 | 51 | # Substitute your actual domain name and IP addresses here 52 | a_rec = {"type": "A", 53 | "name": domain_name, 54 | "data": "1.2.3.4", 55 | "ttl": 6000} 56 | mx_rec = {"type": "MX", 57 | "name": domain_name, 58 | "data": "mail.example.edu", 59 | "priority": 50, 60 | "comment": "Backup mail server"} 61 | recs = dom.add_records([a_rec, mx_rec]) 62 | print(recs) 63 | print() 64 | -------------------------------------------------------------------------------- /samples/cloud_loadbalancers/add_remove_node.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import time 23 | 24 | import pyrax 25 | 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | clb = pyrax.cloud_loadbalancers 31 | 32 | lb = clb.list()[0] 33 | print() 34 | print("Load Balancer:", lb) 35 | print() 36 | print("Current nodes:", lb.nodes 37 | ) 38 | # You may have to adjust the address of the node to something on 39 | # the same internal network as your load balancer. 40 | new_node = clb.Node(address="10.177.1.2", port=80, condition="ENABLED") 41 | lb.add_nodes([new_node]) 42 | pyrax.utils.wait_until(lb, "status", "ACTIVE", interval=1, attempts=30, 43 | verbose=True) 44 | 45 | print() 46 | print("After adding node:", lb.nodes 47 | ) 48 | # Now remove that node. Note that we can't use the original node instance, 49 | # as it was created independently, and doesn't have the link to its load 50 | # balancer. Instead, we'll get the last node from the load balancer. 51 | added_node = [node for node in lb.nodes 52 | if node.address == new_node.address][0] 53 | print() 54 | print("Added Node:", added_node) 55 | added_node.delete() 56 | pyrax.utils.wait_until(lb, "status", "ACTIVE", interval=1, attempts=30, 57 | verbose=True) 58 | print() 59 | print("After removing node:", lb.nodes) 60 | -------------------------------------------------------------------------------- /samples/cloudfiles/fetch_objects.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import pyrax 23 | 24 | pyrax.set_setting("identity_type", "rackspace") 25 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 26 | pyrax.set_credential_file(creds_file) 27 | cf = pyrax.cloudfiles 28 | 29 | cont_name = pyrax.utils.random_ascii(8) 30 | cont = cf.create_container(cont_name) 31 | obj_name = pyrax.utils.random_ascii(8) 32 | 33 | text = "This is some text containing unicode characters like é, ü and ˚¬∆ç" * 100 34 | obj = cf.store_object(cont, obj_name, text) 35 | 36 | # Make sure that the content stored is identical 37 | print("Using obj.get()") 38 | stored_text = obj.get() 39 | if stored_text == text: 40 | print("Stored text is identical") 41 | else: 42 | print("Difference detected!") 43 | print("Original:", text) 44 | print("Stored:", stored_text 45 | ) 46 | # Let's look at the metadata for the stored object 47 | meta, stored_text = obj.get(include_meta=True) 48 | print() 49 | print("Metadata:", meta 50 | ) 51 | # Demonstrate chunked retrieval 52 | print() 53 | print("Using chunked retrieval") 54 | obj_generator = obj.get(chunk_size=256) 55 | joined_text = "".join(obj_generator) 56 | if joined_text == text: 57 | print("Joined text is identical") 58 | else: 59 | print("Difference detected!") 60 | print("Original:", text) 61 | print("Joined:", joined_text 62 | ) 63 | # Clean up 64 | cont.delete(True) 65 | -------------------------------------------------------------------------------- /samples/cloud_dns/create_subdomain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | import pyrax.exceptions as exc 27 | 28 | 29 | pyrax.set_setting("identity_type", "rackspace") 30 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 31 | pyrax.set_credential_file(creds_file) 32 | dns = pyrax.cloud_dns 33 | 34 | domain_name = "abc.example.edu" 35 | try: 36 | dom = dns.find(name=domain_name) 37 | except exc.NotFound as e: 38 | answer = six.moves.input("The domain '%s' was not found. Do you want to create " 39 | "it? [y/n]" % domain_name) 40 | if not answer.lower().startswith("y"): 41 | sys.exit() 42 | try: 43 | dom = dns.create(name=domain_name, emailAddress="sample@example.edu", 44 | ttl=900, comment="sample domain") 45 | except exc.DomainCreationFailed as e: 46 | print("Domain creation failed:", e) 47 | print() 48 | sys.exit() 49 | print("Domain created:", dom) 50 | print() 51 | 52 | sub_name = "sub.%s" % domain_name 53 | try: 54 | sub = dns.create(name=sub_name, emailAddress="sample@example.edu", ttl=900, 55 | comment="sample subdomain") 56 | except exc.DomainCreationFailed as e: 57 | print("Could not create '%s': %s" % (sub_name, e)) 58 | print() 59 | sys.exit() 60 | 61 | print("Subdomain '%s' successfully created." % sub_name) 62 | print(sub) 63 | print() 64 | -------------------------------------------------------------------------------- /samples/cloudfiles/container_metadata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import time 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cf = pyrax.cloudfiles 31 | 32 | cont_name = pyrax.utils.random_ascii() 33 | cont = cf.create_container(cont_name) 34 | print("Container:", cont 35 | ) 36 | # Get the existing metadata, if any 37 | meta = cf.get_container_metadata(cont) 38 | print("Initial metadata:", meta 39 | ) 40 | # Create a dict of metadata. Make one key with the required prefix, 41 | # and the other without, to illustrate how pyrax will 'massage' 42 | # the keys to include the require prefix. 43 | new_meta = {"X-Container-Meta-City": "Springfield", 44 | "Famous_Family": "Simpsons"} 45 | print() 46 | print("Setting container metadata to:", new_meta) 47 | cf.set_container_metadata(cont, new_meta) 48 | 49 | # Verify that the new metadata has been set for both keys. 50 | meta = cf.get_container_metadata(cont) 51 | print("Updated metadata:", meta 52 | ) 53 | # Now remove the city key 54 | print() 55 | print("Removing meta key for 'city'") 56 | cf.remove_container_metadata_key(cont, "city") 57 | 58 | # Verify that the key has been removed. 59 | meta = cf.get_container_metadata(cont) 60 | print("After removing key:", meta 61 | ) 62 | # Clean up 63 | cont.delete(True) 64 | -------------------------------------------------------------------------------- /samples/queueing/list_claims.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | 27 | print("Sorry, this hasn't been implemented yet.") 28 | exit() 29 | 30 | pyrax.set_setting("identity_type", "rackspace") 31 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 32 | pyrax.set_credential_file(creds_file) 33 | pq = pyrax.queues 34 | 35 | queues = pq.list() 36 | if not queues: 37 | print("There are no queues to post to. Please create one before proceeding.") 38 | exit() 39 | 40 | if len(queues) == 1: 41 | queue = queues[0] 42 | print("Only one queue available; using '%s'." % queue.name) 43 | else: 44 | print("Queues:") 45 | for pos, queue in enumerate(queues): 46 | print("%s - %s" % (pos, queue.name)) 47 | snum = six.moves.input("Enter the number of the queue you wish to list " 48 | "messages from: ") 49 | if not snum: 50 | exit() 51 | try: 52 | num = int(snum) 53 | except ValueError: 54 | print("'%s' is not a valid number." % snum) 55 | exit() 56 | if not 0 <= num < len(queues): 57 | print("'%s' is not a valid queue number." % snum) 58 | exit() 59 | queue = queues[num] 60 | claims = pq.list_claims(queue) 61 | if not claims: 62 | print("There are no claims available in this queue.") 63 | exit() 64 | for claim in claims: 65 | print("ID:", claim.id) 66 | print(claim) 67 | print() 68 | -------------------------------------------------------------------------------- /samples/cloud_monitoring/create_alarm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | sys.path.insert(0, os.path.abspath(os.pardir)) 25 | 26 | import pyrax 27 | 28 | from util import option_chooser 29 | 30 | pyrax.set_setting("identity_type", "rackspace") 31 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 32 | pyrax.set_credential_file(creds_file) 33 | cm = pyrax.cloud_monitoring 34 | 35 | # We need the IP address of the entity for this check 36 | ents = cm.list_entities() 37 | if not ents: 38 | print("You must create an entity before you can create a notification.") 39 | sys.exit() 40 | print("Select the entity on which you wish to create the notification:") 41 | ent = option_chooser(ents, attr="name") 42 | entity = ents[ent] 43 | print(entity 44 | ) 45 | checks = entity.list_checks() 46 | print("Select a check to notify about:") 47 | check_num = option_chooser(checks, attr="label") 48 | check = checks[check_num] 49 | 50 | plans = cm.list_notification_plans() 51 | plan_num = option_chooser(plans, attr="label") 52 | plan = plans[plan_num] 53 | 54 | # Create an alarm which causes your notification plan's `warning` to be 55 | # notified whenever the average ping time goes over 5 seconds. Otherwise, 56 | # the status will be `ok`. 57 | alarm = cm.create_alarm(entity, check, plan, 58 | ("if (rate(metric['average']) > 5) { return new AlarmStatus(WARNING); } " 59 | "return new AlarmStatus(OK);"), label="sample alarm") 60 | 61 | print("Created Alarm %s" % alarm.id) 62 | -------------------------------------------------------------------------------- /samples/cloudfiles/object_metadata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import time 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cf = pyrax.cloudfiles 31 | 32 | cont_name = pyrax.utils.random_ascii(8) 33 | cont = cf.create_container(cont_name) 34 | oname = pyrax.utils.random_ascii(8) 35 | obj = cont.store_object(oname, "some text") 36 | 37 | # Get the existing metadata, if any 38 | meta = cf.get_object_metadata(cont, obj) 39 | print("Initial metadata:", meta 40 | ) 41 | # Create a dict of metadata. Make one key with the required prefix, 42 | # and the other without, to illustrate how pyrax will 'massage' 43 | # the keys to include the require prefix. 44 | new_meta = {"X-Object-Meta-City": "Springfield", 45 | "Famous_Family": "Simpsons"} 46 | print() 47 | print("Adding metadata:", new_meta) 48 | cf.set_object_metadata(cont, obj, new_meta) 49 | 50 | # Verify that the new metadata has been set for both keys. 51 | meta = cf.get_object_metadata(cont, obj) 52 | print("Updated metadata:", meta 53 | ) 54 | # Now remove the city key 55 | print() 56 | print("Removing meta key for 'city'") 57 | cf.remove_object_metadata_key(cont, obj, "city") 58 | 59 | # Verify that the key has been removed. 60 | meta = cf.get_object_metadata(cont, obj) 61 | print("After removing key:", meta 62 | ) 63 | # Clean up 64 | cont.delete(True) 65 | -------------------------------------------------------------------------------- /samples/cloudservers/reboot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cs = pyrax.cloudservers 31 | 32 | servers = cs.servers.list() 33 | # Find the first 'ACTIVE' server 34 | try: 35 | active = [server for server in servers 36 | if server.status == "ACTIVE"][0] 37 | except IndexError: 38 | print("There are no active servers in your account.") 39 | print("Please create one before running this script.") 40 | sys.exit() 41 | # Display server info 42 | print("Server Name:", active.name) 43 | print("Server ID:", active.id) 44 | print("Server Status:", active.status) 45 | print() 46 | answer = six.moves.input("Do you wish to reboot this server? [y/n] ") 47 | if answer.strip().lower()[0] == "y": 48 | print() 49 | print("A 'soft' reboot attempts a graceful shutdown and restart of your " 50 | "server.") 51 | print("A 'hard' reboot power cycles your server.") 52 | answer = six.moves.input("Which type of reboot do you want to do? [s/h] ") 53 | answer = answer.strip().lower()[0] 54 | reboot_type = {"s": "soft", "h": "hard"}[answer] 55 | active.reboot(reboot_type) 56 | # Reload the server 57 | after_reboot = cs.servers.get(active.id) 58 | print() 59 | print("After reboot command") 60 | print("Server Status =", after_reboot.status) 61 | -------------------------------------------------------------------------------- /samples/cloud_databases/add_database.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import sys 24 | 25 | import pyrax 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cdb = pyrax.cloud_databases 31 | 32 | instances = cdb.list() 33 | if not instances: 34 | print("There are no cloud database instances.") 35 | print("Please create one and re-run this script.") 36 | sys.exit() 37 | 38 | print() 39 | print("Available Instances:") 40 | for pos, inst in enumerate(instances): 41 | print("%s: %s (%s, RAM=%s, volume=%s) Status=%s" % (pos, inst.name, 42 | inst.flavor.name, inst.flavor.ram, inst.volume.size, inst.status)) 43 | try: 44 | sel = int(six.moves.input( 45 | "Enter the number of the instance to which you want to add a database: " 46 | )) 47 | except ValueError: 48 | print() 49 | print("Invalid (non-numeric) entry.") 50 | print() 51 | sys.exit() 52 | try: 53 | inst = instances[sel] 54 | except IndexError: 55 | print() 56 | print("Invalid selection.") 57 | print() 58 | sys.exit() 59 | 60 | prompt = "Enter the name of the new database to create in this instance: " 61 | nm = six.moves.input(prompt) 62 | db = inst.create_database(nm) 63 | 64 | dbs = inst.list_databases() 65 | print() 66 | print("Database %s has been created." % nm) 67 | print("Current databases for instance '%s':" % inst.name) 68 | for db in dbs: 69 | print(db.name) 70 | print() 71 | -------------------------------------------------------------------------------- /samples/images/add_image_member.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | imgs = pyrax.images 30 | 31 | print("You will need a valid project_id for the member you wish to add.") 32 | images = imgs.list(visibility="private") 33 | 34 | if len(images) == 1: 35 | image = images[0] 36 | print("Only one image available; using '%s'." % image.name) 37 | else: 38 | print("Images:") 39 | for pos, image in enumerate(images): 40 | print("[%s] - %s" % (pos, image.name)) 41 | snum = six.moves.input("Enter the number of the image you want to share: ") 42 | if not snum: 43 | exit() 44 | try: 45 | num = int(snum) 46 | except ValueError: 47 | print("'%s' is not a valid number." % snum) 48 | exit() 49 | if not 0 <= num < len(images): 50 | print("'%s' is not a valid image number." % snum) 51 | exit() 52 | image = images[num] 53 | 54 | project_id = six.moves.input("Enter the project ID of the member you wish to " 55 | "share this image with: ") 56 | if not project_id: 57 | print("No project ID entered; exiting.") 58 | exit() 59 | imgs.http_log_debug = True 60 | member = imgs.add_image_member(image, project_id) 61 | print("The following member was added:") 62 | print(" ID: %s" % member.id) 63 | print(" Status: %s" % member.status) 64 | print(" Created at: %s" % member.created_at) 65 | -------------------------------------------------------------------------------- /samples/cloud_monitoring/create_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | 24 | sys.path.insert(0, os.path.abspath(os.pardir)) 25 | 26 | import pyrax 27 | 28 | from util import option_chooser 29 | 30 | pyrax.set_setting("identity_type", "rackspace") 31 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 32 | pyrax.set_credential_file(creds_file) 33 | cm = pyrax.cloud_monitoring 34 | 35 | # We need the IP address of the entity for this check 36 | ents = cm.list_entities() 37 | if not ents: 38 | print("You must create an entity before you can create a notification.") 39 | sys.exit() 40 | print("Select the entity on which you wish to create the notification:") 41 | ent = option_chooser(ents, attr="name") 42 | entity = ents[ent] 43 | print(entity 44 | ) 45 | aliases = entity.ip_addresses.items() 46 | print("Select an IP address to check") 47 | interface = option_chooser(aliases) 48 | alias = aliases[interface][0] 49 | 50 | # cm.list_check_types() would provide all available check types. 51 | # However, this sample will use the most basic type: remote.ping 52 | 53 | # List the available Monitoring Zones 54 | zones = cm.list_monitoring_zones() 55 | print("Select a Monitoring Zone:") 56 | zone_choice = option_chooser(zones, attr="label") 57 | zone = zones[zone_choice] 58 | 59 | # Create the check 60 | chk = cm.create_check(entity, label="sample_check", check_type="remote.ping", 61 | details={"count": 5}, monitoring_zones_poll=[zone], 62 | period=60, timeout=20, target_alias=alias) 63 | 64 | print("Name:", chk.name) 65 | print("ID:", chk.id) 66 | -------------------------------------------------------------------------------- /samples/queueing/post_message.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | queues = pq.list() 32 | if not queues: 33 | print("There are no queues to post to. Please create one before proceeding.") 34 | exit() 35 | 36 | if len(queues) == 1: 37 | queue = queues[0] 38 | print("Only one queue available; using '%s'." % queue.nam) 39 | else: 40 | print("Queues:") 41 | for pos, queue in enumerate(queues): 42 | print("%s - %s" % (pos, queue.name)) 43 | snum = six.moves.input("Enter the number of the queue you wish to post a " 44 | "message to: ") 45 | if not snum: 46 | exit() 47 | try: 48 | num = int(snum) 49 | except ValueError: 50 | print("'%s' is not a valid number." % snu) 51 | exit() 52 | if not 0 <= num < len(queues): 53 | print("'%s' is not a valid queue number." % snu) 54 | exit() 55 | queue = queues[num] 56 | msg = six.moves.input("Enter the message to post: ") 57 | sttl = six.moves.input("Enter a TTL for the message, or just press Enter for the " 58 | "default of 14 days: ") 59 | if not sttl: 60 | ttl = None 61 | else: 62 | try: 63 | ttl = int(sttl) 64 | except ValueError: 65 | print("'%s' is not a valid number." % stt) 66 | exit() 67 | pq.post_message(queue, msg, ttl=ttl) 68 | print("Your message has been posted.") 69 | -------------------------------------------------------------------------------- /samples/cloudfiles/temporary_url.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import requests 23 | import time 24 | 25 | import pyrax 26 | import pyrax.exceptions as exc 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | cf = pyrax.cloudfiles 32 | 33 | cont_name = pyrax.utils.random_ascii(8) 34 | cont = cf.create_container(cont_name) 35 | oname = pyrax.utils.random_ascii(8) 36 | ipsum = """Import integration functools test dunder object explicit. Method 37 | integration mercurial unit import. Future integration decorator pypy method 38 | tuple unit pycon. Django raspberrypi mercurial 2to3 cython scipy. Cython 39 | raspberrypi exception pypy object. Cython integration functools 2to3 object. 40 | Future raspberrypi exception 2to3. Dunder integration community goat import 41 | jinja exception science. Kwargs integration diversity 2to3 dunder future 42 | functools. Import integration itertools 2to3 cython pycon unit tuple.""" 43 | print("Creating an object...") 44 | obj = cont.store_object(oname, ipsum) 45 | 46 | print("Getting the TempURL...") 47 | # Get the existing TempURL key 48 | curr_key = cf.get_temp_url_key() 49 | if not curr_key: 50 | # Create one. 51 | cf.set_temp_url_key() 52 | 53 | # Create the Temporary URL 54 | temp_url = obj.get_temp_url(seconds=60) 55 | print("Temporary URL") 56 | print(temp_url) 57 | print() 58 | 59 | # Now try downloading it 60 | print("Downloading the TempURL...") 61 | resp = requests.get(temp_url) 62 | content = resp.content 63 | print("Downloaded content == stored content: ", content == ipsum 64 | ) 65 | # Clean up 66 | cf.set_temp_url_key(curr_key) 67 | cont.delete(True) 68 | -------------------------------------------------------------------------------- /samples/cloud_dns/list_records.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | import pyrax.exceptions as exc 27 | 28 | 29 | pyrax.set_setting("identity_type", "rackspace") 30 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 31 | pyrax.set_credential_file(creds_file) 32 | dns = pyrax.cloud_dns 33 | 34 | PAGE_SIZE = 10 35 | count = 0 36 | domain_name = "abc.example.edu" 37 | 38 | def print_records(records): 39 | for record in records: 40 | print("Record:", record.type) 41 | print(" ID:", record.id) 42 | print(" data:", record.data) 43 | print(" TTL:", record.ttl) 44 | print(" comment:", record.comment) 45 | print() 46 | 47 | try: 48 | dom = dns.find(name=domain_name) 49 | except exc.NotFound: 50 | answer = six.moves.input("The domain '%s' was not found. Do you want to create " 51 | "it? [y/n]" % domain_name) 52 | if not answer.lower().startswith("y"): 53 | sys.exit() 54 | try: 55 | dom = dns.create(name=domain_name, emailAddress="sample@example.edu", 56 | ttl=900, comment="sample domain") 57 | except exc.DomainCreationFailed as e: 58 | print("Domain creation failed:", e) 59 | print("Domain created:", dom) 60 | print() 61 | 62 | records = dom.list_records(limit=PAGE_SIZE) 63 | count += len(records) 64 | print_records(records) 65 | 66 | # Loop until all records are printed 67 | while True: 68 | try: 69 | records = dns.list_records_next_page() 70 | count += len(records) 71 | except exc.NoMoreResults: 72 | break 73 | print_records(records) 74 | 75 | print("There were a total of %s record(s)." % count) 76 | print() 77 | -------------------------------------------------------------------------------- /samples/cloud_dns/list_subdomains.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | import pyrax 26 | import pyrax.exceptions as exc 27 | 28 | 29 | pyrax.set_setting("identity_type", "rackspace") 30 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 31 | pyrax.set_credential_file(creds_file) 32 | dns = pyrax.cloud_dns 33 | 34 | PAGE_SIZE = 10 35 | count = 0 36 | domain_name = "abc.example.edu" 37 | 38 | def print_domains(domains): 39 | for domain in domains: 40 | print("Domain:", domain.name) 41 | print(" email:", domain.emailAddress) 42 | print(" created:", domain.created) 43 | print() 44 | 45 | try: 46 | dom = dns.find(name=domain_name) 47 | except exc.NotFound: 48 | answer = six.moves.input("The domain '%s' was not found. Do you want to create " 49 | "it? [y/n]" % domain_name) 50 | if not answer.lower().startswith("y"): 51 | sys.exit() 52 | try: 53 | dom = dns.create(name=domain_name, emailAddress="sample@example.edu", 54 | ttl=900, comment="sample domain") 55 | except exc.DomainCreationFailed as e: 56 | print("Domain creation failed:", e) 57 | print("Domain created:", dom) 58 | print() 59 | 60 | subdomains = dom.list_subdomains(limit=PAGE_SIZE) 61 | count += len(subdomains) 62 | print_domains(subdomains) 63 | 64 | # Loop until all subdomains are printed 65 | while True: 66 | try: 67 | subdomains = dns.list_subdomains_next_page() 68 | count += len(subdomains) 69 | except exc.NoMoreResults: 70 | break 71 | print_domains(subdomains) 72 | 73 | print("There were a total of %s subdomain(s)." % count) 74 | subs = dom.list_subdomains() 75 | print(subs) 76 | -------------------------------------------------------------------------------- /samples/cloud_monitoring/create_notification.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import six 24 | 25 | sys.path.insert(0, os.path.abspath(os.pardir)) 26 | 27 | import pyrax 28 | 29 | from util import option_chooser 30 | 31 | pyrax.set_setting("identity_type", "rackspace") 32 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 33 | pyrax.set_credential_file(creds_file) 34 | cm = pyrax.cloud_monitoring 35 | 36 | # We need the IP address of the entity for this check 37 | ents = cm.list_entities() 38 | if not ents: 39 | print("You must create an entity before you can create a notification.") 40 | sys.exit() 41 | print("Select the entity on which you wish to create the notification:") 42 | ent = option_chooser(ents, attr="name") 43 | entity = ents[ent] 44 | print(entity 45 | ) 46 | checks = entity.list_checks() 47 | print("Select a check to notify about:") 48 | check_num = option_chooser(checks, attr="label") 49 | check = checks[check_num] 50 | 51 | # cm.list_notification_types() would provide all available check types. 52 | # However, this sample will use the most basic type: email 53 | 54 | email = six.moves.input("Enter the email address to be notified at: ") 55 | 56 | # Create the notification 57 | notif = cm.create_notification("email", label="sample email", 58 | details={"address": email}) 59 | 60 | # You may want to set different notifications to different states. 61 | # This sample just sets the same for all as a simple example. 62 | np = cm.create_notification_plan(label="sample notification plan", 63 | ok_state=notif, warning_state=notif, critical_state=notif) 64 | 65 | print("Created Notification %s" % notif.id) 66 | print("Added %s to Notification Plan %s" % (notif.id, np.id)) 67 | -------------------------------------------------------------------------------- /samples/images/delete_image_member.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | imgs = pyrax.images 29 | 30 | 31 | print("You will be able to remove members from an image (that is, unshare it)") 32 | images = imgs.list(visibility="private") 33 | 34 | images_with_members = [] 35 | for image in images: 36 | members = image.list_members() 37 | if not members: 38 | continue 39 | images_with_members.append((image, members)) 40 | 41 | if not images_with_members: 42 | print("You have no images that are shared with other members.") 43 | exit() 44 | 45 | member_index = 0 46 | to_delete = [] 47 | for image, members in images_with_members: 48 | print("Image: %s" % image.name) 49 | for member in members: 50 | print(" [%s] - %s (%s)" % (member_index, member.id, member.status)) 51 | to_delete.append(member) 52 | member_index += 1 53 | snum = six.moves.input("Enter the number of the member you wish to delete: ") 54 | if not snum: 55 | exit() 56 | try: 57 | num = int(snum) 58 | except ValueError: 59 | print("'%s' is not a valid number." % snum) 60 | exit() 61 | if not 0 <= num < member_index: 62 | print("'%s' is not a valid member number." % snum) 63 | exit() 64 | member = to_delete[num] 65 | 66 | imgs.http_log_debug = True 67 | res = imgs.delete_image_member(member.image_id, member.id) 68 | 69 | print("RES", res) 70 | # print("The following member was added:") 71 | # print(" ID: %s" % member.id) 72 | # print(" Status: %s" % member.status) 73 | # print(" Created at: %s" % member.created_at) 74 | -------------------------------------------------------------------------------- /pyrax/service_catalog.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011 OpenStack LLC. 2 | # Copyright 2011, Piston Cloud Computing, Inc. 3 | # Copyright 2012, Rackspace 4 | # 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | 20 | import pyrax.exceptions as exc 21 | 22 | 23 | class ServiceCatalog(object): 24 | """Helper methods for dealing with a Keystone Service Catalog.""" 25 | 26 | def __init__(self, resource_dict): 27 | self.catalog = resource_dict 28 | 29 | def get_token(self): 30 | """Extracts and returns the authentication token.""" 31 | return self.catalog["access"]["token"]["id"] 32 | 33 | def url_for(self, attr=None, filter_value=None, 34 | service_type=None, endpoint_type="publicURL", 35 | service_name=None, volume_service_name=None): 36 | """Fetches the public URL from the given service for 37 | a particular endpoint attribute. If none given, returns 38 | the first. See tests for sample service catalog.""" 39 | matching_endpoints = [] 40 | # We don't always get a service catalog back ... 41 | if "serviceCatalog" not in self.catalog["access"]: 42 | return None 43 | 44 | # Full catalog ... 45 | catalog = self.catalog["access"]["serviceCatalog"] 46 | for service in catalog: 47 | if service.get("type") != service_type: 48 | continue 49 | endpoints = service["endpoints"] 50 | for endpoint in endpoints: 51 | if not filter_value or endpoint.get(attr) == filter_value: 52 | endpoint["serviceName"] = service.get("name") 53 | matching_endpoints.append(endpoint) 54 | 55 | if not matching_endpoints: 56 | raise exc.EndpointNotFound() 57 | elif len(matching_endpoints) > 1: 58 | raise exc.AmbiguousEndpoints(endpoints=matching_endpoints) 59 | else: 60 | return matching_endpoints[0][endpoint_type] 61 | -------------------------------------------------------------------------------- /samples/cloudfiles/get_objects.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | 23 | import six 24 | 25 | import pyrax 26 | import pyrax.exceptions as exc 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | cf = pyrax.cloudfiles 32 | 33 | cont_name = pyrax.utils.random_ascii(8) 34 | cont = cf.create_container(cont_name) 35 | text = "File Content" 36 | 37 | # Create 5 files with a similar name 38 | for i in six.moves.range(5): 39 | nm = "series_%s" % i 40 | cont.store_object(nm, text) 41 | 42 | # Create 5 files in a "folder", with repeated single-letter names 43 | start = ord("a") 44 | end = start + 5 45 | for i in six.moves.range(start, end): 46 | chars = chr(i) * 4 47 | nm = "stuff/%s" % chars 48 | cont.store_object(nm, text) 49 | 50 | # Verify 51 | objs = cont.get_objects() 52 | print() 53 | print("Created the following objects:") 54 | for obj in objs: 55 | print(" ", obj.name) 56 | print() 57 | 58 | # Limit and marker 59 | limit = 4 60 | marker = "" 61 | objs = cont.get_objects(limit=limit, marker=marker) 62 | print("Paging 4 objects at a time") 63 | print("Paged Objects:", [obj.name for obj in objs]) 64 | marker = objs[-1].name 65 | while True: 66 | objs = cont.get_objects(limit=limit, marker=marker) 67 | if not objs: 68 | break 69 | print("Paged Objects:", [obj.name for obj in objs]) 70 | marker = objs[-1].name 71 | print() 72 | 73 | # Prefix 74 | objs = cont.get_objects(prefix="stuff") 75 | print("Objects Prefixed with 'stuff':", [obj.name for obj in objs]) 76 | print() 77 | 78 | # Delimiter 79 | objs = cont.get_objects(delimiter="/") 80 | print("Objects Delimited with '/':", [obj.name for obj in objs] 81 | ) 82 | # Clean up 83 | cont.delete(True) 84 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | Contributing to pyrax 2 | ===================== 3 | 4 | Please create all pull requests against the 'working' branch. The 5 | 'master' branch is reserved for full releases, complete with updated 6 | docs, etc. 7 | 8 | For ease of testing, please ensure that the ``tox`` module is installed. 9 | 10 | While PEP8 is generally followed, it is not treated as Holy Gospel. 11 | Practicality beats purity, and coming up with some convoluted coding to 12 | avoid a line of 82 characters is an anti-pattern. 13 | 14 | When indenting continuation lines, the standard is 2 levels (i.e., 8 15 | spaces). Please do not use "visual indentation", as it is fraught with 16 | its own issues with consistency. 17 | 18 | There are several other places where pyrax differs from the "pure" PEP8 19 | suggestions. Please remember that PEP8 is a guideline, not an absolute 20 | dictum. Here is the command I use to run the pep8 tool: 21 | 22 | :: 23 | 24 | tox -e pep8 25 | 26 | Any pull requests to address style differences between the above command 27 | and your interpretation of PEP8 will be rejected. 28 | 29 | All changes other than simple typos should be accompanied by unit tests. 30 | All changes must pass all unit tests. You can run the tests by running: 31 | 32 | :: 33 | 34 | tox -e py27 35 | 36 | For consistency's sake, use double quotes to delimit strings unless the 37 | strings contain double quote characters. 38 | 39 | Pull Request Guidelines: 40 | 41 | - All pull requests should be a single commit, so that the changes can 42 | be observed and evaluated together. Here's the best way to make that 43 | happen: 44 | 45 | - Pull from this repo's 'working' branch to your local repo. All 46 | pull requests *must* be against the 'working' branch. 47 | - Create a local branch for making your changes: 48 | 49 | - git checkout working 50 | - git checkout -b mychangebranch 51 | 52 | - Do all your testing, fixing, etc., in that branch. Make as many 53 | commits as you need as you work. 54 | - When you've completed your changes, and have added your unit tests 55 | and made sure that everything's working great, merge it back into 56 | working using the '--squash' option so that it appears as a single 57 | commit. 58 | 59 | - git checkout working 60 | - git merge --squash mychangebranch 61 | - git commit -am "Adds super powers to pyrax." 62 | - git push origin working 63 | 64 | - Now you have your changes in a single commit against your 65 | 'working' branch on GitHub, and can create the pull request. 66 | -------------------------------------------------------------------------------- /samples/queueing/list_messages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | queues = pq.list() 32 | if not queues: 33 | print("There are no queues to post to. Please create one before proceeding.") 34 | exit() 35 | 36 | if len(queues) == 1: 37 | queue = queues[0] 38 | print("Only one queue available; using '%s'." % queue.name) 39 | else: 40 | print("Queues:") 41 | for pos, queue in enumerate(queues): 42 | print("%s - %s" % (pos, queue.name)) 43 | snum = six.moves.input("Enter the number of the queue you wish to list " 44 | "messages from: ") 45 | if not snum: 46 | exit() 47 | try: 48 | num = int(snum) 49 | except ValueError: 50 | print("'%s' is not a valid number." % snum) 51 | exit() 52 | if not 0 <= num < len(queues): 53 | print("'%s' is not a valid queue number." % snum) 54 | exit() 55 | queue = queues[num] 56 | echo = claimed = False 57 | secho = six.moves.input("Do you want to include your own messages? [y/N]") 58 | if secho: 59 | echo = secho in ("Yy") 60 | sclaimed = six.moves.input("Do you want to include claimed messages? [y/N]") 61 | if sclaimed: 62 | claimed = sclaimed in ("Yy") 63 | 64 | msgs = pq.list_messages(queue, echo=echo, include_claimed=claimed) 65 | if not msgs: 66 | print("There are no messages available in this queue.") 67 | exit() 68 | for msg in msgs: 69 | print("ID:", msg.id) 70 | print("Age:", msg.age) 71 | print("TTL:", msg.ttl) 72 | print("Claim ID:", msg.claim_id) 73 | print("Body:", msg.body) 74 | print() 75 | -------------------------------------------------------------------------------- /samples/cloud_databases/add_user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import getpass 22 | import os 23 | import sys 24 | import six 25 | 26 | import pyrax 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | cdb = pyrax.cloud_databases 32 | 33 | instances = cdb.list() 34 | if not instances: 35 | print("There are no cloud database instances.") 36 | print("Please create one and re-run this script.") 37 | sys.exit() 38 | 39 | print() 40 | print("Available Instances:") 41 | for pos, inst in enumerate(instances): 42 | print("%s: %s (%s, RAM=%s, volume=%s) Status=%s" % (pos, inst.name, 43 | inst.flavor.name, inst.flavor.ram, inst.volume.size, inst.status)) 44 | try: 45 | sel = int(six.moves.input( 46 | "Enter the number of the instance to which you want to add a user: ")) 47 | except ValueError: 48 | print() 49 | print("Invalid (non-numeric) entry.") 50 | print() 51 | sys.exit() 52 | try: 53 | inst = instances[sel] 54 | except IndexError: 55 | print() 56 | print("Invalid selection.") 57 | print() 58 | sys.exit() 59 | 60 | print() 61 | nm = six.moves.input("Enter the user name: ") 62 | pw = getpass.getpass("Enter the password for this user: ") 63 | print() 64 | print("Available Databases:") 65 | dbs = inst.list_databases() 66 | for pos, db in enumerate(dbs): 67 | print("%s: %s" % (pos, db.name)) 68 | print("Enter the numbers of the databases which the user can access,", end=' ') 69 | print("separated by spaces: ", end=' ') 70 | selected = six.moves.input() 71 | selnums = [int(val) for val in selected.split()] 72 | sel_dbs = [db.name for pos, db in enumerate(dbs) 73 | if pos in selnums] 74 | 75 | user = inst.create_user(nm, pw, database_names=sel_dbs) 76 | 77 | print() 78 | print("User '%s' has been created on instance '%s'." % (nm, inst.name)) 79 | print() 80 | -------------------------------------------------------------------------------- /samples/images/export_task.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | imgs = pyrax.images 29 | cf = pyrax.cloudfiles 30 | 31 | print("You will need to select an image to export, and a Container into which " 32 | "the exported image will be placed.") 33 | images = imgs.list(visibility="private") 34 | print() 35 | print("Select an image to export:") 36 | for pos, image in enumerate(images): 37 | print("[%s] %s" % (pos, image.name)) 38 | snum = six.moves.input("Enter the number of the image you want to share: ") 39 | if not snum: 40 | exit() 41 | try: 42 | num = int(snum) 43 | except ValueError: 44 | print("'%s' is not a valid number." % snum) 45 | exit() 46 | if not 0 <= num < len(images): 47 | print("'%s' is not a valid image number." % snum) 48 | exit() 49 | image = images[num] 50 | 51 | conts = cf.list() 52 | print() 53 | print("Select the target container to place the exported image:") 54 | for pos, cont in enumerate(conts): 55 | print("[%s] %s" % (pos, cont.name)) 56 | snum = six.moves.input("Enter the number of the container: ") 57 | if not snum: 58 | exit() 59 | try: 60 | num = int(snum) 61 | except ValueError: 62 | print("'%s' is not a valid number." % snum) 63 | exit() 64 | if not 0 <= num < len(conts): 65 | print("'%s' is not a valid container number." % snum) 66 | exit() 67 | cont = conts[num] 68 | 69 | task = imgs.export_task(image, cont) 70 | print("Task ID=%s" % task.id) 71 | print() 72 | answer = six.moves.input("Do you want to track the task until completion? This " 73 | "may take several minutes. [y/N]: ") 74 | if answer and answer[0].lower() == "y": 75 | pyrax.utils.wait_until(task, "status", ["success", "failure"], 76 | verbose=True, interval=30) 77 | -------------------------------------------------------------------------------- /samples/queueing/delete_message.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | queues = pq.list() 32 | if not queues: 33 | print("There are no queues to post to. Please create one before proceeding.") 34 | exit() 35 | 36 | if len(queues) == 1: 37 | queue = queues[0] 38 | print("Only one queue available; using '%s'." % queue.name) 39 | else: 40 | print("Queues:") 41 | for pos, queue in enumerate(queues): 42 | print("%s - %s" % (pos, queue.name)) 43 | snum = six.moves.input("Enter the number of the queue you wish to list " 44 | "messages from: ") 45 | if not snum: 46 | exit() 47 | try: 48 | num = int(snum) 49 | except ValueError: 50 | print("'%s' is not a valid number." % snum) 51 | exit() 52 | if not 0 <= num < len(queues): 53 | print("'%s' is not a valid queue number." % snum) 54 | exit() 55 | queue = queues[num] 56 | echo = claimed = True 57 | msgs = pq.list_messages(queue, echo=echo, include_claimed=claimed) 58 | if not msgs: 59 | print("There are no messages available in this queue.") 60 | exit() 61 | for pos, msg in enumerate(msgs): 62 | msg.get() 63 | print(pos, "- ID:", msg.id, msg.claim_id, "Body='%s'" % msg.body[:80]) 64 | snum = six.moves.input("Enter the number of the message you wish to delete: ") 65 | if not snum: 66 | print("No message selected; exiting.") 67 | exit() 68 | try: 69 | num = int(snum) 70 | except ValueError: 71 | print("'%s' is not a valid number." % snum) 72 | exit() 73 | if not 0 <= num < len(msgs): 74 | print("'%s' is not a valid message number." % snum) 75 | exit() 76 | msg_to_delete = msgs[num] 77 | msg_to_delete.delete() 78 | print() 79 | print("The message has been deleted.") 80 | -------------------------------------------------------------------------------- /samples/cloudservers/delete_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import sys 23 | import time 24 | import six 25 | 26 | import pyrax 27 | 28 | pyrax.set_setting("identity_type", "rackspace") 29 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 30 | pyrax.set_credential_file(creds_file) 31 | cs = pyrax.cloudservers 32 | 33 | def create_server(): 34 | print("Creating the sacrificial server...") 35 | img = cs.list_images()[0] 36 | flv = cs.list_flavors()[0] 37 | srv = cs.servers.create("sacrifice", img.id, flv.id) 38 | print("Server '%s' created; ID=%s" % (srv.name, srv.id)) 39 | return srv 40 | 41 | print() 42 | print("Looking for a server named 'sacrifice' to delete...") 43 | try: 44 | sacrifice = cs.servers.find(name="sacrifice") 45 | print("Found server named 'sacrifice'.") 46 | except Exception as e: 47 | print("No server named 'sacrifice' exists, so for safety reasons this") 48 | print("script will not do anything potentially destructive.") 49 | print() 50 | answer = six.moves.input("Do you want to create that server now? [y/n] ") 51 | if answer.strip().lower()[0] == "y": 52 | sacrifice = create_server() 53 | else: 54 | print("The server will not be created.") 55 | sys.exit() 56 | 57 | if sacrifice.status != "ACTIVE": 58 | print("Please wait until the 'sacrifice' server is in ACTIVE status.") 59 | print("Current status:", sacrifice.status) 60 | raw_answer = six.moves.input("Do you want this script to cycle every 10 " 61 | "seconds to check? [y/n] ") 62 | answer = raw_answer[0].lower() 63 | if answer != "y": 64 | sys.exit() 65 | print("Waiting... (press CTRL-C to stop)") 66 | while sacrifice.status != "ACTIVE": 67 | time.sleep(10) 68 | sacrifice = cs.servers.get(sacrifice.id) 69 | print("Status is '%s' at %s" % (sacrifice.status, time.ctime())) 70 | print() 71 | print("The server is now active. You may re-run this script to delete it.") 72 | sys.exit() 73 | 74 | print("Deleting 'sacrifice' server...", end=' ') 75 | sacrifice.delete() 76 | print(" Done!") 77 | -------------------------------------------------------------------------------- /samples/cloud_blockstorage/attach_detach_volume.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import sys 24 | 25 | import pyrax 26 | 27 | pyrax.set_setting("identity_type", "rackspace") 28 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 29 | pyrax.set_credential_file(creds_file) 30 | cs = pyrax.cloudservers 31 | cbs = pyrax.cloud_blockstorage 32 | 33 | try: 34 | server = cs.servers.find(name="sample_server") 35 | except cs.exceptions.NotFound as e: 36 | print() 37 | print("Before running this sample, create a server named 'sample_server' ") 38 | print("and wait for it to be in an ACTIVE state.") 39 | prompt = "Do you wish to have this server created for you? [y/N]" 40 | answer = six.moves.input(prompt) 41 | if answer.lower().startswith("y"): 42 | ubu_image = [img for img in cs.images.list() 43 | if "Ubuntu" in img.name][0] 44 | flavor_1GB = [flavor for flavor in cs.flavors.list() 45 | if flavor.ram == 1024][0] 46 | print("Creating the server...") 47 | server = cs.servers.create("sample_server", ubu_image.id, flavor_1GB.id) 48 | print("Server created; waiting for it to become active...") 49 | pyrax.utils.wait_until(server, "status", "ACTIVE", attempts=0, 50 | verbose=True) 51 | else: 52 | sys.exit() 53 | 54 | # Create a 100GB SATA volume, and attach it to the server 55 | vol = cbs.create(name="sample_volume", size=100, volume_type="SATA") 56 | print("New volume:", vol.name) 57 | print("Attaching to:", server) 58 | print("It may take several seconds for the attachment to complete.") 59 | vol.attach_to_instance(server, mountpoint="/dev/xvdd") 60 | pyrax.utils.wait_until(vol, "status", "in-use", interval=3, attempts=0, 61 | verbose=True) 62 | print("Volume attachments:", vol.attachments) 63 | 64 | # Now detach the volume 65 | print() 66 | print("Detaching the volume...") 67 | vol.detach() 68 | pyrax.utils.wait_until(vol, "status", "available", interval=3, attempts=0, 69 | verbose=True) 70 | print("Attachments:", vol.attachments) 71 | 72 | # Delete the volume 73 | vol.delete() 74 | print("Deleted") 75 | -------------------------------------------------------------------------------- /samples/queueing/delete_messages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | queues = pq.list() 32 | if not queues: 33 | print("There are no queues to post to. Please create one before proceeding.") 34 | exit() 35 | 36 | if len(queues) == 1: 37 | queue = queues[0] 38 | print("Only one queue available; using '%s'." % queue.name) 39 | else: 40 | print("Queues:") 41 | for pos, queue in enumerate(queues): 42 | print("%s - %s" % (pos, queue.name)) 43 | snum = six.moves.input("Enter the number of the queue you wish to list " 44 | "messages from: ") 45 | if not snum: 46 | exit() 47 | try: 48 | num = int(snum) 49 | except ValueError: 50 | print("'%s' is not a valid number." % snum) 51 | exit() 52 | if not 0 <= num < len(queues): 53 | print("'%s' is not a valid queue number." % snum) 54 | exit() 55 | queue = queues[num] 56 | echo = claimed = True 57 | msgs = pq.list_messages(queue, echo=echo, include_claimed=claimed) 58 | if not msgs: 59 | print("There are no messages available in this queue.") 60 | exit() 61 | for pos, msg in enumerate(msgs): 62 | msg.get() 63 | print(pos, "- ID:", msg.id, msg.claim_id, "Body='%s'" % msg.body[:80]) 64 | snums = six.moves.input("Enter one or more numbers of the messages you wish to " 65 | "delete, separated by spaces: ") 66 | if not snums: 67 | print("No messages selected; exiting.") 68 | exit() 69 | nums = [int(num) for num in snums.split()] 70 | ids = [msg.id for msg in msgs if msgs.index(msg) in nums] 71 | if not ids: 72 | print("No messages match your selections; exiting.") 73 | exit() 74 | print("DEL", pq.delete_messages_by_ids(queue, ids)) 75 | del_msgs = [msg for msg in msgs if msg.id in ids] 76 | 77 | print() 78 | print("The following messages were deleted:") 79 | for del_msg in del_msgs: 80 | print(del_msg.id, "Body='%s'" % del_msg.body) 81 | -------------------------------------------------------------------------------- /samples/autoscale/add_policy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | au = pyrax.autoscale 29 | 30 | def safe_int(val, allow_zero=True): 31 | """ 32 | This function converts the six.moves.input values to integers. It handles 33 | invalid entries, and optionally forbids values of zero. 34 | """ 35 | try: 36 | ret = int(val) 37 | except ValueError: 38 | print("Sorry, '%s' is not a valid integer." % val) 39 | return False 40 | if not allow_zero and ret == 0: 41 | print("Please enter a non-zero integer.") 42 | return False 43 | return ret 44 | 45 | # Get the current scaling groups 46 | sgs = au.list() 47 | if not sgs: 48 | print("There are no scaling groups defined. Please run the " 49 | "'create_scaling_group.py' script first.") 50 | exit() 51 | 52 | print() 53 | print("Available Scaling Groups:") 54 | for pos, sg in enumerate(sgs): 55 | print("%s - %s" % (pos, sg.name)) 56 | answer = six.moves.input("Enter the number of the scaling group you wish to add a " 57 | "policy to: ") 58 | if not answer: 59 | print("Nothing entered; exiting.") 60 | exit() 61 | intanswer = safe_int(answer) 62 | if not 0 <= intanswer < len(sgs): 63 | print("The number '%s' does not correspond to any scaling group." % answer) 64 | exit() 65 | sg = sgs[intanswer] 66 | 67 | pname = "" 68 | while not pname: 69 | pname = six.moves.input("Enter a name for this policy: ") 70 | 71 | cooldown = 0 72 | while not cooldown: 73 | cooldown_input = six.moves.input("Enter a cooldown period in seconds: ") 74 | cooldown = safe_int(cooldown_input, False) 75 | 76 | change = 0 77 | while not change: 78 | change = safe_int(six.moves.input("Enter the change increment: "), False) 79 | 80 | answer = six.moves.input("Is that a percentage change? [y/N]: ") 81 | is_percent = "y" in answer.lower() 82 | 83 | policy = au.add_policy(sg, pname, "webhook", cooldown, change, is_percent) 84 | 85 | print("Policy added: %s" % policy) 86 | -------------------------------------------------------------------------------- /samples/autoscale/delete_policy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | au = pyrax.autoscale 29 | 30 | def safe_int(val, allow_zero=True): 31 | """ 32 | This function converts the six.moves.input values to integers. It handles 33 | invalid entries, and optionally forbids values of zero. 34 | """ 35 | try: 36 | ret = int(val) 37 | except ValueError: 38 | print("Sorry, '%s' is not a valid integer." % val) 39 | return False 40 | if not allow_zero and ret == 0: 41 | print("Please enter a non-zero integer.") 42 | return False 43 | return ret 44 | 45 | # Get the current scaling groups 46 | sgs = au.list() 47 | if not sgs: 48 | print("There are no scaling groups defined.") 49 | exit() 50 | 51 | print() 52 | print("Available Scaling Groups:") 53 | for pos, sg in enumerate(sgs): 54 | print("%s - %s" % (pos, sg.name)) 55 | intanswer = -1 56 | while intanswer < 0: 57 | answer = six.moves.input("Enter the number of the scaling group: ") 58 | if not answer: 59 | print("Nothing entered; exiting.") 60 | exit() 61 | intanswer = safe_int(answer) 62 | if intanswer is False: 63 | intanswer = -1 64 | continue 65 | if not 0 <= intanswer < len(sgs): 66 | print("The number '%s' does not correspond to any scaling group." % answer) 67 | intanswer = -1 68 | 69 | policies = sg.list_policies() 70 | if not policies: 71 | print("There are no policies defined for this scaling group.") 72 | exit() 73 | for pos, policy in enumerate(policies): 74 | print("%s - %s" % (pos, policy.name)) 75 | answer = six.moves.input("Enter the number of the policy to delete: ") 76 | if not answer: 77 | print("Nothing entered; exiting.") 78 | exit() 79 | intanswer = safe_int(answer) 80 | if not 0 <= intanswer < len(policies): 81 | print("The number '%s' does not correspond to any policy." % answer) 82 | exit() 83 | policy = policies[intanswer] 84 | policy.delete() 85 | print("Policy '%s' has been deleted." % policy.name) 86 | -------------------------------------------------------------------------------- /tests/unit/test_cloud_cdn.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import mock 4 | 5 | from pyrax.cloudcdn import CloudCDNClient 6 | from pyrax.cloudcdn import CloudCDNFlavor 7 | from pyrax.cloudcdn import CloudCDNFlavorManager 8 | from pyrax.cloudcdn import CloudCDNService 9 | from pyrax.cloudcdn import CloudCDNServiceManager 10 | 11 | class CloudCDNTest(unittest.TestCase): 12 | 13 | @mock.patch("pyrax.client.BaseClient.method_get") 14 | def test_ping(self, mock_get): 15 | sot = CloudCDNClient(mock.MagicMock()) 16 | sot.ping() 17 | mock_get.assert_called_with("/ping") 18 | 19 | @mock.patch("pyrax.cloudcdn.CloudCDNFlavorManager.list") 20 | def test_list_flavors(self, mock_list): 21 | sot = CloudCDNClient(mock.MagicMock()) 22 | sot.list_flavors() 23 | mock_list.assert_called_once_with() 24 | 25 | @mock.patch("pyrax.cloudcdn.CloudCDNFlavorManager.get") 26 | def test_get_flavor(self, mock_get): 27 | sot = CloudCDNClient(mock.MagicMock()) 28 | flavor = "flavor" 29 | sot.get_flavor(flavor) 30 | mock_get.assert_called_once_with(flavor) 31 | 32 | @mock.patch("pyrax.cloudcdn.CloudCDNServiceManager.list") 33 | def test_list_services(self, mock_list): 34 | sot = CloudCDNClient(mock.MagicMock()) 35 | sot.list_services() 36 | mock_list.assert_called_with(limit=None, marker=None) 37 | 38 | kwargs = {"limit": 1, "marker": 2} 39 | sot.list_services(**kwargs) 40 | mock_list.assert_called_with(**kwargs) 41 | 42 | @mock.patch("pyrax.cloudcdn.CloudCDNServiceManager.get") 43 | def test_get_service(self, mock_get): 44 | sot = CloudCDNClient(mock.MagicMock()) 45 | service = "service" 46 | sot.get_service(service) 47 | mock_get.assert_called_once_with(service) 48 | 49 | @mock.patch("pyrax.cloudcdn.CloudCDNServiceManager.create") 50 | def test_create_service(self, mock_create): 51 | sot = CloudCDNClient(mock.MagicMock()) 52 | args = (1, 2, 3, 4, 5, 6) 53 | sot.create_service(*args) 54 | mock_create.assert_called_once_with(*args) 55 | 56 | @mock.patch("pyrax.cloudcdn.CloudCDNServiceManager.patch") 57 | def test_patch_service(self, mock_patch): 58 | sot = CloudCDNClient(mock.MagicMock()) 59 | args = (1, 2) 60 | sot.patch_service(*args) 61 | mock_patch.assert_called_once_with(*args) 62 | 63 | @mock.patch("pyrax.cloudcdn.CloudCDNServiceManager.delete") 64 | def test_delete_service(self, mock_delete): 65 | sot = CloudCDNClient(mock.MagicMock()) 66 | service = "service" 67 | sot.delete_service(service) 68 | mock_delete.assert_called_once_with(service) 69 | 70 | @mock.patch("pyrax.cloudcdn.CloudCDNServiceManager.delete_assets") 71 | def test_delete_assets(self, mock_delete): 72 | sot = CloudCDNClient(mock.MagicMock()) 73 | args = (1, 2, 3) 74 | sot.delete_assets(*args) 75 | mock_delete.assert_called_once_with(*args) 76 | -------------------------------------------------------------------------------- /samples/cloud_networks/create_bastion.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | from pprint import pprint 22 | import os 23 | import six 24 | 25 | import pyrax 26 | from pyrax import utils 27 | 28 | 29 | pyrax.set_setting("identity_type", "rackspace") 30 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 31 | pyrax.set_credential_file(creds_file) 32 | cs = pyrax.cloudservers 33 | cnw = pyrax.cloud_networks 34 | new_network_name = "SAMPLE_NETWORK" 35 | new_network_cidr = "192.168.0.0/24" 36 | 37 | # These are the IDs for the image and flavor to be used 38 | img_id = "5cebb13a-f783-4f8c-8058-c4182c724ccd" 39 | flavor_id = "performance1-1" 40 | 41 | # Create the new network 42 | new_net = cnw.create(new_network_name, cidr=new_network_cidr) 43 | print("New network:", new_net 44 | ) 45 | # Create the bastion server 46 | networks = new_net.get_server_networks(public=True, private=True) 47 | bastion = cs.servers.create("bastion", img_id, flavor_id, 48 | nics=networks) 49 | print("Bastion server:", bastion.name, bastion.id 50 | ) 51 | # Create an isolated server 52 | networks = new_net.get_server_networks(public=False, private=False) 53 | isolated = cs.servers.create("isolated", img_id, flavor_id, 54 | nics=networks) 55 | print("Isolated server:", isolated.name, isolated.id 56 | ) 57 | print() 58 | print("The networks will not be visible until the servers have finished building.") 59 | print("Do you want to wait until then to see the results? It might take several") 60 | answer = six.moves.input("minutes to complete. [y/N]") 61 | if answer not in "yY": 62 | exit() 63 | 64 | bas_id = bastion.id 65 | iso_id = isolated.id 66 | pyrax.utils.wait_until(bastion, "status", ("ERROR", "ACTIVE"), attempts=0, 67 | interval=10, verbose=True) 68 | pyrax.utils.wait_until(isolated, "status", ("ERROR", "ACTIVE"), attempts=0, 69 | interval=10, verbose=True) 70 | # Refresh the objects with the latest values of the servers. 71 | bastion = cs.servers.get(bas_id) 72 | isolated = cs.servers.get(iso_id) 73 | if "ERROR" in (bastion.status, isolated.status): 74 | print("There was an error building the servers. Please try again.") 75 | exit() 76 | 77 | print("Bastion server networks:") 78 | pprint(bastion.networks) 79 | print() 80 | print("Isolated server networks:") 81 | pprint(isolated.networks) 82 | -------------------------------------------------------------------------------- /samples/cloudfiles/upload_folder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import time 23 | 24 | import six 25 | 26 | import pyrax 27 | import pyrax.exceptions as exc 28 | import pyrax.utils as utils 29 | 30 | pyrax.set_setting("identity_type", "rackspace") 31 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 32 | pyrax.set_credential_file(creds_file) 33 | cf = pyrax.cloudfiles 34 | 35 | cont_name = pyrax.utils.random_ascii(8) 36 | cont = cf.create_container(cont_name) 37 | 38 | # pyrax has a utility for creating temporary local directories that clean 39 | # themselves up. 40 | with utils.SelfDeletingTempDirectory() as tmpfolder: 41 | # Create a bunch of files 42 | for idx in six.moves.range(13): 43 | fname = "file_%s" % idx 44 | pth = os.path.join(tmpfolder, fname) 45 | with open(pth, "w") as tmp: 46 | tmp.write("This is some text") 47 | # Create a subfolder. It will be deleted automatically as part of 48 | # the cleanup of SelfDeletingTempDirectory. 49 | subfolder_path = os.path.join(tmpfolder, "subfolder") 50 | os.mkdir(subfolder_path) 51 | # Create some files in the subfolder, too. 52 | for idx in six.moves.range(7): 53 | fname = "subfile_%s" % idx 54 | pth = os.path.join(subfolder_path, fname) 55 | with open(pth, "w") as tmp: 56 | tmp.write("This is some text. " * 100) 57 | 58 | # OK, we've created our local file system. Now upload it to a container 59 | # named 'upfolder'. We'll have it skip all files ending in the digits 60 | # '2', '6' or '0'. 61 | ignore = ["*2", "*6", "*0"] 62 | print("Beginning Folder Uplaod") 63 | upload_key, total_bytes = cf.upload_folder(tmpfolder, cont, ignore=ignore) 64 | # Since upload_folder happens in the background, we need to stay in this 65 | # block until the upload is complete, or the SelfDeletingTempDirectory 66 | # will be deleted, and the upload won't find the files it needs. 67 | print("Total bytes to upload:", total_bytes) 68 | uploaded = 0 69 | while uploaded < total_bytes: 70 | uploaded = cf.get_uploaded(upload_key) 71 | print("Progress: %4.2f%%" % ((uploaded * 100.0) / total_bytes)) 72 | time.sleep(1) 73 | 74 | # OK, the upload is complete. Let's verify what's in 'upfolder'. 75 | folder_name = os.path.basename(tmpfolder) 76 | print() 77 | print("Temp folder name:", folder_name) 78 | nms = cf.get_container_object_names(cont, prefix=folder_name) 79 | print("Number of files in container:", len(nms)) 80 | print("\n".join(nms) 81 | ) 82 | # Clean up 83 | cont.delete(True) 84 | -------------------------------------------------------------------------------- /samples/images/import_task.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2014 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | imgs = pyrax.images 29 | cf = pyrax.cloudfiles 30 | 31 | print("You will need an image file stored in a Cloud Files container.") 32 | conts = cf.list() 33 | print() 34 | print("Select the container containing the image to import:") 35 | for pos, cont in enumerate(conts): 36 | print("[%s] %s" % (pos, cont.name)) 37 | snum = six.moves.input("Enter the number of the container: ") 38 | if not snum: 39 | exit() 40 | try: 41 | num = int(snum) 42 | except ValueError: 43 | print("'%s' is not a valid number." % snum) 44 | exit() 45 | if not 0 <= num < len(conts): 46 | print("'%s' is not a valid container number." % snum) 47 | exit() 48 | cont = conts[num] 49 | 50 | print() 51 | print("Select the image object:") 52 | objs = cont.get_objects() 53 | for pos, obj in enumerate(objs): 54 | print("[%s] %s" % (pos, obj.name)) 55 | snum = six.moves.input("Enter the number of the image object: ") 56 | if not snum: 57 | exit() 58 | try: 59 | num = int(snum) 60 | except ValueError: 61 | print("'%s' is not a valid number." % snum) 62 | exit() 63 | if not 0 <= num < len(objs): 64 | print("'%s' is not a valid object number." % snum) 65 | exit() 66 | obj = objs[num] 67 | 68 | fmt = six.moves.input("Enter the format of the image [VHD]: ") 69 | fmt = fmt or "VHD" 70 | base_name = os.path.splitext(os.path.basename(obj.name))[0] 71 | prompt = "Enter a name for the imported image ['%s']: " % base_name 72 | obj_name = six.moves.input(prompt) 73 | obj_name = obj_name or base_name 74 | 75 | task = imgs.import_task(obj, cont, img_format=fmt, img_name=obj_name) 76 | print("Task ID=%s" % task.id) 77 | print() 78 | answer = six.moves.input("Do you want to track the task until completion? This " 79 | "may take several minutes. [y/N]: ") 80 | if answer and answer[0].lower() == "y": 81 | pyrax.utils.wait_until(task, "status", ["success", "failure"], 82 | verbose=True, interval=30) 83 | print() 84 | if task.status == "success": 85 | print("Success!") 86 | print("Your new image:") 87 | new_img = imgs.find(name=obj_name) 88 | print(" ID: %s" % new_img.id) 89 | print(" Name: %s" % new_img.name) 90 | print(" Status: %s" % new_img.status) 91 | print(" Size: %s" % new_img.size) 92 | print(" Tags: %s" % new_img.tags) 93 | else: 94 | print("Image import failed!") 95 | print("Reason: %s" % task.message) 96 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup 4 | from setuptools.command.sdist import sdist as _sdist 5 | import re 6 | import sys 7 | import time 8 | import codecs 9 | import subprocess 10 | if sys.version < "2.2.3": 11 | from distutils.dist import DistributionMetadata 12 | DistributionMetadata.classifiers = None 13 | DistributionMetadata.download_url = None 14 | 15 | # Workaround for problems caused by this import 16 | # It's either this or hardcoding the version. 17 | # from pyrax.version import version 18 | with open("pyrax/version.py", "rt") as vfile: 19 | version_text = vfile.read() 20 | vmatch = re.search(r'version ?= ?"(.+)"$', version_text) 21 | version = vmatch.groups()[0] 22 | 23 | # When set to '0' this expands in the RPM SPEC file to a unique date-base string 24 | # Set to another value when cutting official release RPMS, then change back to 25 | # zero for the next development cycle 26 | release = '0' 27 | 28 | 29 | class sdist(_sdist): 30 | """ custom sdist command, to prep pyrax.spec file """ 31 | 32 | def run(self): 33 | global version 34 | global release 35 | 36 | # Create a development release string for later use 37 | git_head = subprocess.Popen("git log -1 --pretty=format:%h", 38 | shell=True, 39 | stdout=subprocess.PIPE).communicate()[0].strip() 40 | date = time.strftime("%Y%m%d%H%M%S", time.gmtime()) 41 | git_release = "%sgit%s" % (date, git_head) 42 | 43 | # Expand macros in pyrax.spec.in 44 | spec_in = open('pyrax.spec.in', 'r') 45 | spec = open('pyrax.spec', 'w') 46 | for line in spec_in.xreadlines(): 47 | if "@VERSION@" in line: 48 | line = line.replace("@VERSION@", version) 49 | elif "@RELEASE@" in line: 50 | # If development release, include date+githash in %{release} 51 | if release.startswith('0'): 52 | release += '.' + git_release 53 | line = line.replace("@RELEASE@", release) 54 | spec.write(line) 55 | spec_in.close() 56 | spec.close() 57 | 58 | # Run parent constructor 59 | _sdist.run(self) 60 | 61 | # Get the long description from the relevant file 62 | try: 63 | f = codecs.open('README.rst', encoding='utf-8') 64 | long_description = f.read() 65 | f.close() 66 | except: 67 | long_description = '' 68 | 69 | testing_requires = ["mock"] 70 | 71 | setup( 72 | name="pyrax", 73 | version=version, 74 | description="Python language bindings for OpenStack Clouds.", 75 | long_description=long_description, 76 | author="Rackspace", 77 | url="https://github.com/rackspace/pyrax", 78 | license='Apache License, Version 2.0', 79 | keywords="pyrax rackspace cloud openstack", 80 | classifiers=[ 81 | "Development Status :: 5 - Production/Stable", 82 | "License :: OSI Approved :: Apache Software License", 83 | "Programming Language :: Python :: 2", 84 | "Operating System :: OS Independent", 85 | ], 86 | install_requires=[ 87 | "python-novaclient==2.27.0", 88 | "rackspace-novaclient", 89 | "keyring", 90 | "requests>=2.2.1,<3", 91 | "six>=1.9.0,<2", 92 | ] + testing_requires, 93 | packages=[ 94 | "pyrax", 95 | "pyrax/identity", 96 | ], 97 | cmdclass={'sdist': sdist} 98 | ) 99 | -------------------------------------------------------------------------------- /samples/autoscale/add_webhook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | au = pyrax.autoscale 29 | 30 | def safe_int(val, allow_zero=True): 31 | """ 32 | This function converts the six.moves.input values to integers. It handles 33 | invalid entries, and optionally forbids values of zero. 34 | """ 35 | try: 36 | ret = int(val) 37 | except ValueError: 38 | print("Sorry, '%s' is not a valid integer." % val) 39 | return False 40 | if not allow_zero and ret == 0: 41 | print("Please enter a non-zero integer.") 42 | return False 43 | return ret 44 | 45 | # Get the current scaling groups 46 | sgs = au.list() 47 | if not sgs: 48 | print("There are no scaling groups defined.") 49 | exit() 50 | 51 | print() 52 | print("Available Scaling Groups:") 53 | for pos, sg in enumerate(sgs): 54 | print("%s - %s" % (pos, sg.name)) 55 | intanswer = -1 56 | while intanswer < 0: 57 | answer = six.moves.input("Enter the number of the scaling group: ") 58 | if not answer: 59 | print("Nothing entered; exiting.") 60 | exit() 61 | intanswer = safe_int(answer) 62 | if intanswer is False: 63 | intanswer = -1 64 | continue 65 | if not 0 <= intanswer < len(sgs): 66 | print("The number '%s' does not correspond to any scaling group." % answer) 67 | intanswer = -1 68 | 69 | policies = sg.list_policies() 70 | if not policies: 71 | print("There are no policies defined for this scaling group. You can only " 72 | "add webhooks to existing policies.") 73 | exit() 74 | for pos, policy in enumerate(policies): 75 | print("%s - %s" % (pos, policy.name)) 76 | answer = six.moves.input("Enter the number of the policy: ") 77 | if not answer: 78 | print("Nothing entered; exiting.") 79 | exit() 80 | intanswer = safe_int(answer) 81 | if not 0 <= intanswer < len(policies): 82 | print("The number '%s' does not correspond to any policy." % answer) 83 | exit() 84 | policy = policies[intanswer] 85 | 86 | name = "" 87 | while not name: 88 | name = six.moves.input("Enter a name for this webhook: ") 89 | 90 | metadata = {} 91 | while True: 92 | key = six.moves.input("Enter a metadata key, or press Enter to end metadata " 93 | "entry: ") 94 | if not key: 95 | break 96 | val = six.moves.input("Enter the value for the key '%s': " % key) 97 | metadata[key] = val 98 | 99 | hook = policy.add_webhook(name, metadata=metadata) 100 | 101 | print() 102 | print() 103 | print("Webhook added: %s" % hook) 104 | -------------------------------------------------------------------------------- /docs/installing_pyrax.md: -------------------------------------------------------------------------------- 1 | # Installing pyrax 2 | This document explains how to install pyrax on your system so that you can start creating cloud-based applications in Python. 3 | 4 | ## Installation with `pip` 5 | This is the preferred method, as `pip` handles all of the dependency requirements for pyrax for you. 6 | 7 | If you don't already have `pip` installed, you should follow the [pip installation instructions](http://www.pip-installer.org/en/latest/installing.html). 8 | 9 | > For all of the examples below, it is assumed that you are installing into a virtualenv, or on a system where you are logged in as the root/administrator. If that is not the case, then you probably have to run the installation under `sudo` to get administrator privileges. 10 | 11 | `pip` installs pyrax and its dependencies from one of two sources: the official packaged releases on the [Python Package Index (PyPI)](http://pypi.python.org/pypi), or from the source code repository on [GitHub](https://github.com/rackspace/pyrax). The only difference between the two is that with PyPI you can only install the latest official release of pyrax, while with GitHub you can install any branch, including the current development trunk version. Bear in mind that this option is only for developers who need the latest changes and are willing to live with occasional bugs as the code gets updated – what is commonly referred to as the "bleeding edge". 12 | 13 | To install from PyPI, run the following: 14 | 15 | pip install pyrax 16 | 17 | To install the current released version from GitHub, run: 18 | 19 | pip install git+git://github.com/rackspace/pyrax.git@latest-release 20 | 21 | To install the development trunk version from GitHub, run: 22 | 23 | pip install git+git://github.com/rackspace/pyrax.git 24 | 25 | 26 | ## Installing From Source 27 | > NOTE: some Python distributions come with versions of `distutils` that do not support the `install_requires` option to `setup.py`. If you have one of those versions, you get errors as you try to install using the steps below. The best option at this point is to use `pip` to install, as described above. 28 | 29 | Download the source code for pyrax from GitHub, and install from that. First, grab the source: 30 | 31 | curl -O https://github.com/downloads/rackspace/pyrax/pyrax-.tar.gz 32 | 33 | Then from the command line: 34 | 35 | tar zxf pyrax-.tar.gz 36 | cd pyrax- 37 | python setup.py install 38 | 39 | 40 | ## Testing the Installed Module 41 | If all goes well, pyrax and all its dependencies should be installed and ready to use. To test, open the interpreter and try it out (assuming that you have a Rackspace account): 42 | 43 | [ed@MGM6AEDV7M ~/projects]$ python 44 | Python 2.7.2 (default, Jun 20 2012, 16:23:33) 45 | [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin 46 | Type "help", "copyright", "credits" or "license" for more information. 47 | >>> import pyrax 48 | >>> pyrax.set_setting("identity_type", "rackspace") 49 | >>> pyrax.set_credentials("my_username", "my_API_key") 50 | >>> pyrax.cloudfiles.list_containers() 51 | ['photos', 'music', 'documents'] 52 | 53 | 54 | ## Updating to Future Versions 55 | `pip` makes it simple to update pyrax to the latest released version. All you need to do is add `--upgrade` to the command you used to install pyrax, and pip installs the latest version of pyrax along with the latest version of any dependencies. 56 | 57 | For a source install, you have to download the latest source, and then manually check each of the dependencies for updated releases, and if found, install them according to their directions. 58 | -------------------------------------------------------------------------------- /samples/autoscale/delete_webhook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2012 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | 25 | pyrax.set_setting("identity_type", "rackspace") 26 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 27 | pyrax.set_credential_file(creds_file) 28 | au = pyrax.autoscale 29 | 30 | def safe_int(val, allow_zero=True): 31 | """ 32 | This function converts the six.moves.input values to integers. It handles 33 | invalid entries, and optionally forbids values of zero. 34 | """ 35 | try: 36 | ret = int(val) 37 | except ValueError: 38 | print("Sorry, '%s' is not a valid integer." % val) 39 | return False 40 | if not allow_zero and ret == 0: 41 | print("Please enter a non-zero integer.") 42 | return False 43 | return ret 44 | 45 | # Get the current scaling groups 46 | sgs = au.list() 47 | if not sgs: 48 | print("There are no scaling groups defined.") 49 | exit() 50 | 51 | print() 52 | print("Available Scaling Groups:") 53 | for pos, sg in enumerate(sgs): 54 | print("%s - %s" % (pos, sg.name)) 55 | intanswer = -1 56 | while intanswer < 0: 57 | answer = six.moves.input("Enter the number of the scaling group: ") 58 | if not answer: 59 | print("Nothing entered; exiting.") 60 | exit() 61 | intanswer = safe_int(answer) 62 | if intanswer is False: 63 | intanswer = -1 64 | continue 65 | if not 0 <= intanswer < len(sgs): 66 | print("The number '%s' does not correspond to any scaling group." % answer) 67 | intanswer = -1 68 | 69 | policies = sg.list_policies() 70 | if not policies: 71 | print("There are no policies defined for this scaling group. You can only " 72 | "add webhooks to existing policies.") 73 | exit() 74 | for pos, policy in enumerate(policies): 75 | print("%s - %s" % (pos, policy.name)) 76 | answer = six.moves.input("Enter the number of the policy: ") 77 | if not answer: 78 | print("Nothing entered; exiting.") 79 | exit() 80 | intanswer = safe_int(answer) 81 | if not 0 <= intanswer < len(policies): 82 | print("The number '%s' does not correspond to any policy." % answer) 83 | exit() 84 | policy = policies[intanswer] 85 | 86 | webhooks = policy.list_webhooks() 87 | if not webhooks: 88 | print("There are no webhooks defined for this policy.") 89 | exit() 90 | for pos, webhook in enumerate(webhooks): 91 | print("%s - %s" % (pos, webhook.name)) 92 | answer = six.moves.input("Enter the number of the webhook: ") 93 | if not answer: 94 | print("Nothing entered; exiting.") 95 | exit() 96 | intanswer = safe_int(answer) 97 | if not 0 <= intanswer < len(webhooks): 98 | print("The number '%s' does not correspond to any webhook." % answer) 99 | exit() 100 | webhook = webhooks[intanswer] 101 | webhook.delete() 102 | print() 103 | print("Webhook '%s' has been deleted." % webhook.name) 104 | -------------------------------------------------------------------------------- /samples/queueing/claim_messages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c)2013 Rackspace US, Inc. 4 | 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import os 22 | import six 23 | import pyrax 24 | import pyrax.exceptions as exc 25 | 26 | pyrax.set_setting("identity_type", "rackspace") 27 | creds_file = os.path.expanduser("~/.rackspace_cloud_credentials") 28 | pyrax.set_credential_file(creds_file) 29 | pq = pyrax.queues 30 | 31 | queues = pq.list() 32 | if not queues: 33 | print("There are no queues to post to. Please create one before proceeding.") 34 | exit() 35 | 36 | if len(queues) == 1: 37 | queue = queues[0] 38 | print("Only one queue available; using '%s'." % queue.name) 39 | else: 40 | print("Queues:") 41 | for pos, queue in enumerate(queues): 42 | print("%s - %s" % (pos, queue.name)) 43 | snum = six.moves.input("Enter the number of the queue you wish to post a " 44 | "message to: ") 45 | if not snum: 46 | exit() 47 | try: 48 | num = int(snum) 49 | except ValueError: 50 | print("'%s' is not a valid number." % snum) 51 | exit() 52 | if not 0 <= num < len(queues): 53 | print("'%s' is not a valid queue number." % snum) 54 | exit() 55 | queue = queues[num] 56 | 57 | sttl = six.moves.input("Enter a TTL for the claim: ") 58 | if not sttl: 59 | print("A TTL value is required.") 60 | exit() 61 | else: 62 | try: 63 | ttl = int(sttl) 64 | if not 60 <= ttl <= 43200: 65 | old_ttl = ttl 66 | ttl = max(min(ttl, 43200), 60) 67 | print("TTL values must be between 60 and 43200 seconds; changing " 68 | "it to '%s'." % ttl) 69 | except ValueError: 70 | print("'%s' is not a valid number." % sttl) 71 | exit() 72 | 73 | sgrace = six.moves.input("Enter a grace period for the claim: ") 74 | if not sgrace: 75 | print("A value for the grace period is required.") 76 | exit() 77 | else: 78 | try: 79 | grace = int(sgrace) 80 | if not 60 <= grace <= 43200: 81 | old_grace = grace 82 | grace = max(min(grace, 43200), 60) 83 | print("Grace values must be between 60 and 43200 seconds; changing " 84 | "it to '%s'." % grace) 85 | except ValueError: 86 | print("'%s' is not a valid number." % sgrace) 87 | exit() 88 | 89 | scount = six.moves.input("Enter the number of messages to claim (max=20), or " 90 | "press Enter for the default of 10: ") 91 | if not scount: 92 | count = None 93 | else: 94 | try: 95 | count = int(scount) 96 | except ValueError: 97 | print("'%s' is not a valid number." % scount) 98 | exit() 99 | 100 | claim = pq.claim_messages(queue, ttl, grace, count=count) 101 | if not claim: 102 | print("There were no messages available to claim.") 103 | exit() 104 | num_msgs = len(claim.messages) 105 | print() 106 | print("You have successfully claimed %s messages." % num_msgs) 107 | print("Claim ID:", claim.id) 108 | for msg in claim.messages: 109 | print("Age:", msg.age) 110 | print("Body:", msg.body) 111 | print() 112 | -------------------------------------------------------------------------------- /pyrax/http.py: -------------------------------------------------------------------------------- 1 | # Copyright (c)2014 Rackspace US, Inc. 2 | 3 | # All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | """ 17 | Wrapper around the requests library. Used for making all HTTP calls. 18 | """ 19 | 20 | import logging 21 | import json 22 | import requests 23 | 24 | import pyrax 25 | import pyrax.exceptions as exc 26 | 27 | 28 | req_methods = { 29 | "HEAD": requests.head, 30 | "GET": requests.get, 31 | "POST": requests.post, 32 | "PUT": requests.put, 33 | "DELETE": requests.delete, 34 | "PATCH": requests.patch, 35 | } 36 | 37 | # NOTE: FIX THIS!!! 38 | verify_ssl = False 39 | 40 | 41 | def request(method, uri, *args, **kwargs): 42 | """ 43 | Handles all the common functionality required for API calls. Returns 44 | the resulting response object. 45 | 46 | Formats the request into a dict representing the headers 47 | and body that will be used to make the API call. 48 | """ 49 | req_method = req_methods[method.upper()] 50 | raise_exception = kwargs.pop("raise_exception", True) 51 | raw_content = kwargs.pop("raw_content", False) 52 | kwargs["headers"] = kwargs.get("headers", {}) 53 | http_log_req(method, uri, args, kwargs) 54 | data = None 55 | if "data" in kwargs: 56 | # The 'data' kwarg is used when you don't want json encoding. 57 | data = kwargs.pop("data") 58 | elif "body" in kwargs: 59 | if "Content-Type" not in kwargs["headers"]: 60 | kwargs["headers"]["Content-Type"] = "application/json" 61 | data = json.dumps(kwargs.pop("body")) 62 | if data: 63 | resp = req_method(uri, data=data, **kwargs) 64 | else: 65 | resp = req_method(uri, **kwargs) 66 | if raw_content: 67 | body = resp.content 68 | else: 69 | try: 70 | body = resp.json() 71 | except ValueError: 72 | # No JSON in response 73 | body = resp.content 74 | http_log_resp(resp, body) 75 | if resp.status_code >= 400 and raise_exception: 76 | raise exc.from_response(resp, body) 77 | return resp, body 78 | 79 | 80 | def http_log_req(method, uri, args, kwargs): 81 | """ 82 | When pyrax.get_http_debug() is True, outputs the equivalent `curl` 83 | command for the API request being made. 84 | """ 85 | if not pyrax.get_http_debug(): 86 | return 87 | string_parts = ["curl -i -X %s" % method] 88 | for element in args: 89 | string_parts.append("%s" % element) 90 | for element in kwargs["headers"]: 91 | header = "-H '%s: %s'" % (element, kwargs["headers"][element]) 92 | string_parts.append(header) 93 | string_parts.append(uri) 94 | log = logging.getLogger("pyrax") 95 | log.debug("\nREQ: %s\n" % " ".join(string_parts)) 96 | if "body" in kwargs: 97 | pyrax._logger.debug("REQ BODY: %s\n" % (kwargs["body"])) 98 | if "data" in kwargs: 99 | pyrax._logger.debug("REQ DATA: %s\n" % (kwargs["data"])) 100 | 101 | 102 | def http_log_resp(resp, body): 103 | """ 104 | When pyrax.get_http_debug() is True, outputs the response received 105 | from the API request. 106 | """ 107 | if not pyrax.get_http_debug(): 108 | return 109 | log = logging.getLogger("pyrax") 110 | log.debug("RESP: %s\n%s", resp, resp.headers) 111 | if body: 112 | log.debug("RESP BODY: %s", body) 113 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | pyrax 2 | ===== 3 | 4 | Python SDK for OpenStack/Rackspace APIs 5 | 6 | **Note: Please submit an issue before submitting a pull 7 | request so we can determine whether or not the change may be accepted. 8 | Pyrax is in the process of being deprecated in favor of the OpenStack 9 | SDK. We will announce the process and timelines for this deprecation 10 | as soon as we can.** 11 | 12 | See the LICENSE file for license and copyright information. 13 | 14 | **pyrax** should work with most OpenStack-based cloud deployments, 15 | though it specifically targets the Rackspace public cloud. For example, 16 | the code for cloudfiles contains the ability to publish your content on 17 | Rackspace's CDN network, even though CDN support is not part of 18 | OpenStack Swift. But if you don't use any of the CDN-related code, your 19 | app will work fine on any standard Swift deployment. 20 | 21 | See the `Release 22 | Notes `_ 23 | for what has changed in the latest release 24 | 25 | .. image:: https://travis-ci.org/rackspace/pyrax.svg?branch=master 26 | :target: https://travis-ci.org/rackspace/pyrax 27 | 28 | Getting Started with OpenStack/Rackspace 29 | ---------------------------------------- 30 | 31 | To sign up for a Rackspace Cloud account, go to 32 | 33 | `http://www.rackspace.com/cloud `_ 34 | 35 | and follow the prompts. 36 | 37 | If you are working with an OpenStack deployment, you can find more 38 | information at `http://www.openstack.org `_. 39 | 40 | Requirements 41 | ------------ 42 | 43 | - A Rackspace Cloud account 44 | 45 | - username 46 | - API key 47 | 48 | - Python 2.7 49 | 50 | - pyrax is not yet tested yet with other Python versions. Please 51 | post feedback about what works or does not work with other 52 | versions. See the **Support and Feedback** section below for where 53 | to post. 54 | 55 | Installation 56 | ------------ 57 | 58 | The best way to install **pyrax** is by using 59 | `pip `_ to get the latest 60 | official release: 61 | 62 | :: 63 | 64 | pip install pyrax 65 | 66 | If you would like to work with the current development state of pyrax, 67 | you can install directly from trunk on GitHub: 68 | 69 | :: 70 | 71 | pip install git+git://github.com/rackspace/pyrax.git 72 | 73 | If you are not using 74 | `virtualenv `_, you will need to 75 | run ``pip install`` as admin using ``sudo``. 76 | 77 | You may also download and install from source. The source code for 78 | **pyrax** is available on 79 | `GitHub `_. 80 | 81 | Once you have the source code, ``cd`` to the base directory of the 82 | source and run (using ``sudo``, if necessary): 83 | 84 | :: 85 | 86 | python setup.py install 87 | 88 | For more information on getting started, check out the following 89 | documentation: 90 | 91 | `https://github.com/rackspace/pyrax/blob/master/docs/getting\_started.md `_ 92 | `https://developer.rackspace.com/sdks/python/ `_ 93 | 94 | Updates 95 | ------- 96 | 97 | If you installed **pyrax** using pip, it is simple to get the latest 98 | updates from either PyPI or GitHub: 99 | 100 | :: 101 | 102 | # PyPI 103 | pip install --upgrade pyrax 104 | # GitHub 105 | pip install --upgrade git+git://github.com/rackspace/pyrax.git 106 | 107 | Contributing 108 | ------------ 109 | 110 | Please see the `HACKING `_ file for contribution guidelines. 111 | Make sure pull requests are on the ``working`` branch! 112 | 113 | Support and Feedback 114 | -------------------- 115 | 116 | You can find documentation for using the **pyrax** SDK at 117 | https://developer.rackspace.com/sdks/python/. 118 | 119 | Your feedback is appreciated! If you have specific issues with the 120 | **pyrax** SDK, developers should file an `issue via 121 | Github `_. 122 | 123 | For general feedback and support requests, contact us at 124 | https://developer.rackspace.com/support/ 125 | --------------------------------------------------------------------------------