← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1401437] [NEW] nova passes incorrect authentication info to cinderclient

 

Public bug reported:

There are multiple problems with the authentication information that
nova/volume/cinder code passes to cinderclient:

1. nova/volume/cinder.py passes 'cinder endpoint publicURL'  as the
auth_url to cinderclient for credential authentication instead of the
keystone auth_url .This happens here:

get_cinder_client_version(context) sets the value for global CINDER_URL and passes it to
c = cinder_client.Client(version,
                             context.user_id,
                             context.auth_token,
                             project_id=context.project_id,
                             auth_url=CINDER_URL,
                             insecure=CONF.cinder.api_insecure,
                             retries=CONF.cinder.http_retries,
                             timeout=CONF.cinder.http_timeout,
                             cacert=CONF.cinder.ca_certificates_file)

c.client.auth_token = context.auth_token or '%s:%s' % (context.user_id,
                                                           context.project_id)
    

Under normal circumstances ( i e in cases where the context has
auth_token) , the auth_url is never used/required. So this is required
only when the token expires and an attempt to do fresh authentication is
made here:

def _cs_request(self, url, method, **kwargs):
        auth_attempts = 0
        attempts = 0
        backoff = 1
        while True:
            attempts += 1
            if not self.management_url or not self.auth_token:
                self.authenticate()
            kwargs.setdefault('headers', {})['X-Auth-Token'] = self.auth_token
            if self.projectid:
                kwargs['headers']['X-Auth-Project-Id'] = self.projectid
            try:
                resp, body = self.request(self.management_url + url, method,
                                          **kwargs)
                return resp, body
            except exceptions.BadRequest as e:
                if attempts > self.retries:
                    raise
            except exceptions.Unauthorized:
                if auth_attempts > 0:
                    raise
                self._logger.debug("Unauthorized, reauthenticating.")
                self.management_url = self.auth_token = None
                # First reauth. Discount this attempt.
                attempts -= 1
                auth_attempts += 1
                continue


2. nova/volume.cinderclient.py >> cinderclient method passes context.auth_token instead of the password.Due to this HttpClient.password attribute is set to the auth token instead of the password. 

3. There are other problems around this which is summarized as below:

cinderclient should really support a way of passing an auth_token in on
the __init__ so it is explicitly supported for the caller to specify an
auth_token, rather than forcing this hack that nova is currently using
of setting the auth_token itself after creating the cinderclient
instance. That's not strictly required, but it would be a much better
design. At that point, cinderclient should also stop requiring the
auth_url parameter (it currently raises an exception if that isn't
specified) if an auth_token is specified and retries==0, since in that
case the auth_url would never be used. Userid and password would also
not be required in that case.

nova needs to either start passing a valid userid and password and a
valid auth_url so that retries will work, or stop setting retries to a
non-zero number (it's using a conf setting to determine the number of
retries, and the default is 3). If the decision is to get retries
working, then we have to figure out what to pass for the userid and
password. Nova won't know the end-user's user/password that correspond
to the auth_token it initially uses, and we wouldn't want to be using a
different user on retries than we do on the initial requests, so I don't
think retries should be supported unless nova is going to make ALL
requests with a service userid rather than with the end-user's userid...
and I don't think that fits with the current OpenStack architecture. So
that leaves us with not supporting retries. In that case, nova should
still stop passing the auth_token in as the password so that someone
doesn't stumble over that later when retry support is added. Similarly
for the auth_url it should start passing the correct keystone auth_url,
or at least make it clear that it's passing an invalid auth_url so
someone doesn't stumble over that when trying to add retry support
later. And it definitely needs to stop setting retries to a non-zero
number.

** Affects: nova
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to OpenStack Compute (nova).
https://bugs.launchpad.net/bugs/1401437

Title:
  nova passes incorrect authentication info to cinderclient

Status in OpenStack Compute (Nova):
  New

Bug description:
  There are multiple problems with the authentication information that
  nova/volume/cinder code passes to cinderclient:

  1. nova/volume/cinder.py passes 'cinder endpoint publicURL'  as the
  auth_url to cinderclient for credential authentication instead of the
  keystone auth_url .This happens here:

  get_cinder_client_version(context) sets the value for global CINDER_URL and passes it to
  c = cinder_client.Client(version,
                               context.user_id,
                               context.auth_token,
                               project_id=context.project_id,
                               auth_url=CINDER_URL,
                               insecure=CONF.cinder.api_insecure,
                               retries=CONF.cinder.http_retries,
                               timeout=CONF.cinder.http_timeout,
                               cacert=CONF.cinder.ca_certificates_file)

  c.client.auth_token = context.auth_token or '%s:%s' % (context.user_id,
                                                             context.project_id)
      

  Under normal circumstances ( i e in cases where the context has
  auth_token) , the auth_url is never used/required. So this is required
  only when the token expires and an attempt to do fresh authentication
  is made here:

  def _cs_request(self, url, method, **kwargs):
          auth_attempts = 0
          attempts = 0
          backoff = 1
          while True:
              attempts += 1
              if not self.management_url or not self.auth_token:
                  self.authenticate()
              kwargs.setdefault('headers', {})['X-Auth-Token'] = self.auth_token
              if self.projectid:
                  kwargs['headers']['X-Auth-Project-Id'] = self.projectid
              try:
                  resp, body = self.request(self.management_url + url, method,
                                            **kwargs)
                  return resp, body
              except exceptions.BadRequest as e:
                  if attempts > self.retries:
                      raise
              except exceptions.Unauthorized:
                  if auth_attempts > 0:
                      raise
                  self._logger.debug("Unauthorized, reauthenticating.")
                  self.management_url = self.auth_token = None
                  # First reauth. Discount this attempt.
                  attempts -= 1
                  auth_attempts += 1
                  continue

  
  2. nova/volume.cinderclient.py >> cinderclient method passes context.auth_token instead of the password.Due to this HttpClient.password attribute is set to the auth token instead of the password. 

  3. There are other problems around this which is summarized as below:

  cinderclient should really support a way of passing an auth_token in
  on the __init__ so it is explicitly supported for the caller to
  specify an auth_token, rather than forcing this hack that nova is
  currently using of setting the auth_token itself after creating the
  cinderclient instance. That's not strictly required, but it would be a
  much better design. At that point, cinderclient should also stop
  requiring the auth_url parameter (it currently raises an exception if
  that isn't specified) if an auth_token is specified and retries==0,
  since in that case the auth_url would never be used. Userid and
  password would also not be required in that case.

  nova needs to either start passing a valid userid and password and a
  valid auth_url so that retries will work, or stop setting retries to a
  non-zero number (it's using a conf setting to determine the number of
  retries, and the default is 3). If the decision is to get retries
  working, then we have to figure out what to pass for the userid and
  password. Nova won't know the end-user's user/password that correspond
  to the auth_token it initially uses, and we wouldn't want to be using
  a different user on retries than we do on the initial requests, so I
  don't think retries should be supported unless nova is going to make
  ALL requests with a service userid rather than with the end-user's
  userid... and I don't think that fits with the current OpenStack
  architecture. So that leaves us with not supporting retries. In that
  case, nova should still stop passing the auth_token in as the password
  so that someone doesn't stumble over that later when retry support is
  added. Similarly for the auth_url it should start passing the correct
  keystone auth_url, or at least make it clear that it's passing an
  invalid auth_url so someone doesn't stumble over that when trying to
  add retry support later. And it definitely needs to stop setting
  retries to a non-zero number.

To manage notifications about this bug go to:
https://bugs.launchpad.net/nova/+bug/1401437/+subscriptions


Follow ups

References