Skip to content

Commit

Permalink
Merge branch 'working'
Browse files Browse the repository at this point in the history
  • Loading branch information
sivel committed Apr 16, 2015
2 parents d412fa9 + 0ce3f7d commit 70d5c10
Show file tree
Hide file tree
Showing 21 changed files with 738 additions and 85 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,5 @@ Your feedback is appreciated! If you have specific issues with the
**pyrax** SDK, developers should file an `issue via
Github <https://github.com/rackspace/pyrax/issues>`_.

For general feedback and support requests, send an email to:
`[email protected] <mailto:sdk-support@rackspace.com>`_.
For general feedback and support requests, contact us at
https://developer.rackspace.com/support/
31 changes: 31 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Release Notes for pyrax

### 2015.04.16 - Version 1.9.4

- Cloud CDN
- Introduced the Cloud CDN service with support for listing flavors as
well creating, updating, and deleting of services.

- Identity
- Make BaseIdentity respect `verify_ssl` # 515
- Respect the `_auth_endpoint` attribute of the identity instance for Keystone identity #522

- Cloud Monitoring
- Add ability to create agent check types #508
- Fix entity retrieval #512
- Add support for monitoring agent tokens #525

- Cloud Files
- Update documentation #519

- Cloud Databases
- PEP8 Clean Up #507

- Cloud Block Storage
- Allow renaming volumes and snapshots #506
- Do not hardcode CBS volume sizes #541

- General
- `verify_ssl` is now respected when creating a context #523
- pep8 fix ups for recent pep8 1.6 changes #540
- Replace support email address with contact page #546
- Ensure we default verify_ssl to True in the default environment

### 2014.11.24 - Version 1.9.3

- Identity
Expand Down
11 changes: 11 additions & 0 deletions docs/cloud_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,17 @@ Metadata for storage objects works exactly the same, using the analogous methods
Cloud Files makes it easy to publish your stored objects over the high-speed Akamai CDN. Content is made available at the container level. Individual files within a public container cannot be private. This may affect your storage design, so that only files you wish to have accessible to the public are stored in public containers.


### CDN default web pages

You can set a static web page as the landing page for you CND-enabled containter by calling:

cont.set_web_index_page("example-index.html")

Set the header indicating the error page in this container by calling:

cont.set_web_error_page("example-error.html")


### Publishing a Container to CDN
To publish a container to CDN, simply make the following call:

Expand Down
32 changes: 26 additions & 6 deletions pyrax/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
from novaclient.v1_1.servers import Server as CloudServer

from .autoscale import AutoScaleClient
from .cloudcdn import CloudCDNClient
from .clouddatabases import CloudDatabaseClient
from .cloudloadbalancers import CloudLoadBalancerClient
from .cloudblockstorage import CloudBlockStorageClient
Expand All @@ -84,6 +85,7 @@
# Initiate the services to None until we are authenticated.
cloudservers = None
cloudfiles = None
cloud_cdn = None
cloud_loadbalancers = None
cloud_databases = None
cloud_blockstorage = None
Expand Down Expand Up @@ -115,6 +117,7 @@

_client_classes = {
"compute": _cs_client.Client,
"cdn": CloudCDNClient,
"object_store": StorageClient,
"database": CloudDatabaseClient,
"load_balancer": CloudLoadBalancerClient,
Expand Down Expand Up @@ -169,6 +172,12 @@ class Settings(object):
_settings = {"default": dict.fromkeys(list(env_dct.keys()))}
_default_set = False

def __init__(self, *args, **kwargs):
# Default verify_ssl to True
if self._settings["default"].get("verify_ssl") is None:
self._settings["default"]["verify_ssl"] = True

super(Settings, self).__init__(*args, **kwargs)

def get(self, key, env=None):
"""
Expand Down Expand Up @@ -578,14 +587,15 @@ def authenticate(connect=True):

def clear_credentials():
"""De-authenticate by clearing all the names back to None."""
global identity, regions, services, cloudservers, cloudfiles
global identity, regions, services, cloudservers, cloudfiles, cloud_cdn
global cloud_loadbalancers, cloud_databases, cloud_blockstorage, cloud_dns
global cloud_networks, cloud_monitoring, autoscale, images, queues
identity = None
regions = tuple()
services = tuple()
cloudservers = None
cloudfiles = None
cloud_cdn = None
cloud_loadbalancers = None
cloud_databases = None
cloud_blockstorage = None
Expand All @@ -612,9 +622,10 @@ def connect_to_services(region=None):
"""Establishes authenticated connections to the various cloud APIs."""
global cloudservers, cloudfiles, cloud_loadbalancers, cloud_databases
global cloud_blockstorage, cloud_dns, cloud_networks, cloud_monitoring
global autoscale, images, queues
global autoscale, images, queues, cloud_cdn
cloudservers = connect_to_cloudservers(region=region)
cloudfiles = connect_to_cloudfiles(region=region)
cloud_cdn = connect_to_cloud_cdn(region=region)
cloud_loadbalancers = connect_to_cloud_loadbalancers(region=region)
cloud_databases = connect_to_cloud_databases(region=region)
cloud_blockstorage = connect_to_cloud_blockstorage(region=region)
Expand Down Expand Up @@ -645,7 +656,7 @@ def _get_service_endpoint(context, svc, region=None, public=True):
return ep


def connect_to_cloudservers(region=None, context=None, **kwargs):
def connect_to_cloudservers(region=None, context=None, verify_ssl=None, **kwargs):
"""Creates a client for working with cloud servers."""
context = context or identity
_cs_auth_plugin.discover_auth_systems()
Expand All @@ -660,7 +671,10 @@ def connect_to_cloudservers(region=None, context=None, **kwargs):
if not mgt_url:
# Service is not available
return
insecure = not get_setting("verify_ssl")
if verify_ssl is None:
insecure = not get_setting("verify_ssl")
else:
insecure = not verify_ssl
cs_shell = _cs_shell()
extensions = cs_shell._discover_extensions("1.1")
cloudservers = _cs_client.Client(context.username, context.password,
Expand Down Expand Up @@ -728,13 +742,14 @@ def connect_to_cloudfiles(region=None, public=None):


@_require_auth
def _create_client(ep_name, region, public=True):
def _create_client(ep_name, region, public=True, verify_ssl=None):
region = _safe_region(region)
ep = _get_service_endpoint(None, ep_name.split(":")[0], region,
public=public)
if not ep:
return
verify_ssl = get_setting("verify_ssl")
if verify_ssl is None:
verify_ssl = get_setting("verify_ssl")
cls = _client_classes[ep_name]
client = cls(identity, region_name=region, management_url=ep,
verify_ssl=verify_ssl, http_log_debug=_http_debug)
Expand All @@ -747,6 +762,11 @@ def connect_to_cloud_databases(region=None):
return _create_client(ep_name="database", region=region)


def connect_to_cloud_cdn(region=None):
"""Creates a client for working with cloud loadbalancers."""
return _create_client(ep_name="cdn", region=region)


def connect_to_cloud_loadbalancers(region=None):
"""Creates a client for working with cloud loadbalancers."""
return _create_client(ep_name="load_balancer", region=region)
Expand Down
13 changes: 7 additions & 6 deletions pyrax/base_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ def __init__(self, identity, catalog):
eps = catalog.get("endpoints", [])
for ep in eps:
rgn = ep.get("region", "ALL")
self.endpoints[rgn] = Endpoint(ep, self.service_type, rgn, identity)
self.endpoints[rgn] = Endpoint(ep, self.service_type, rgn, identity,
verify_ssl=self.identity.verify_ssl)
return


Expand Down Expand Up @@ -153,13 +154,14 @@ class Endpoint(object):
}


def __init__(self, ep_dict, service, region, identity):
def __init__(self, ep_dict, service, region, identity, verify_ssl=True):
"""
Set local attributes from the supplied dictionary.
"""
self.service = service
self.region = region
self.identity = identity
self.verify_ssl = verify_ssl
for key, val in list(ep_dict.items()):
att_name = self.attr_map.get(key, key)
setattr(self, att_name, val)
Expand Down Expand Up @@ -246,15 +248,14 @@ def _create_client(self, clt_class, url, public=True, special=False):
"""
Creates a client instance for the service.
"""
verify_ssl = pyrax.get_setting("verify_ssl")
if self.service == "compute" and not special:
# Novaclient requires different parameters.
client = pyrax.connect_to_cloudservers(region=self.region,
context=self.identity)
context=self.identity, verify_ssl=self.verify_ssl)
client.identity = self.identity
else:
client = clt_class(self.identity, region_name=self.region,
management_url=url, verify_ssl=verify_ssl)
management_url=url, verify_ssl=self.verify_ssl)
return client


Expand Down Expand Up @@ -566,7 +567,7 @@ def _call(self, mthd, uri, admin, data, headers, std_headers):
if "tokens" in uri:
# We'll handle the exception here
kwargs["raise_exception"] = False
return pyrax.http.request(mthd, uri, **kwargs)
return pyrax.http.request(mthd, uri, verify=self.verify_ssl, **kwargs)


def authenticate(self, username=None, password=None, api_key=None,
Expand Down
74 changes: 62 additions & 12 deletions pyrax/cloudblockstorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import pyrax.utils as utils


MIN_SIZE = 100
MAX_SIZE = 1024
RETRY_INTERVAL = 5


Expand Down Expand Up @@ -96,6 +94,23 @@ def delete(self):
super(CloudBlockStorageSnapshot, self).delete()


def update(self, display_name=None, display_description=None):
"""
Update the specified values on this snapshot. You may specify one or
more values to update. If no values are specified as non-None, the call
is a no-op; no exception will be raised.
"""
return self.manager.update(self, display_name=display_name,
display_description=display_description)


def rename(self, name):
"""
Allows for direct renaming of an existing snapshot.
"""
return self.update(display_name=name)


def _get_name(self):
return self.display_name

Expand Down Expand Up @@ -187,6 +202,23 @@ def delete(self, force=False):
raise


def update(self, display_name=None, display_description=None):
"""
Update the specified values on this volume. You may specify one or more
values to update. If no values are specified as non-None, the call is a
no-op; no exception will be raised.
"""
return self.manager.update(self, display_name=display_name,
display_description=display_description)


def rename(self, name):
"""
Allows for direct renaming of an existing volume.
"""
return self.update(display_name=name)


def create_snapshot(self, name=None, description=None, force=False):
"""
Creates a snapshot of this volume, with an optional name and
Expand Down Expand Up @@ -249,10 +281,11 @@ def _create_body(self, name, size=None, volume_type=None, description=None,
"""
Used to create the dict required to create a new volume
"""
if not isinstance(size, (int, long)) or not (
MIN_SIZE <= size <= MAX_SIZE):
raise exc.InvalidSize("Volume sizes must be integers between "
"%s and %s." % (MIN_SIZE, MAX_SIZE))
try:
int(size)
except:
raise exc.InvalidSize("Volume sizes must be integers")

if volume_type is None:
volume_type = "SATA"
if description is None:
Expand Down Expand Up @@ -294,7 +327,8 @@ def create(self, *args, **kwargs):
def update(self, volume, display_name=None, display_description=None):
"""
Update the specified values on the specified volume. You may specify
one or more values to update.
one or more values to update. If no values are specified as non-None,
the call is a no-op; no exception will be raised.
"""
uri = "/%s/%s" % (self.uri_base, utils.get_id(volume))
param_dict = {}
Expand Down Expand Up @@ -380,7 +414,8 @@ def create(self, name, volume, description=None, force=False):
def update(self, snapshot, display_name=None, display_description=None):
"""
Update the specified values on the specified snapshot. You may specify
one or more values to update.
one or more values to update. If no values are specified as non-None,
the call is a no-op; no exception will be raised.
"""
uri = "/%s/%s" % (self.uri_base, utils.get_id(snapshot))
param_dict = {}
Expand Down Expand Up @@ -449,12 +484,20 @@ def delete_volume(self, volume, force=False):
def update(self, volume, display_name=None, display_description=None):
"""
Update the specified values on the specified volume. You may specify
one or more values to update.
one or more values to update. If no values are specified as non-None,
the call is a no-op; no exception will be raised.
"""
return self._manager.update(volume, display_name=display_name,
return volume.update(display_name=display_name,
display_description=display_description)


def rename(self, volume, name):
"""
Allows for direct renaming of an existing volume.
"""
return self.update(volume, display_name=name)


@assure_volume
def create_snapshot(self, volume, name=None, description=None, force=False):
"""
Expand All @@ -480,12 +523,19 @@ def delete_snapshot(self, snapshot):
return snapshot.delete()


@assure_snapshot
def update_snapshot(self, snapshot, display_name=None,
display_description=None):
"""
Update the specified values on the specified snapshot. You may specify
one or more values to update.
"""
return self._snapshot_manager.update(snapshot,
display_name=display_name,
return snapshot.update(display_name=display_name,
display_description=display_description)


def rename_snapshot(self, snapshot, name):
"""
Allows for direct renaming of an existing snapshot.
"""
return self.update_snapshot(snapshot, display_name=name)
Loading

0 comments on commit 70d5c10

Please sign in to comment.