'Authenticate with the Keystone service.
There are a few scenarios to consider here:
1. Which version of Keystone are we using? v1 which uses headers to
pass the credentials, or v2 which uses a JSON encoded request body?
2. Keystone may respond back with a redirection using a 305 status
code.
3. We may attempt a v1 auth when v2 is what\'s called for. In this
case, we rewrite the url to contain /v2.0/ and retry using the v2
protocol.'

def authenticate(self):

    def _authenticate(auth_url):
        if (not auth_url.endswith('/')):
            auth_url += '/'
        token_url = urlparse.urljoin(auth_url, 'tokens')
        is_v2 = auth_url.rstrip('/').endswith('v2.0')
        if is_v2:
            self._v2_auth(token_url)
        else:
            self._v1_auth(token_url)
    self.check_auth_params()
    auth_url = self.creds['auth_url']
    for redirect_iter in range(self.MAX_REDIRECTS):
        try:
            _authenticate(auth_url)
        except exception.AuthorizationRedirect as e:
            auth_url = e.url
        except exception.AuthorizationFailure:
            if ('v2.0' not in auth_url):
                auth_url = urlparse.urljoin(auth_url, 'v2.0/')
        else:
            self.creds['auth_url'] = auth_url
            break
    else:
        raise exception.MaxRedirectsExceeded(redirects=self.MAX_REDIRECTS)
