]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
openstack: use OS_AUTH_TYPE=token_endpoint when possible 949/head
authorLoic Dachary <ldachary@redhat.com>
Fri, 2 Sep 2016 06:49:18 +0000 (08:49 +0200)
committerLoic Dachary <ldachary@redhat.com>
Wed, 14 Sep 2016 06:11:19 +0000 (08:11 +0200)
It requires setting the OS_URL depending on the command and avoids
calling the auth endpoint entirely.

Fixes: http://tracker.ceph.com/issues/16893
Signed-off-by: Loic Dachary <loic@dachary.org>
teuthology/openstack/__init__.py
teuthology/openstack/test/test_openstack.py
teuthology/provision/openstack.py

index 13947e2d52d250974e0577b231bb6743ea7fb495..a13c4cf61d412074a4f85263e8a060ff858fcbd8 100644 (file)
@@ -215,31 +215,66 @@ class OpenStack(object):
         if self.provider != 'ovh':
             return False
         if (OpenStack.token is None and
-            os.environ.get('OS_AUTH_TYPE') == 'v2token' and
-            'OS_TOKEN' in os.environ and
+            'OS_TOKEN_VALUE' in os.environ and
             'OS_TOKEN_EXPIRES' in os.environ):
             log.debug("get token from the environment of the parent process")
-            OpenStack.token = os.environ['OS_TOKEN']
+            OpenStack.token = os.environ['OS_TOKEN_VALUE']
             OpenStack.token_expires = int(os.environ['OS_TOKEN_EXPIRES'])
         if (OpenStack.token_expires is not None and
             OpenStack.token_expires < time.time()):
             log.debug("token discarded because it has expired")
             OpenStack.token = None
         if OpenStack.token is None:
-            if os.environ.get('OS_AUTH_TYPE') == 'v2token':
-                del os.environ['OS_AUTH_TYPE']
+            if 'OS_TOKEN_VALUE' in os.environ:
+                del os.environ['OS_TOKEN_VALUE']
             OpenStack.token = misc.sh("openstack -q token issue -c id -f value").strip()
-            os.environ['OS_AUTH_TYPE'] = 'v2token'
-            os.environ['OS_TOKEN'] = OpenStack.token
+            os.environ['OS_TOKEN_VALUE'] = OpenStack.token
             OpenStack.token_expires = int(time.time() + OpenStack.token_cache_duration)
             os.environ['OS_TOKEN_EXPIRES'] = str(OpenStack.token_expires)
-            log.info("caching OS_TOKEN and setting OS_AUTH_TYPE=v2token "
+            log.info("caching OS_TOKEN_VALUE "
                      "during %s seconds" % OpenStack.token_cache_duration)
         return True
+
+    def get_os_url(self, cmd, type=None):
+        if self.provider != 'ovh':
+            return ""
+        url = ""
+        if (type == 'compute' or
+            cmd.startswith("server ") or
+            cmd.startswith("flavor ")):
+            url = "https://compute.{reg}.cloud.ovh.net/v2/{tenant}"
+        elif (type == 'network' or
+              cmd.startswith("ip ") or
+              cmd.startswith("security ") or
+              cmd.startswith("network ")):
+            url = "https://network.compute.{reg}.cloud.ovh.net/"
+        elif (type == 'image' or
+              cmd.startswith("image ")):
+            url = "https://image.compute.{reg}.cloud.ovh.net/"
+        elif (type == 'volume' or
+              cmd.startswith("volume ")):
+            url = "https://volume.compute.{reg}.cloud.ovh.net/v2/{tenant}"
+        if url != "":
+            url = url.format(reg=os.environ['OS_REGION_NAME'],
+                             tenant=os.environ['OS_TENANT_ID'])
+        return url
         
     def run(self, cmd, *args, **kwargs):
-        self.cache_token()
-        return misc.sh("openstack --quiet " + cmd, *args, **kwargs)
+        url = self.get_os_url(cmd, kwargs.get('type'))
+        if url != "":
+            if self.cache_token():
+                os.environ['OS_TOKEN'] = os.environ['OS_TOKEN_VALUE']
+                os.environ['OS_URL'] = url
+        if re.match('(server|flavor|ip|security|network|image|volume)', cmd):
+            cmd = "openstack --quiet " + cmd
+        try:
+            status = misc.sh(cmd)
+        finally:
+            if 'OS_TOKEN' in os.environ:
+                del os.environ['OS_TOKEN']
+            if 'OS_URL' in os.environ:
+                del os.environ['OS_URL']
+        return status
     
     def set_provider(self):
         if 'OS_AUTH_URL' not in os.environ:
@@ -681,6 +716,8 @@ ssh access           : ssh {identity}{username}@{ip} # logs in /usr/share/nginx/
         template = open(user_data).read()
         openrc = ''
         for (var, value) in os.environ.iteritems():
+            if var in ('OS_TOKEN_VALUE', 'OS_TOKEN_EXPIRES'):
+                continue
             if var.startswith('OS_'):
                 openrc += ' ' + var + '=' + value
         if self.args.upload:
@@ -745,7 +782,11 @@ openstack security group rule create --proto udp --dst-port 16000:65535 teutholo
 
     @staticmethod
     def create_floating_ip():
-        pools = json.loads(OpenStack().run("ip floating pool list -f json"))
+        try:
+            pools = json.loads(OpenStack().run("ip floating pool list -f json"))
+        except subprocess.CalledProcessError:
+            log.debug("create_floating_ip: ip floating pool list failed")
+            return None
         if not pools:
             return None
         pool = pools[0]['Name']
index 3c9155e2544da841488df0081aeb6aec50d812c5..6140957e6cc4d35bc54cb52cfae3fbb45e2bbb04 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015 Red Hat, Inc.
+# Copyright (c) 2015,2016 Red Hat, Inc.
 #
 # Author: Loic Dachary <loic@dachary.org>
 #
@@ -274,6 +274,31 @@ class TestOpenStack(object):
         else:
             del os.environ['OS_AUTH_URL']
 
+    def test_get_os_url(self):
+        o = OpenStack()
+        #
+        # Only for OVH
+        #
+        o.provider = 'something'
+        assert "" == o.get_os_url("server ")
+        o.provider = 'ovh'
+        assert "" == o.get_os_url("unknown ")
+        type2cmd = {
+            'compute': ('server', 'flavor'),
+            'network': ('ip', 'security', 'network'),
+            'image': ('image',),
+            'volume': ('volume',),
+        }
+        os.environ['OS_REGION_NAME'] = 'REGION'
+        os.environ['OS_TENANT_ID'] = 'TENANT'
+        for (type, cmds) in type2cmd.iteritems():
+            for cmd in cmds:
+                assert ("//" + type) in o.get_os_url(cmd + " ")
+        for type in type2cmd.keys():
+            assert ("//" + type) in o.get_os_url("whatever ", type=type)
+        del os.environ['OS_REGION_NAME']
+        del os.environ['OS_TENANT_ID']
+
     @patch('teuthology.misc.sh')
     def test_cache_token(self, m_sh):
         token = 'TOKEN VALUE'
@@ -289,13 +314,11 @@ class TestOpenStack(object):
         #
         # Set the environment with the token
         #
-        assert 'OS_AUTH_TYPE' not in os.environ
-        assert 'OS_TOKEN' not in os.environ
+        assert 'OS_TOKEN_VALUE' not in os.environ
         assert 'OS_TOKEN_EXPIRES' not in os.environ
         assert True == o.cache_token()
         m_sh.assert_called_with('openstack -q token issue -c id -f value')
-        assert 'v2token' == os.environ['OS_AUTH_TYPE']
-        assert token == os.environ['OS_TOKEN']
+        assert token == os.environ['OS_TOKEN_VALUE']
         assert token == OpenStack.token
         assert time.time() < int(os.environ['OS_TOKEN_EXPIRES'])
         assert time.time() < OpenStack.token_expires
@@ -307,8 +330,7 @@ class TestOpenStack(object):
         assert True == o.cache_token()
         assert time.time() < int(os.environ['OS_TOKEN_EXPIRES'])
         assert time.time() < OpenStack.token_expires
-        del os.environ['OS_AUTH_TYPE']
-        del os.environ['OS_TOKEN']
+        del os.environ['OS_TOKEN_VALUE']
         del os.environ['OS_TOKEN_EXPIRES']
 
     @patch('teuthology.misc.sh')
@@ -317,16 +339,14 @@ class TestOpenStack(object):
         o = OpenStack()
         o.provider = 'ovh'
         token = 'TOKEN VALUE'
-        os.environ['OS_AUTH_TYPE'] = 'v2token'
-        os.environ['OS_TOKEN'] = token
+        os.environ['OS_TOKEN_VALUE'] = token
         token_expires = int(time.time()) + OpenStack.token_cache_duration
         os.environ['OS_TOKEN_EXPIRES'] = str(token_expires)
         assert True == o.cache_token()
         assert token == OpenStack.token
         assert token_expires == OpenStack.token_expires
         m_sh.assert_not_called()
-        del os.environ['OS_AUTH_TYPE']
-        del os.environ['OS_TOKEN']
+        del os.environ['OS_TOKEN_VALUE']
         del os.environ['OS_TOKEN_EXPIRES']
         
     @patch('teuthology.misc.sh')
@@ -336,19 +356,16 @@ class TestOpenStack(object):
         OpenStack.token = None
         o = OpenStack()
         o.provider = 'ovh'
-        os.environ['OS_AUTH_TYPE'] = 'v2token'
-        os.environ['OS_TOKEN'] = token
+        os.environ['OS_TOKEN_VALUE'] = token
         token_expires = int(time.time()) - 2000
         os.environ['OS_TOKEN_EXPIRES'] = str(token_expires)
         assert True == o.cache_token()
         m_sh.assert_called_with('openstack -q token issue -c id -f value')
-        assert 'v2token' == os.environ['OS_AUTH_TYPE']
-        assert token == os.environ['OS_TOKEN']
+        assert token == os.environ['OS_TOKEN_VALUE']
         assert token == OpenStack.token
         assert time.time() < int(os.environ['OS_TOKEN_EXPIRES'])
         assert time.time() < OpenStack.token_expires
-        del os.environ['OS_AUTH_TYPE']
-        del os.environ['OS_TOKEN']
+        del os.environ['OS_TOKEN_VALUE']
         del os.environ['OS_TOKEN_EXPIRES']
 
 class TestTeuthologyOpenStack(object):
index 27f5e6529b5cba3bf902a834e9570ece0c891914..b16041e502922a35916aa1aaaac59938c19083cd 100644 (file)
@@ -66,22 +66,33 @@ class ProvisionOpenStack(OpenStack):
             except subprocess.CalledProcessError as e:
                 if 'No volume with a name or ID' not in e.output:
                     raise e
-                self.run("volume create -f json " +
-                         config['openstack'].get('volume-create', '') + " " +
-                         " --property ownedby=" + config.openstack['ip'] +
-                         " --size " + str(volumes['size']) + " " +
-                         volume_name)
+                # do not use OpenStack().run because its
+                # bugous for volume create as of openstackclient 3.2.0
+                # https://bugs.launchpad.net/python-openstackclient/+bug/1619726
+                misc.sh(
+                    "openstack volume create -f json " +
+                    config['openstack'].get('volume-create', '') + " " +
+                    " --property ownedby=" + config.openstack['ip'] +
+                    " --size " + str(volumes['size']) + " " +
+                    volume_name)
             with safe_while(sleep=2, tries=100,
                             action="volume " + volume_name) as proceed:
                 while proceed():
-                    r = self.run("volume show  -f json " + volume_name)
-                    status = self.get_value(json.loads(r), 'status')
-                    if status == 'available':
-                        break
-                    else:
-                        log.info("volume " + volume_name +
-                                 " not available yet")
-            self.run("server add volume " + name + " " + volume_name)
+                    try:
+                        r = OpenStack().run("volume show  -f json " +
+                                            volume_name)
+                        status = self.get_value(json.loads(r), 'status')
+                        if status == 'available':
+                            break
+                        else:
+                            log.info("volume " + volume_name +
+                                     " not available yet")
+                    except subprocess.CalledProcessError:
+                            log.info("volume " + volume_name +
+                                     " not information available yet")
+            # do not use OpenStack().run because its
+            # bugous for volume
+            misc.sh("openstack server add volume " + name + " " + volume_name)
 
     @staticmethod
     def ip2name(prefix, ip):
@@ -127,7 +138,7 @@ class ProvisionOpenStack(OpenStack):
                " --wait " +
                " " + self.basename)
         try:
-            misc.sh(cmd)
+            self.run(cmd, type='compute')
         except CalledProcessError as exc:
             if "quota exceeded" in exc.output.lower():
                 raise QuotaExceededError(message=exc.output)