Merge "Add operator role to heat stack owner"
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 5cce0bb..bf6c537 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -16,8 +16,8 @@
 
 import six
 
-from tempest import exceptions
 from tempest.lib import auth
+from tempest.lib import exceptions
 
 
 @six.add_metaclass(abc.ABCMeta)
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 92f335f..f534f30 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -13,157 +13,65 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
+
+from tempest.lib import exceptions
 
 
-class TempestException(Exception):
-    """Base Tempest Exception
-
-    To correctly use this class, inherit from it and define
-    a 'message' property. That message will get printf'd
-    with the keyword arguments provided to the constructor.
-    """
-    message = "An unknown exception occurred"
-
-    def __init__(self, *args, **kwargs):
-        super(TempestException, self).__init__()
-        try:
-            self._error_string = self.message % kwargs
-        except Exception:
-            # at least get the core message out if something happened
-            self._error_string = self.message
-        if len(args) > 0:
-            # If there is a non-kwarg parameter, assume it's the error
-            # message or reason description and tack it on to the end
-            # of the exception message
-            # Convert all arguments into their string representations...
-            args = ["%s" % arg for arg in args]
-            self._error_string = (self._error_string +
-                                  "\nDetails: %s" % '\n'.join(args))
-
-    def __str__(self):
-        return self._error_string
-
-
-class RestClientException(TempestException,
-                          testtools.TestCase.failureException):
-    pass
-
-
-class InvalidConfiguration(TempestException):
+class InvalidConfiguration(exceptions.TempestException):
     message = "Invalid Configuration"
 
 
-class InvalidCredentials(TempestException):
-    message = "Invalid Credentials"
-
-
-class InvalidServiceTag(TempestException):
+class InvalidServiceTag(exceptions.TempestException):
     message = "Invalid service tag"
 
 
-class InvalidIdentityVersion(TempestException):
-    message = "Invalid version %(identity_version)s of the identity service"
-
-
-class TimeoutException(TempestException):
+class TimeoutException(exceptions.TempestException):
     message = "Request timed out"
 
 
-class BuildErrorException(TempestException):
+class BuildErrorException(exceptions.TempestException):
     message = "Server %(server_id)s failed to build and is in ERROR status"
 
 
-class ImageKilledException(TempestException):
+class ImageKilledException(exceptions.TempestException):
     message = "Image %(image_id)s 'killed' while waiting for '%(status)s'"
 
 
-class AddImageException(TempestException):
+class AddImageException(exceptions.TempestException):
     message = "Image %(image_id)s failed to become ACTIVE in the allotted time"
 
 
-class VolumeBuildErrorException(TempestException):
+class VolumeBuildErrorException(exceptions.TempestException):
     message = "Volume %(volume_id)s failed to build and is in ERROR status"
 
 
-class VolumeRestoreErrorException(TempestException):
+class VolumeRestoreErrorException(exceptions.TempestException):
     message = "Volume %(volume_id)s failed to restore and is in ERROR status"
 
 
-class SnapshotBuildErrorException(TempestException):
+class SnapshotBuildErrorException(exceptions.TempestException):
     message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"
 
 
-class VolumeBackupException(TempestException):
+class VolumeBackupException(exceptions.TempestException):
     message = "Volume backup %(backup_id)s failed and is in ERROR status"
 
 
-class StackBuildErrorException(TempestException):
+class StackBuildErrorException(exceptions.TempestException):
     message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
                "due to '%(stack_status_reason)s'")
 
 
-class EndpointNotFound(TempestException):
-    message = "Endpoint not found"
-
-
-class IdentityError(TempestException):
-    message = "Got identity error"
-
-
-class ServerUnreachable(TempestException):
+class ServerUnreachable(exceptions.TempestException):
     message = "The server is not reachable via the configured network"
 
 
 # NOTE(andreaf) This exception is added here to facilitate the migration
 # of get_network_from_name and preprov_creds to tempest.lib, and it should
 # be migrated along with them
-class InvalidTestResource(TempestException):
+class InvalidTestResource(exceptions.TempestException):
     message = "%(name) is not a valid %(type), or the name is ambiguous"
 
 
-class RFCViolation(RestClientException):
+class RFCViolation(exceptions.RestClientException):
     message = "RFC Violation"
-
-
-class InvalidHttpSuccessCode(RestClientException):
-    message = "The success code is different than the expected one"
-
-
-class BadRequest(RestClientException):
-    message = "Bad request"
-
-
-class ResponseWithNonEmptyBody(RFCViolation):
-    message = ("RFC Violation! Response with %(status)d HTTP Status Code "
-               "MUST NOT have a body")
-
-
-class ResponseWithEntity(RFCViolation):
-    message = ("RFC Violation! Response with 205 HTTP Status Code "
-               "MUST NOT have an entity")
-
-
-class InvalidHTTPResponseHeader(RestClientException):
-    message = "HTTP response header is invalid"
-
-
-class InvalidStructure(TempestException):
-    message = "Invalid structure of table with details"
-
-
-class CommandFailed(Exception):
-    def __init__(self, returncode, cmd, output, stderr):
-        super(CommandFailed, self).__init__()
-        self.returncode = returncode
-        self.cmd = cmd
-        self.stdout = output
-        self.stderr = stderr
-
-    def __str__(self):
-        return ("Command '%s' returned non-zero exit status %d.\n"
-                "stdout:\n%s\n"
-                "stderr:\n%s" % (self.cmd,
-                                 self.returncode,
-                                 self.stdout,
-                                 self.stderr))
diff --git a/tempest/lib/exceptions.py b/tempest/lib/exceptions.py
index 259bbbb..2a6a788 100644
--- a/tempest/lib/exceptions.py
+++ b/tempest/lib/exceptions.py
@@ -149,6 +149,10 @@
     message = "Unexpected response code received"
 
 
+class InvalidIdentityVersion(TempestException):
+    message = "Invalid version %(identity_version)s of the identity service"
+
+
 class InvalidStructure(TempestException):
     message = "Invalid structure of table with details"
 
diff --git a/tempest/manager.py b/tempest/manager.py
index 72762ab..f2659a8 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 from tempest import config
-from tempest import exceptions
 from tempest.lib import auth
+from tempest.lib import exceptions
 
 CONF = config.CONF
 
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 2b2f8ac..4ef9a87 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -223,7 +223,7 @@
                 port = self._create_port(network_id=net_id,
                                          client=clients.ports_client,
                                          **create_port_body)
-                ports.append({'port': port.id})
+                ports.append({'port': port['id']})
             if ports:
                 kwargs['networks'] = ports
             self.ports = ports
diff --git a/tempest/test.py b/tempest/test.py
index 4c0d0bb..4e06db8 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -39,6 +39,7 @@
 from tempest import exceptions
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
 
 LOG = logging.getLogger(__name__)
 
@@ -539,7 +540,7 @@
             if hasattr(cred_provider, credentials_method):
                 creds = getattr(cred_provider, credentials_method)()
             else:
-                raise exceptions.InvalidCredentials(
+                raise lib_exc.InvalidCredentials(
                     "Invalid credentials type %s" % credential_type)
         return cls.client_manager(credentials=creds.credentials,
                                   service=cls._service)
diff --git a/tempest/tests/lib/test_auth.py b/tempest/tests/lib/test_auth.py
index c08bf6a..12590a3 100644
--- a/tempest/tests/lib/test_auth.py
+++ b/tempest/tests/lib/test_auth.py
@@ -802,3 +802,12 @@
         _, auth_data = self.auth_provider.get_auth()
         self.assertIn('domain', auth_data)
         self.assertNotIn('project', auth_data)
+
+
+class TestGetCredentials(base.TestCase):
+
+    def test_invalid_identity_version(self):
+        with testtools.ExpectedException(exceptions.InvalidIdentityVersion,
+                                         '.* v1 .*'):
+            auth.get_credentials('http://localhost/identity/v3',
+                                 identity_version='v1')