[Python-modules-commits] [python-shade] 01/02: Import python-shade_1.4.0.orig.tar.gz

Clint Byrum spamaps at moszumanska.debian.org
Tue Feb 23 00:13:09 UTC 2016


This is an automated email from the git hooks/post-receive script.

spamaps pushed a commit to branch master
in repository python-shade.

commit a1dc6938972ec86566e92d7feb01a36edfc6c353
Author: Clint Byrum <spamaps at debian.org>
Date:   Mon Feb 22 15:52:33 2016 -0800

    Import python-shade_1.4.0.orig.tar.gz
---
 AUTHORS                                            |   4 +
 ChangeLog                                          |  38 ++++
 PKG-INFO                                           |   4 +-
 README.rst                                         |   2 +-
 doc/source/conf.py                                 |   6 +-
 doc/source/index.rst                               |   1 +
 doc/source/installation.rst                        |   2 +-
 doc/source/releasenotes.rst                        |   5 +
 .../cache-in-use-volumes-c7fa8bb378106fe3.yaml     |   4 +
 .../notes/cinderv2-norm-fix-037189c60b43089f.yaml  |   3 +
 .../notes/create-stack-fix-12dbb59a48ac7442.yaml   |   4 +
 .../notes/delete-obj-return-a3ecf0415b7a2989.yaml  |   5 +
 .../notes/fix-list-networks-a592725df64c306e.yaml  |   3 +
 .../notes/fix-update-domain-af47b066ac52eb7f.yaml  |   3 +
 .../notes/started-using-reno-242e2b0cd27f9480.yaml |   3 +
 requirements.txt                                   |   2 +-
 setup.cfg                                          |   2 +-
 shade.egg-info/PKG-INFO                            |   4 +-
 shade.egg-info/SOURCES.txt                         |  13 +-
 shade.egg-info/pbr.json                            |   2 +-
 shade.egg-info/requires.txt                        |   2 +-
 shade/__init__.py                                  |   9 +-
 shade/_tasks.py                                    |   7 +-
 shade/_utils.py                                    |  96 ++++++++-
 shade/cmd/inventory.py                             |   1 -
 shade/inventory.py                                 |  34 ++-
 shade/meta.py                                      |  61 +++---
 shade/openstackcloud.py                            | 108 ++++++----
 shade/operatorcloud.py                             |  58 +++++-
 shade/task_manager.py                              |   2 -
 shade/tests/ansible/hooks/post_test_hook.sh        |   1 +
 shade/tests/fakes.py                               |  18 ++
 shade/tests/functional/hooks/post_test_hook.sh     |   1 +
 shade/tests/functional/test_domain.py              |  12 ++
 shade/tests/functional/test_identity.py            |  10 +
 shade/tests/functional/test_inventory.py           |  24 +++
 shade/tests/functional/test_network.py             |  27 +--
 shade/tests/unit/test__utils.py                    |  36 ++++
 shade/tests/unit/test_create_server.py             |  13 +-
 shade/tests/unit/test_delete_server.py             |  14 ++
 shade/tests/unit/test_domains.py                   |  64 ++++++
 shade/tests/unit/test_identity_roles.py            |  43 ++++
 shade/tests/unit/test_inventory.py                 | 122 +++++++++++
 shade/tests/unit/test_meta.py                      |  21 +-
 shade/tests/unit/test_network.py                   |  28 +++
 shade/tests/unit/test_object.py                    | 228 +++++++++++++++++++++
 shade/tests/unit/test_rebuild_server.py            |   9 +-
 shade/tests/unit/test_security_groups.py           |  18 ++
 shade/tests/unit/test_shade.py                     | 179 +++++++++++++++-
 shade/tests/unit/test_shade_operator.py            |  78 +++++--
 shade/tests/unit/test_stack.py                     | 145 +++++++++++++
 shade/tests/unit/test_volume.py                    | 194 ++++++++++++++++++
 test-requirements.txt                              |   1 +
 53 files changed, 1626 insertions(+), 148 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 3c354e6..ce8acbf 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,6 +3,7 @@ Alberto Gireud <agireud at us.ibm.com>
 Atsushi SAKAI <sakaia at jp.fujitsu.com>
 Caleb Boylan <calebboylan at gmail.com>
 Clark Boylan <clark.boylan at gmail.com>
+Clayton O'Neill <clayton at oneill.net>
 Clint Byrum <clint at fewbar.com>
 David Shrewsbury <shrewsbury.dave at gmail.com>
 Davide Guerri <davide.guerri at gmail.com>
@@ -14,8 +15,11 @@ James E. Blair <jeblair at linux.vnet.ibm.com>
 Jeremy Stanley <fungi at yuggoth.org>
 Joshua Harlow <harlowja at yahoo-inc.com>
 Julia Kreger <juliaashleykreger at gmail.com>
+Kyle Mestery <mestery at mestery.com>
 Lars Kellogg-Stedman <lars at redhat.com>
+Matthew Treinish <mtreinish at kortar.org>
 Monty Taylor <mordred at inaugust.com>
+Morgan Fainberg <morgan.fainberg at gmail.com>
 Ricardo Carrillo Cruz <ricardo.carrillo.cruz at gmail.com>
 Rosario Di Somma <rosario.disomma at dreamhost.com>
 Steve Leon <kokhang at gmail.com>
diff --git a/ChangeLog b/ChangeLog
index 2129f65..fc35e6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,44 @@
 CHANGES
 =======
 
+1.4.0
+-----
+
+* correct rpmlint errors
+* Add tests for stack search API
+* Fix filtering in search_stacks()
+* Bug fix: Cinder v2 returns bools now
+* Normalize server objects
+* Make server variable expansion optional
+* Have inventory use os-client-config extra_config
+* Fix unittest stack status
+* Fix shade tests with OCC 1.13.0
+* No Mutable Defaults
+* Add option to enable HTTP tracing
+* Add support for querying role assignments
+* Add inventory unit tests
+* Fix server deletes when cinder isn't available
+* Pedantic spelling correction
+* Bug fix: create_stack() fails when waiting
+* Stack API improvements
+* Bug fix: delete_object() returns True/False
+* Add wait support for ironic node [de]activate
+* Improve test coverage: container/object list API
+* Make a new swift client prior to each image upload
+* Improve test coverage: volume attach/detach API
+* Bug fix: Allow name update for domains
+* Improve test coverage: network delete API
+* Bug fix: Fix pass thru filtering in list_networks
+* Consider 'in-use' a non-pending volume for caching
+* Improve test coverage: private extension API
+* Improve test coverage: hypervisor list
+* Use reno for release notes
+* Improve test coverage: list_router_interfaces API
+* Change the client imports to stop shadowing
+* Use non-versioned cinderclient constructor
+* Improve test coverage: server secgroup API
+* Improve test coverage: container API
+
 1.3.0
 -----
 
diff --git a/PKG-INFO b/PKG-INFO
index 0b53537..49614a5 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: shade
-Version: 1.3.0
+Version: 1.4.0
 Summary: Client library for operating OpenStack clouds
 Home-page: http://docs.openstack.org/infra/shade/
 Author: OpenStack Infrastructure Team
@@ -33,7 +33,7 @@ Description: Introduction
         
           import shade
         
-          # Initialize and turn on debug loggin
+          # Initialize and turn on debug logging
           shade.simple_logging(debug=True)
         
           # Initialize cloud
diff --git a/README.rst b/README.rst
index 33eda5c..2b46ebd 100644
--- a/README.rst
+++ b/README.rst
@@ -25,7 +25,7 @@ Sometimes an example is nice.
 
   import shade
 
-  # Initialize and turn on debug loggin
+  # Initialize and turn on debug logging
   shade.simple_logging(debug=True)
 
   # Initialize cloud
diff --git a/doc/source/conf.py b/doc/source/conf.py
index bbebf47..e55e85b 100755
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -3,7 +3,11 @@ import sys
 
 sys.path.insert(0, os.path.abspath('../..'))
 
-extensions = ['sphinx.ext.autodoc', 'oslosphinx']
+extensions = [
+    'sphinx.ext.autodoc',
+    'oslosphinx',
+    'reno.sphinxext'
+]
 
 # The suffix of source filenames.
 source_suffix = '.rst'
diff --git a/doc/source/index.rst b/doc/source/index.rst
index af9eaa3..2aa8bd3 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -16,6 +16,7 @@ Contents:
    contributing
    coding
    future
+   releasenotes
 
 .. include:: ../../README.rst
 
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index c47e487..9699e77 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -9,4 +9,4 @@ At the command line::
 Or, if you have virtualenv wrapper installed::
 
     $ mkvirtualenv shade
-    $ pip install shade
\ No newline at end of file
+    $ pip install shade
diff --git a/doc/source/releasenotes.rst b/doc/source/releasenotes.rst
new file mode 100644
index 0000000..2a4bceb
--- /dev/null
+++ b/doc/source/releasenotes.rst
@@ -0,0 +1,5 @@
+=============
+Release Notes
+=============
+
+.. release-notes::
diff --git a/releasenotes/notes/cache-in-use-volumes-c7fa8bb378106fe3.yaml b/releasenotes/notes/cache-in-use-volumes-c7fa8bb378106fe3.yaml
new file mode 100644
index 0000000..4ac0b61
--- /dev/null
+++ b/releasenotes/notes/cache-in-use-volumes-c7fa8bb378106fe3.yaml
@@ -0,0 +1,4 @@
+---
+fixes:
+  - Fixed caching the volume list when volumes are in
+    use.
diff --git a/releasenotes/notes/cinderv2-norm-fix-037189c60b43089f.yaml b/releasenotes/notes/cinderv2-norm-fix-037189c60b43089f.yaml
new file mode 100644
index 0000000..0847ee6
--- /dev/null
+++ b/releasenotes/notes/cinderv2-norm-fix-037189c60b43089f.yaml
@@ -0,0 +1,3 @@
+---
+fixes:
+  - Fixed the volume normalization function when used with cinder v2.
diff --git a/releasenotes/notes/create-stack-fix-12dbb59a48ac7442.yaml b/releasenotes/notes/create-stack-fix-12dbb59a48ac7442.yaml
new file mode 100644
index 0000000..35bb8c0
--- /dev/null
+++ b/releasenotes/notes/create-stack-fix-12dbb59a48ac7442.yaml
@@ -0,0 +1,4 @@
+---
+fixes:
+  - The create_stack() call was fixed to call the correct iterator
+    method and to return the updated stack object when waiting.
diff --git a/releasenotes/notes/delete-obj-return-a3ecf0415b7a2989.yaml b/releasenotes/notes/delete-obj-return-a3ecf0415b7a2989.yaml
new file mode 100644
index 0000000..381bcb9
--- /dev/null
+++ b/releasenotes/notes/delete-obj-return-a3ecf0415b7a2989.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - The delete_object() method was not returning True/False,
+    similar to other delete methods. It is now consistent with
+    the other delete APIs.
diff --git a/releasenotes/notes/fix-list-networks-a592725df64c306e.yaml b/releasenotes/notes/fix-list-networks-a592725df64c306e.yaml
new file mode 100644
index 0000000..eecc255
--- /dev/null
+++ b/releasenotes/notes/fix-list-networks-a592725df64c306e.yaml
@@ -0,0 +1,3 @@
+---
+fixes:
+  - Fix for list_networks() ignoring any filters.
diff --git a/releasenotes/notes/fix-update-domain-af47b066ac52eb7f.yaml b/releasenotes/notes/fix-update-domain-af47b066ac52eb7f.yaml
new file mode 100644
index 0000000..060461d
--- /dev/null
+++ b/releasenotes/notes/fix-update-domain-af47b066ac52eb7f.yaml
@@ -0,0 +1,3 @@
+---
+fixes:
+  - Fix for update_domain() where 'name' was not updatable.
diff --git a/releasenotes/notes/started-using-reno-242e2b0cd27f9480.yaml b/releasenotes/notes/started-using-reno-242e2b0cd27f9480.yaml
new file mode 100644
index 0000000..d7cfb51
--- /dev/null
+++ b/releasenotes/notes/started-using-reno-242e2b0cd27f9480.yaml
@@ -0,0 +1,3 @@
+---
+other:
+- Started using reno for release notes.
diff --git a/requirements.txt b/requirements.txt
index 8d6eaf7..47db714 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,7 +4,7 @@ munch
 decorator
 jsonpatch
 ipaddress
-os-client-config>=1.11.1
+os-client-config>=1.13.0
 requestsexceptions>=1.1.1
 six
 
diff --git a/setup.cfg b/setup.cfg
index 3ba2d88..f84e0dc 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -32,6 +32,6 @@ upload-dir = doc/build/html
 
 [egg_info]
 tag_build = 
-tag_date = 0
 tag_svn_revision = 0
+tag_date = 0
 
diff --git a/shade.egg-info/PKG-INFO b/shade.egg-info/PKG-INFO
index 0b53537..49614a5 100644
--- a/shade.egg-info/PKG-INFO
+++ b/shade.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: shade
-Version: 1.3.0
+Version: 1.4.0
 Summary: Client library for operating OpenStack clouds
 Home-page: http://docs.openstack.org/infra/shade/
 Author: OpenStack Infrastructure Team
@@ -33,7 +33,7 @@ Description: Introduction
         
           import shade
         
-          # Initialize and turn on debug loggin
+          # Initialize and turn on debug logging
           shade.simple_logging(debug=True)
         
           # Initialize cloud
diff --git a/shade.egg-info/SOURCES.txt b/shade.egg-info/SOURCES.txt
index 55d902b..fe7242f 100644
--- a/shade.egg-info/SOURCES.txt
+++ b/shade.egg-info/SOURCES.txt
@@ -19,9 +19,17 @@ doc/source/contributing.rst
 doc/source/future.rst
 doc/source/index.rst
 doc/source/installation.rst
+doc/source/releasenotes.rst
 doc/source/usage.rst
 extras/delete-network.sh
 extras/run-ansible-tests.sh
+releasenotes/notes/cache-in-use-volumes-c7fa8bb378106fe3.yaml
+releasenotes/notes/cinderv2-norm-fix-037189c60b43089f.yaml
+releasenotes/notes/create-stack-fix-12dbb59a48ac7442.yaml
+releasenotes/notes/delete-obj-return-a3ecf0415b7a2989.yaml
+releasenotes/notes/fix-list-networks-a592725df64c306e.yaml
+releasenotes/notes/fix-update-domain-af47b066ac52eb7f.yaml
+releasenotes/notes/started-using-reno-242e2b0cd27f9480.yaml
 shade/__init__.py
 shade/_log.py
 shade/_tasks.py
@@ -107,6 +115,7 @@ shade/tests/unit/test_floating_ip_nova.py
 shade/tests/unit/test_floating_ip_pool.py
 shade/tests/unit/test_groups.py
 shade/tests/unit/test_identity_roles.py
+shade/tests/unit/test_inventory.py
 shade/tests/unit/test_keypair.py
 shade/tests/unit/test_meta.py
 shade/tests/unit/test_network.py
@@ -119,5 +128,7 @@ shade/tests/unit/test_security_groups.py
 shade/tests/unit/test_services.py
 shade/tests/unit/test_shade.py
 shade/tests/unit/test_shade_operator.py
+shade/tests/unit/test_stack.py
 shade/tests/unit/test_task_manager.py
-shade/tests/unit/test_users.py
\ No newline at end of file
+shade/tests/unit/test_users.py
+shade/tests/unit/test_volume.py
\ No newline at end of file
diff --git a/shade.egg-info/pbr.json b/shade.egg-info/pbr.json
index 820d7c0..8434767 100644
--- a/shade.egg-info/pbr.json
+++ b/shade.egg-info/pbr.json
@@ -1 +1 @@
-{"is_release": true, "git_version": "5662df1"}
\ No newline at end of file
+{"is_release": true, "git_version": "457ea84"}
\ No newline at end of file
diff --git a/shade.egg-info/requires.txt b/shade.egg-info/requires.txt
index 405add0..d4351c5 100644
--- a/shade.egg-info/requires.txt
+++ b/shade.egg-info/requires.txt
@@ -3,7 +3,7 @@ munch
 decorator
 jsonpatch
 ipaddress
-os-client-config>=1.11.1
+os-client-config>=1.13.0
 requestsexceptions>=1.1.1
 six
 keystoneauth1>=1.0.0
diff --git a/shade/__init__.py b/shade/__init__.py
index c2820c3..385cd73 100644
--- a/shade/__init__.py
+++ b/shade/__init__.py
@@ -32,11 +32,18 @@ if requestsexceptions.SubjectAltNameWarning:
         'ignore', category=requestsexceptions.SubjectAltNameWarning)
 
 
-def simple_logging(debug=False):
+def simple_logging(debug=False, http_debug=False):
+    if http_debug:
+        debug = True
     if debug:
         log_level = logging.DEBUG
     else:
         log_level = logging.INFO
+    if http_debug:
+        # Enable HTTP level tracing
+        log = _log.setup_logging('keystoneauth')
+        log.addHandler(logging.StreamHandler())
+        log.setLevel(log_level)
     log = _log.setup_logging('shade')
     log.addHandler(logging.StreamHandler())
     log.setLevel(log_level)
diff --git a/shade/_tasks.py b/shade/_tasks.py
index 5f5320e..dffda00 100644
--- a/shade/_tasks.py
+++ b/shade/_tasks.py
@@ -169,7 +169,7 @@ class NovaUrlGet(task_manager.Task):
 
 class NetworkList(task_manager.Task):
     def main(self, client):
-        return client.neutron_client.list_networks()
+        return client.neutron_client.list_networks(**self.args)
 
 
 class NetworkCreate(task_manager.Task):
@@ -677,6 +677,11 @@ class RoleDelete(task_manager.Task):
         return client.keystone_client.roles.delete(**self.args)
 
 
+class RoleAssignmentList(task_manager.Task):
+    def main(self, client):
+        return client.keystone_client.role_assignments.list(**self.args)
+
+
 class StackList(task_manager.Task):
     def main(self, client):
         return client.heat_client.stacks.list()
diff --git a/shade/_utils.py b/shade/_utils.py
index ef43663..ae20654 100644
--- a/shade/_utils.py
+++ b/shade/_utils.py
@@ -15,6 +15,7 @@
 import contextlib
 import inspect
 import netifaces
+import six
 import time
 
 from decorator import decorator
@@ -141,6 +142,36 @@ def _get_entity(func, name_or_id, filters):
     return entities[0]
 
 
+def normalize_servers(servers, cloud_name, region_name):
+    # Here instead of _utils because we need access to region and cloud
+    # name from the cloud object
+    ret = []
+    for server in servers:
+        ret.append(normalize_server(server, cloud_name, region_name))
+    return ret
+
+
+def normalize_server(server, cloud_name, region_name):
+    server.pop('links', None)
+    server['flavor'].pop('links', None)
+    # OpenStack can return image as a string when you've booted
+    # from volume
+    if str(server['image']) != server['image']:
+        server['image'].pop('links', None)
+
+    server['region'] = region_name
+    server['cloud'] = cloud_name
+
+    az = server.get('OS-EXT-AZ:availability_zone', None)
+    if az:
+        server['az'] = az
+
+    # Ensure volumes is always in the server dict, even if empty
+    server['volumes'] = []
+
+    return server
+
+
 def normalize_keystone_services(services):
     """Normalize the structure of keystone services
 
@@ -327,13 +358,16 @@ def normalize_volumes(volumes):
         new_vol['display_name'] = name
         new_vol['description'] = description
         new_vol['display_description'] = description
-        # For some reason, cinder uses strings for bools for these fields
+        # For some reason, cinder v1 uses strings for bools for these fields.
+        # Cinder v2 uses booleans.
         for field in ('bootable', 'multiattach'):
-            if field in new_vol and new_vol[field] is not None:
-                if new_vol[field].lower() == 'true':
-                    new_vol[field] = True
-                elif new_vol[field].lower() == 'false':
-                    new_vol[field] = False
+            if field in new_vol and isinstance(new_vol[field],
+                                               six.string_types):
+                if new_vol[field] is not None:
+                    if new_vol[field].lower() == 'true':
+                        new_vol[field] = True
+                    elif new_vol[field].lower() == 'false':
+                        new_vol[field] = False
         ret.append(new_vol)
     return meta.obj_list_to_dict(ret)
 
@@ -363,6 +397,56 @@ def normalize_groups(domains):
     return meta.obj_list_to_dict(ret)
 
 
+def normalize_role_assignments(assignments):
+    """Put role_assignments into a form that works with search/get interface.
+
+    Role assignments have the structure::
+
+        [
+            {
+                "role": {
+                    "id": "--role-id--"
+                },
+                "scope": {
+                    "domain": {
+                        "id": "--domain-id--"
+                    }
+                },
+                "user": {
+                    "id": "--user-id--"
+                }
+            },
+        ]
+
+    Which is hard to work with in the rest of our interface. Map this to be::
+
+        [
+            {
+                "id": "--role-id--",
+                "domain": "--domain-id--",
+                "user": "--user-id--",
+            }
+        ]
+
+    Scope can be "domain" or "project" and "user" can also be "group".
+
+    :param list assignments: A list of dictionaries of role assignments.
+
+    :returns: A list of flattened/normalized role assignment dicts.
+    """
+    new_assignments = []
+    for assignment in assignments:
+        new_val = {'id': assignment['role']['id']}
+        for scope in ('project', 'domain'):
+            if scope in assignment['scope']:
+                new_val[scope] = assignment['scope'][scope]['id']
+        for assignee in ('user', 'group'):
+            if assignee in assignment:
+                new_val[assignee] = assignment[assignee]['id']
+        new_assignments.append(new_val)
+    return new_assignments
+
+
 def valid_kwargs(*valid_args):
     # This decorator checks if argument passed as **kwargs to a function are
     # present in valid_args.
diff --git a/shade/cmd/inventory.py b/shade/cmd/inventory.py
index 4f9538f..47d3897 100755
--- a/shade/cmd/inventory.py
+++ b/shade/cmd/inventory.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/shade/inventory.py b/shade/inventory.py
index 2ea9995..9806597 100644
--- a/shade/inventory.py
+++ b/shade/inventory.py
@@ -12,18 +12,29 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import functools
+
 import os_client_config
 
 import shade
 from shade import _utils
+from shade import meta
 
 
 class OpenStackInventory(object):
 
+    # Put this here so the capability can be detected with hasattr on the class
+    extra_config = None
+
     def __init__(
-            self, config_files=[], refresh=False, private=False):
+            self, config_files=None, refresh=False, private=False,
+            config_key=None, config_defaults=None):
+        if config_files is None:
+            config_files = []
         config = os_client_config.config.OpenStackConfig(
             config_files=os_client_config.config.CONFIG_FILES + config_files)
+        self.extra_config = config.get_extra_config(
+            config_key, config_defaults)
 
         self.clouds = [
             shade.OpenStackCloud(cloud_config=cloud_config)
@@ -39,7 +50,7 @@ class OpenStackInventory(object):
             for cloud in self.clouds:
                 cloud._cache.invalidate()
 
-    def list_hosts(self):
+    def list_hosts(self, expand=True):
         hostvars = []
 
         for cloud in self.clouds:
@@ -47,14 +58,21 @@ class OpenStackInventory(object):
             # Cycle on servers
             for server in cloud.list_servers():
 
-                meta = cloud.get_openstack_vars(server)
-                hostvars.append(meta)
+                if expand:
+                    server_vars = cloud.get_openstack_vars(server)
+                else:
+                    server_vars = meta.add_server_interfaces(cloud, server)
+                hostvars.append(server_vars)
 
         return hostvars
 
-    def search_hosts(self, name_or_id=None, filters=None):
-        hosts = self.list_hosts()
+    def search_hosts(self, name_or_id=None, filters=None, expand=True):
+        hosts = self.list_hosts(expand=expand)
         return _utils._filter_list(hosts, name_or_id, filters)
 
-    def get_host(self, name_or_id, filters=None):
-        return _utils._get_entity(self.search_hosts, name_or_id, filters)
+    def get_host(self, name_or_id, filters=None, expand=True):
+        if expand:
+            func = self.search_hosts
+        else:
+            func = functools.partial(self.search_hosts, expand=False)
+        return _utils._get_entity(func, name_or_id, filters)
diff --git a/shade/meta.py b/shade/meta.py
index b952b36..c2d492b 100644
--- a/shade/meta.py
+++ b/shade/meta.py
@@ -224,44 +224,47 @@ def get_groups_from_server(cloud, server, server_vars):
 
 
 def expand_server_vars(cloud, server):
-    """Add clean up the server dict with information that is essential."""
-    server_vars = server
-    server_vars.pop('links', None)
+    """Backwards compatibility function."""
+    return add_server_interfaces(cloud, server)
 
+
+def add_server_interfaces(cloud, server):
+    """Add network interface information to server.
+
+    Query the cloud as necessary to add information to the server record
+    about the network information needed to interface with the server.
+
+    Ensures that public_v4, public_v6, private_v4, private_v6, interface_ip,
+                 accessIPv4 and accessIPv6 are always set.
+    """
     # First, add an IP address. Set it to '' rather than None if it does
     # not exist to remain consistent with the pre-existing missing values
-    server_vars['public_v4'] = get_server_external_ipv4(cloud, server) or ''
-    server_vars['public_v6'] = get_server_external_ipv6(server) or ''
-    server_vars['private_v4'] = get_server_private_ip(server, cloud) or ''
+    server['public_v4'] = get_server_external_ipv4(cloud, server) or ''
+    server['public_v6'] = get_server_external_ipv6(server) or ''
+    server['private_v4'] = get_server_private_ip(server, cloud) or ''
     interface_ip = None
-    if cloud.private and server_vars['private_v4']:
-        interface_ip = server_vars['private_v4']
+    if cloud.private and server['private_v4']:
+        interface_ip = server['private_v4']
     else:
-        if (server_vars['public_v6'] and cloud._local_ipv6
+        if (server['public_v6'] and cloud._local_ipv6
             and not cloud.force_ipv4):
-            interface_ip = server_vars['public_v6']
+            interface_ip = server['public_v6']
         else:
-            interface_ip = server_vars['public_v4']
+            interface_ip = server['public_v4']
     if interface_ip:
-        server_vars['interface_ip'] = interface_ip
+        server['interface_ip'] = interface_ip
 
     # Some clouds do not set these, but they're a regular part of the Nova
     # server record. Since we know them, go ahead and set them. In the case
     # where they were set previous, we use the values, so this will not break
     # clouds that provide the information
-    if cloud.private and server_vars['private_v4']:
-        server_vars['accessIPv4'] = server_vars['private_v4']
+    if cloud.private and server['private_v4']:
+        server['accessIPv4'] = server['private_v4']
     else:
-        server_vars['accessIPv4'] = server_vars['public_v4']
-    server_vars['accessIPv6'] = server_vars['public_v6']
+        server['accessIPv4'] = server['public_v4']
+    server['accessIPv6'] = server['public_v6']
 
-    server_vars['region'] = cloud.region_name
-    server_vars['cloud'] = cloud.name
-
-    az = server_vars.get('OS-EXT-AZ:availability_zone', None)
-    if az:
-        server_vars['az'] = az
-    return server_vars
+    return server
 
 
 def expand_server_security_groups(cloud, server):
@@ -273,14 +276,19 @@ def expand_server_security_groups(cloud, server):
 
 
 def get_hostvars_from_server(cloud, server, mounts=None):
-    """Expand additional server information useful for ansible inventory."""
-    server_vars = expand_server_vars(cloud, server)
+    """Expand additional server information useful for ansible inventory.
+
+    Variables in this function may make additional cloud queries to flesh out
+    possibly interesting info, making it more expensive to call than
+    expand_server_vars if caching is not set up. If caching is set up,
+    the extra cost should be minimal.
+    """
+    server_vars = add_server_interfaces(cloud, server)
 
     flavor_id = server['flavor']['id']
     flavor_name = cloud.get_flavor_name(flavor_id)
     if flavor_name:
         server_vars['flavor']['name'] = flavor_name
-    server_vars['flavor'].pop('links', None)
 
     expand_server_security_groups(cloud, server)
 
@@ -294,7 +302,6 @@ def get_hostvars_from_server(cloud, server, mounts=None):
         image_name = cloud.get_image_name(image_id)
         if image_name:
             server_vars['image']['name'] = image_name
-    server_vars['image'].pop('links', None)
 
     volumes = []
     if cloud.has_service('volume'):
diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py
index 08a2699..3804cce 100644
--- a/shade/openstackcloud.py
+++ b/shade/openstackcloud.py
@@ -23,20 +23,20 @@ import warnings
 from dogpile import cache
 import requestsexceptions
 
-from cinderclient.v1 import client as cinder_client
+import cinderclient.client
 import glanceclient
 import glanceclient.exc
-from heatclient import client as heat_client
+import heatclient.client
 from heatclient.common import template_utils
 import keystoneauth1.exceptions
-from keystoneclient import client as keystone_client
-from neutronclient.neutron import client as neutron_client
-from novaclient import client as nova_client
-from novaclient import exceptions as nova_exceptions
-import swiftclient.client as swift_client
-import swiftclient.service as swift_service
+import keystoneclient.client
+import neutronclient.neutron.client
+import novaclient.client
+import novaclient.exceptions as nova_exceptions
+import swiftclient.client
+import swiftclient.service
 import swiftclient.exceptions as swift_exceptions
-import troveclient.client as trove_client
+import troveclient.client
 
 from shade.exc import *  # noqa
 from shade import _log
@@ -65,7 +65,7 @@ OBJECT_CONTAINER_ACLS = {
 def _no_pending_volumes(volumes):
     '''If there are any volumes not in a steady state, don't cache'''
     for volume in volumes:
-        if volume['status'] not in ('available', 'error'):
+        if volume['status'] not in ('available', 'error', 'in-use'):
             return False
     return True
 
@@ -81,7 +81,7 @@ def _no_pending_images(images):
 def _no_pending_stacks(stacks):
     '''If there are any stacks not in a steady state, don't cache'''
     for stack in stacks:
-        status = stack['status']
+        status = stack['stack_status']
         if '_COMPLETE' not in status and '_FAILED' not in status:
             return False
     return True
@@ -220,6 +220,10 @@ class OpenStackCloud(object):
         self._neutron_client = None
         self._nova_client = None
         self._swift_client = None
+        # Lock used to reset client as swift client does not
+        # support keystone sessions meaning that we have to make
+        # a new client in order to get new auth prior to operations.
+        self._swift_client_lock = threading.Lock()
         self._swift_service = None
         self._trove_client = None
 
@@ -268,7 +272,7 @@ class OpenStackCloud(object):
     def nova_client(self):
         if self._nova_client is None:
             self._nova_client = self._get_client(
-                'compute', nova_client.Client)
+                'compute', novaclient.client.Client)
         return self._nova_client
 
     @property
@@ -285,7 +289,7 @@ class OpenStackCloud(object):
     def keystone_client(self):
         if self._keystone_client is None:
             self._keystone_client = self._get_client(
-                'identity', keystone_client.Client)
+                'identity', keystoneclient.client.Client)
         return self._keystone_client
 
     @property
@@ -645,7 +649,7 @@ class OpenStackCloud(object):
     def heat_client(self):
         if self._heat_client is None:
             self._heat_client = self._get_client(
-                'orchestration', heat_client.Client)
+                'orchestration', heatclient.client.Client)
         return self._heat_client
 
     def get_template_contents(
@@ -661,10 +665,11 @@ class OpenStackCloud(object):
 
     @property
     def swift_client(self):
-        if self._swift_client is None:
-            self._swift_client = self._get_client(
-                'object-store', swift_client.Connection)
-        return self._swift_client
+        with self._swift_client_lock:
+            if self._swift_client is None:
+                self._swift_client = self._get_client(
+                    'object-store', swiftclient.client.Connection)
+            return self._swift_client
 
     @property
     def swift_service(self):
@@ -675,7 +680,7 @@ class OpenStackCloud(object):
                 options = dict(os_auth_token=self.auth_token,
                                os_storage_url=endpoint,
                                os_region_name=self.region_name)
-                self._swift_service = swift_service.SwiftService(
+                self._swift_service = swiftclient.service.SwiftService(
                     options=options)
         return self._swift_service
 
@@ -684,21 +689,21 @@ class OpenStackCloud(object):
 
         if self._cinder_client is None:
             self._cinder_client = self._get_client(
-                'volume', cinder_client.Client)
+                'volume', cinderclient.client.Client)
         return self._cinder_client
 
     @property
     def trove_client(self):
         if self._trove_client is None:
             self._trove_client = self._get_client(
-                'database', trove_client.Client)
+                'database', troveclient.client.Client)
         return self._trove_client
 
     @property
     def neutron_client(self):
         if self._neutron_client is None:
             self._neutron_client = self._get_client(
-                'network', neutron_client.Client)
+                'network', neutronclient.neutron.client.Client)
         return self._neutron_client
 
     def create_stack(
@@ -725,23 +730,24 @@ class OpenStackCloud(object):
             stack = self.manager.submitTask(_tasks.StackCreate(**params))
         if not wait:
             return stack
-        for count in _iterate_timeout(
+        for count in _utils._iterate_timeout(
                 timeout,
                 "Timed out waiting for heat stack to finish"):
-            if self.get_stack(name, cache=False):
+            stack = self.get_stack(name, cache=False)
+            if stack:
                 return stack
 
     def delete_stack(self, name_or_id):
         """Delete a Heat Stack
 
-        :param name_or_id: Stack name or id.
+        :param string name_or_id: Stack name or id.
 
-        :returns: True if delete succeeded, False otherwise.
+        :returns: True if delete succeeded, False if the stack was not found.
 
         :raises: ``OpenStackCloudException`` if something goes wrong during
             the openstack API call
         """
-        stack = self.get_stack(name_or_id=name_or_id)
+        stack = self.get_stack(name_or_id)
         if stack is None:
             self.log.debug("Stack %s not found for deleting" % name_or_id)
             return False
@@ -949,8 +955,7 @@ class OpenStackCloud(object):
             openstack API call.
         """
         stacks = self.list_stacks()
-        return _utils._filter_list(
-            stacks, name_or_id, filters, name_name='stack_name')
+        return _utils._filter_list(stacks, name_or_id, filters)
 
     def list_keypairs(self):
         """List all available keypairs.
@@ -1049,7 +1054,7 @@ class OpenStackCloud(object):
         :raises: ``OpenStackCloudException`` if something goes wrong during the
             openstack API call.
         """
-        with _utils.shade_exceptions():
+        with _utils.shade_exceptions("Error fetching stack list"):
             stacks = self.manager.submitTask(_tasks.StackList())
         return stacks
 
@@ -1124,7 +1129,9 @@ class OpenStackCloud(object):
                 "Error fetching server list on {cloud}:{region}:".format(
                     cloud=self.name,
                     region=self.region_name)):
-            servers = self.manager.submitTask(_tasks.ServerList())
+            servers = _utils.normalize_servers(
+                self.manager.submitTask(_tasks.ServerList()),
+                cloud_name=self.name, region_name=self.region_name)
 
             if detailed:
                 return [
@@ -1479,7 +1486,9 @@ class OpenStackCloud(object):
         return _utils._get_entity(searchfunc, name_or_id, filters)
 
     def get_server_by_id(self, id):
-        return self.manager.submitTask(_tasks.ServerGet(server=id))
+        return _utils.normalize_server(
+            self.manager.submitTask(_tasks.ServerGet(server=id)),
+            cloud_name=self.name, region_name=self.region_name)
 
     def get_image(self, name_or_id, filters=None):
         """Get an image by name or ID.
@@ -1997,6 +2006,8 @@ class OpenStackCloud(object):
     def _upload_image_task(
             self, name, filename, container, current_image,
             wait, timeout, **image_properties):
+        with self._swift_client_lock:
+            self._swift_client = None
         self.create_object(
             container, name, filename,
             md5=image_properties.get('md5', None),
@@ -3141,7 +3152,7 @@ class OpenStackCloud(object):
             root_volume=None, terminate_volume=False,
             wait=False, timeout=180, reuse_ips=True,
             network=None, boot_from_volume=False, volume_size='50',
-            boot_volume=None, volumes=[],
+            boot_volume=None, volumes=None,
             **kwargs):
         """Create a virtual server instance.
 
@@ -3218,6 +3229,10 @@ class OpenStackCloud(object):
         :raises: OpenStackCloudException on operation error.
         """
         # nova cli calls this boot_volume. Let's be the same
+
+        if volumes is None:
+            volumes = []
+
         if root_volume and not boot_volume:
             boot_volume = root_volume
 
... 1841 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-shade.git



More information about the Python-modules-commits mailing list