Adding capability to retrieve scoped tokens

Services other than OpenStack requires scoped tokens.
Added methods to retrieve scoped tokens from keystone.

Change-Id: I171beabf62de3e27f13906bcd6e193ccc71e6c9d
This commit is contained in:
Rahul Nair 2016-09-01 12:47:14 -05:00
parent e9df59d322
commit 1740edacd4
3 changed files with 76 additions and 26 deletions

View File

@ -227,11 +227,12 @@ def list_user_opts():
secret=True),
cfg.StrOpt("user_id", default="",
help="Keystone user ID", secret=True),
cfg.StrOpt("project", default="", help="Keystone project ID"),
cfg.StrOpt("token", default="", help="Keystone auth token",
secret=True),
cfg.StrOpt("endpoint", default="", help="Keystone endpoint URI"),
cfg.StrOpt("domain_name", default="", help="Keystone domain name"),
cfg.StrOpt("project_id", default="", help="Keystone project id"),
cfg.StrOpt("project_name", default="", help="Keystone project name"),
cfg.StrOpt("domain_id", default="", help="Keystone domain id"),
cfg.StrOpt("tenant_name", default="", help="Keystone tenant name"),
cfg.StrOpt("tenant_id", default="", help="Keystone tenant id"),

View File

@ -29,9 +29,18 @@ CONF = cfg.CONF
@memoize
def authenticate_v2(
url, username=None, password=None, tenant_name=None,
tenant_id=None, domain=None, serialize_format="json",
tenant_id=None, scoped=False, serialize_format="json",
deserialize_format="json"):
"""Creates auth request body and sends it to the given v2 endpoint.
:param str username: OpenStack username
:param str password: OpenStack password
:param str tenant_name: Name of tenant to which the user belongs
:param str tenant_id: Id of the tenant
:param bool scoped: Flag to retrieve scoped/unscoped tokens
:param str serialize_format: Request body format(json/xml)
:param str deserialize_format: Response body format(json/xml)
"""
headers = {}
kwargs = {}
password_creds = None
@ -43,18 +52,19 @@ def authenticate_v2(
url = '{0}/v2.0/tokens'.format(url)
headers["Content-Type"] = "application/{0}".format(serialize_format)
headers["Accept"] = "application/{0}".format(deserialize_format)
kwargs["tenant_name"] = tenant_name
kwargs["tenant_id"] = tenant_id
password_creds = v2.PasswordCredentials(
username=username, password=password)
request_entity = v2.Auth(
tenant_name=tenant_name, tenant_id=tenant_id,
password_creds=password_creds
)
if scoped:
request_entity = v2.Auth(
tenant_name=tenant_name, tenant_id=tenant_id,
password_creds=password_creds
)
else:
request_entity = v2.Auth(
password_creds=password_creds
)
data = request_entity.serialize(serialize_format)
try:
resp, signals = SynHTTPClient().request(
@ -73,7 +83,8 @@ def authenticate_v2(
@memoize
def authenticate_v2_config(user_section):
def authenticate_v2_config(user_section, scoped=False):
"""Verifies minimum requirement for v2 auth."""
endpoint = CONF.get(user_section).endpoint or CONF.user.endpoint
password = CONF.get(user_section).password or CONF.user.password
if not endpoint or not password:
@ -88,24 +99,43 @@ def authenticate_v2_config(user_section):
tenant_name=CONF.get(user_section).tenant_name or
CONF.user.tenant_name,
tenant_id=CONF.get(user_section).tenant_id or CONF.user.tenant_id,
serialize_format=CONF.get(user_section).serialize_format or
CONF.user.serialize_format,
deserialize_format=CONF.get(user_section).deserialize_format or
CONF.user.deserialize_format)
scoped=scoped)
@memoize
def get_token_v2(user_section='user'):
"""Returns unscoped v2 token."""
access_data = authenticate_v2_config(user_section)
return access_data['token']['id']
@memoize
def get_scoped_token_v2(user_section='user'):
"""Returns scoped v2 token."""
access_data = authenticate_v2_config(user_section, scoped=True)
return access_data['token']['id']
@memoize
def authenticate_v3(
url, username=None, password=None, user_id=None, domain_id=None,
domain_name=None, token=None, serialize_format="json",
deserialize_format="json"):
domain_name=None, token=None, project_name=None,
project_id=None, scoped=False,
serialize_format="json", deserialize_format="json"):
"""Creates auth request body and sends it to the given v3 endpoint.
:param str username: OpenStack username
:param str password: OpenStack password
:param str user_id: Id of the user
:param str domain_name: Name of Domain the user belongs to
:param str domain_id: Id of the domain
:param str token: An auth token
:param str project_name: Name of the project user is part of
:param str project_id: Id of the project
:param bool scoped: Flag to retrieve scoped/unscoped tokens
:param str serialize_format: Request body format(json/xml)
:param str deserialize_format: Response body format(json/xml)
"""
headers = {}
kwargs = {}
if url.endswith('/v3/'):
@ -116,22 +146,29 @@ def authenticate_v3(
url = '{0}/v3/auth/tokens'.format(url)
headers["Content-Type"] = "application/json"
headers["Accept"] = "application/json"
if user_id:
domain = None
username = None
else:
domain = v3.Domain(name=domain_name, id_=domain_id)
password = v3.Password(user=v3.User(
name=username, password=password, id_=user_id, domain=domain
))
if token:
kwargs = {"token": v3.Token(id_=token), "methods": ["token"]}
else:
kwargs = {"password": password, "methods": ["password"]}
request_entity = v3.Auth(identity=v3.Identity(**kwargs))
if scoped:
if project_id:
project_name = None
domain = None
elif domain is None:
domain = v3.Domain(name=domain_name, id_=domain_id)
project = v3.Project(name=project_name, id_=project_id, domain=domain)
scope = v3.Scope(project=project, domain=domain)
else:
scope = None
request_entity = v3.Auth(identity=v3.Identity(**kwargs), scope=scope)
data = request_entity.serialize(serialize_format)
try:
r, signals = SynHTTPClient().request(
@ -146,7 +183,8 @@ def authenticate_v3(
@memoize
def authenticate_v3_config(user_section):
def authenticate_v3_config(user_section, scoped=False):
"""Verifies minimum requirement for v3 auth."""
endpoint = CONF.get(user_section).endpoint or CONF.user.endpoint
if not endpoint:
raise KeyError("Required config parameters not present: endpoint")
@ -158,10 +196,22 @@ def authenticate_v3_config(user_section):
domain_id=CONF.get(user_section).domain_id or CONF.user.domain_id,
domain_name=CONF.get(user_section).domain_name or
CONF.user.domain_name,
token=CONF.get(user_section).token or CONF.user.token)
token=CONF.get(user_section).token or CONF.user.token,
project_name=CONF.get(
user_section).project_name or CONF.user.project_name,
project_id=CONF.get(user_section).project_id or CONF.user.project_id,
scoped=scoped)
@memoize
def get_token_v3(user_section='user'):
"""Returns an unscoped v3 token."""
r = authenticate_v3_config(user_section)
return r.headers["X-Subject-Token"]
@memoize
def get_scoped_token_v3(user_section='user'):
"""Returns a scoped v3 token."""
r = authenticate_v3_config(user_section, scoped=True)
return r.headers["X-Subject-Token"]

View File

@ -77,8 +77,7 @@ class Scope(syntribos.extensions.identity.models.base.BaseIdentityModel):
def _obj_to_dict(self):
return self._remove_empty_values({
"project": self._get_sub_model(self.project),
"domain": self._get_sub_model(self.domain)})
"project": self._get_sub_model(self.project)})
class Domain(syntribos.extensions.identity.models.base.BaseIdentityModel):
@ -92,7 +91,7 @@ class Domain(syntribos.extensions.identity.models.base.BaseIdentityModel):
"id": self.id_})
class Project(Domain):
class Project(syntribos.extensions.identity.models.base.BaseIdentityModel):
def __init__(self, name=None, id_=None, domain=None):
super(Project, self).__init__(locals())