Fixes LP 973338 - Add custom alt and admin manager

* Adds new AltManager, AdminManager derived manager classes
* Allows Manager to be inited with custom credentials
* Adds config.ComputeAdminConfig class and setup
* Updates test_authorization to use AltManager class

Change-Id: Iff5b20fbdfb8979a775f30f7e07d6e06b29e6c1c
diff --git a/tempest/config.py b/tempest/config.py
index 2a64869..8c014bf 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -170,6 +170,26 @@
         return self.get("log_level", 'ERROR')
 
 
+class ComputeAdminConfig(BaseConfig):
+
+    SECTION_NAME = "compute-admin"
+
+    @property
+    def username(self):
+        """Administrative Username to use for Nova API requests."""
+        return self.get("username", "admin")
+
+    @property
+    def tenant_name(self):
+        """Administrative Tenant name to use for Nova API requests."""
+        return self.get("tenant_name", "admin")
+
+    @property
+    def password(self):
+        """API key to use when authenticating as admin."""
+        return self.get("password", "pass")
+
+
 class ImagesConfig(BaseConfig):
 
     """
@@ -253,6 +273,7 @@
 
         self._conf = self.load_config(path)
         self.compute = ComputeConfig(self._conf)
+        self.compute_admin = ComputeAdminConfig(self._conf)
         self.identity = IdentityConfig(self._conf)
         self.images = ImagesConfig(self._conf)
 
diff --git a/tempest/openstack.py b/tempest/openstack.py
index ffe59c4..491f385 100644
--- a/tempest/openstack.py
+++ b/tempest/openstack.py
@@ -40,12 +40,21 @@
     Top level manager for OpenStack Compute clients
     """
 
-    def __init__(self):
+    def __init__(self, username=None, password=None, tenant_name=None):
+        """
+        We allow overriding of the credentials used within the various
+        client classes managed by the Manager object. Left as None, the
+        standard username/password/tenant_name is used.
+
+        :param username: Override of the username
+        :param password: Override of the password
+        :param tenant_name: Override of the tenant name
+        """
         self.config = tempest.config.TempestConfig()
 
-        username = self.config.compute.username
-        password = self.config.compute.password
-        tenant_name = self.config.compute.tenant_name
+        username = username or self.config.compute.username
+        password = password or self.config.compute.password
+        tenant_name = tenant_name or self.config.compute.tenant_name
 
         if None in (username, password, tenant_name):
             msg = ("Missing required credentials. "
@@ -72,6 +81,35 @@
         self.volumes_client = VolumesClient(*client_args)
 
 
+class AltManager(Manager):
+
+    """
+    Manager object that uses the alt_XXX credentials for its
+    managed client objects
+    """
+
+    def __init__(self):
+        conf = tempest.config.TempestConfig()
+        super(AltManager, self).__init__(conf.compute.alt_username,
+                                         conf.compute.alt_password,
+                                         conf.compute.alt_tenant_name)
+
+
+class AdminManager(Manager):
+
+    """
+    Manager object that uses the alt_XXX credentials for its
+    managed client objects
+    """
+
+    def __init__(self):
+        conf = tempest.config.TempestConfig()
+        super(AdminManager, self).__init__(conf.compute_admin.username,
+                                           conf.compute_admin.password,
+                                           conf.compute_admin.tenant_name)
+        # TODO(jaypipes): Add Admin-Only client class construction below...
+
+
 class ServiceManager(object):
 
     """
diff --git a/tempest/tests/test_authorization.py b/tempest/tests/test_authorization.py
index 29f6155..5b2eeca 100644
--- a/tempest/tests/test_authorization.py
+++ b/tempest/tests/test_authorization.py
@@ -36,18 +36,9 @@
             and cls.user2_tenant_name != None):
 
             try:
-                # Setup a client instance for the second user
-                auth_url = cls.config.identity.auth_url
-
-                if cls.config.identity.strategy == 'keystone':
-                    cls.client_args = (cls.config, cls.user2,
-                                       cls.user2_password,
-                                       auth_url, cls.user2_tenant_name)
-                else:
-                    cls.client_args = (cls.config, cls.user2,
-                                       cls.user2_password, auth_url)
-                cls.other_client = ServersClient(*cls.client_args)
-                cls.other_images_client = ImagesClient(*cls.client_args)
+                cls.other_manager = openstack.AltManager()
+                cls.other_client = cls.other_manager.servers_client
+                cls.other_images_client = cls.other_manager.images_client
             except exceptions.AuthenticationFailure:
                 # multi_user is already set to false, just fall through
                 pass
@@ -162,12 +153,15 @@
         A create server request should fail if the tenant id does not match
         the current user
         """
-        other_servers_client = ServersClient(*self.client_args)
-
-        # Change the base URL to impersonate another user
-        other_servers_client.client.base_url = self.client.client.base_url
-        other_servers_client.create_server('test', self.image['id'],
-                                              self.flavor_ref)
+        try:
+            saved_base_url = self.other_client.client.base_url
+            # Change the base URL to impersonate another user
+            self.other_client.client.base_url = self.client.client.base_url
+            self.other_client.create_server('test', self.image['id'],
+                                                    self.flavor_ref)
+        finally:
+            # Reset the base_url...
+            self.other_client.client.base_url = saved_base_url
 
     @classmethod
     def _parse_image_id(self, image_ref):