]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Passing admin tenant name to EOS
authorShashank Hegde <shashank@arista.com>
Mon, 8 Sep 2014 22:05:30 +0000 (15:05 -0700)
committerShashank Hegde <shashank@arista.com>
Thu, 11 Sep 2014 00:22:51 +0000 (17:22 -0700)
The Arista ML2 plugin was not passing the admin tenant name to EOS without which
it is not possible to authenticate with keystone using just the admin name
and password. This patch passes the admin tenant name along with the admin
credentials.

Change-Id: I6c8b872087d17da2c3de43186d1916fc368dd786
Closes-Bug: 1359417

neutron/plugins/ml2/drivers/arista/mechanism_arista.py
neutron/tests/unit/ml2/drivers/arista/test_arista_mechanism_driver.py

index b52c98bce5653f3fd0ebedd65820393962052c9e..990cca983a72b04fc55736b39fe331066434c22c 100644 (file)
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import itertools
 import threading
 
 import jsonrpclib
@@ -377,15 +378,18 @@ class AristaRPCWrapper(object):
         This the initial handshake between Neutron and EOS.
         critical end-point information is registered with EOS.
         """
-        cmds = ['auth url %s user "%s" password "%s"' %
-                (self._keystone_url(),
-                self.keystone_conf.admin_user,
-                self.keystone_conf.admin_password)]
-
-        log_cmds = ['auth url %s user %s password ******' %
-                    (self._keystone_url(),
-                    self.keystone_conf.admin_user)]
 
+        cmds = ['auth url %s user %s password %s tenant %s' % (
+                self._keystone_url(),
+                self.keystone_conf.admin_user,
+                self.keystone_conf.admin_password,
+                self.keystone_conf.admin_tenant_name)]
+
+        log_cmds = ['auth url %s user %s password %s tenant %s' % (
+                    self._keystone_url(),
+                    self.keystone_conf.admin_user,
+                    '******',
+                    self.keystone_conf.admin_tenant_name)]
         self._run_openstack_cmds(cmds, commands_to_log=log_cmds)
 
     def clear_region_updated_time(self):
@@ -424,11 +428,11 @@ class AristaRPCWrapper(object):
                                  param is logged.
         """
 
-        log_cmd = commands
+        log_cmds = commands
         if commands_to_log:
-            log_cmd = commands_to_log
+            log_cmds = commands_to_log
 
-        LOG.info(_('Executing command on Arista EOS: %s'), log_cmd)
+        LOG.info(_('Executing command on Arista EOS: %s'), log_cmds)
 
         try:
             # this returns array of return values for every command in
@@ -436,10 +440,21 @@ class AristaRPCWrapper(object):
             ret = self._server.runCmds(version=1, cmds=commands)
         except Exception as error:
             host = cfg.CONF.ml2_arista.eapi_host
+            error_msg_str = unicode(error)
+            if commands_to_log:
+                # The command might contain sensitive information. If the
+                # command to log is different from the actual command, use
+                # that in the error message.
+                for cmd, log_cmd in itertools.izip(commands, log_cmds):
+                    error_msg_str = error_msg_str.replace(cmd, log_cmd)
             msg = (_('Error %(err)s while trying to execute '
                      'commands %(cmd)s on EOS %(host)s') %
-                   {'err': error, 'cmd': commands_to_log, 'host': host})
-            LOG.exception(msg)
+                  {'err': error_msg_str,
+                   'cmd': commands_to_log,
+                   'host': host})
+            # Logging exception here can reveal passwords as the exception
+            # contains the CLI command which contains the credentials.
+            LOG.error(msg)
             raise arista_exc.AristaRpcError(msg=msg)
 
         return ret
index 56b8a42afdd7c4ded3398a47521f2ea9552a4e82..7eeb97cac75e76ae76e4204466ab860fa7397701 100644 (file)
@@ -503,6 +503,28 @@ class PositiveRPCWrapperValidConfigTestCase(base.BaseTestCase):
         cmds = ['show openstack config region RegionOne timestamp']
         self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds)
 
+    def test_register_with_eos(self):
+        self.drv.register_with_eos()
+        auth = fake_keystone_info_class()
+        keystone_url = '%s://%s:%s/v2.0/' % (auth.auth_protocol,
+                                             auth.auth_host,
+                                             auth.auth_port)
+        auth_cmd = 'auth url %s user %s password %s tenant %s' % (keystone_url,
+                    auth.admin_user,
+                    auth.admin_password,
+                    auth.admin_tenant_name)
+        cmds = ['enable',
+                'configure',
+                'cvx',
+                'service openstack',
+                'region %s' % self.region,
+                auth_cmd,
+                'exit',
+                'exit',
+                'exit',
+                ]
+        self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds)
+
 
 class AristaRPCWrapperInvalidConfigTestCase(base.BaseTestCase):
     """Negative test cases to test the Arista Driver configuration."""
@@ -676,6 +698,7 @@ class fake_keystone_info_class(object):
     auth_port = 5000
     admin_user = 'neutron'
     admin_password = 'fun'
+    admin_tenant_name = 'tenant_name'
 
 
 class FakeNetworkContext(object):