Combine resources across federated OpenStack deployments
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth.py 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # Copyright 2016 Massachusetts Open Cloud
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. from keystoneauth1 import identity
  15. from keystoneauth1 import session
  16. from keystoneclient import v3
  17. from keystoneauth1.exceptions import http
  18. import json
  19. from flask import abort
  20. from mixmatch import config
  21. CONF = config.CONF
  22. LOG = config.LOG
  23. MEMOIZE_SESSION = config.auth.MEMOIZE
  24. @MEMOIZE_SESSION
  25. def get_admin_session(sp=None):
  26. """Return a Keystone session using admin service credentials."""
  27. LOG.info("Getting Admin Session")
  28. service_auth = identity.Password(
  29. auth_url=CONF.auth.auth_url,
  30. username=CONF.auth.username,
  31. password=CONF.auth.password,
  32. project_name=CONF.auth.project_name,
  33. project_domain_id=CONF.auth.project_domain_id,
  34. user_domain_id=CONF.auth.user_domain_id
  35. )
  36. sess = session.Session(auth=service_auth)
  37. if sp is None:
  38. return sess
  39. else:
  40. token = sess.get_token()
  41. project_id = get_projects_at_sp(sp, token)[0]
  42. remote_admin_sess = get_sp_auth(sp, token, project_id)
  43. return remote_admin_sess
  44. @MEMOIZE_SESSION
  45. def get_client(session):
  46. """Return a client object given a session object."""
  47. LOG.debug("Getting client for %s" % session)
  48. return v3.client.Client(session=session)
  49. @MEMOIZE_SESSION
  50. def get_local_auth(user_token):
  51. """Return a Keystone session for the local cluster."""
  52. LOG.debug("Getting session for %s" % user_token)
  53. admin_session = get_admin_session()
  54. client = get_client(admin_session)
  55. token = v3.tokens.TokenManager(client)
  56. try:
  57. token_data = token.validate(token=user_token, include_catalog=False)
  58. except http.NotFound:
  59. abort(401)
  60. project_id = token_data['project']['id']
  61. local_auth = identity.v3.Token(auth_url=CONF.auth.auth_url,
  62. token=user_token,
  63. project_id=project_id)
  64. return session.Session(auth=local_auth)
  65. @MEMOIZE_SESSION
  66. def get_unscoped_sp_auth(service_provider, user_token):
  67. """Perform K2K auth, and return an unscoped session."""
  68. conf = config.service_providers.get(CONF, service_provider)
  69. local_auth = get_local_auth(user_token).auth
  70. LOG.debug("Getting unscoped session for (%s, %s)" % (service_provider,
  71. user_token))
  72. remote_auth = identity.v3.Keystone2Keystone(
  73. local_auth,
  74. conf.sp_name
  75. )
  76. return session.Session(auth=remote_auth)
  77. def get_projects_at_sp(service_provider, user_token):
  78. """Perform K2K auth, and return the projects that can be scoped to."""
  79. conf = config.service_providers.get(CONF, service_provider)
  80. unscoped_session = get_unscoped_sp_auth(service_provider, user_token)
  81. r = json.loads(str(unscoped_session.get(
  82. conf.auth_url + "/auth/projects").text))
  83. return [project[u'id'] for project in r[u'projects']]
  84. @MEMOIZE_SESSION
  85. def get_sp_auth(service_provider, user_token, remote_project_id):
  86. """Perform K2K auth, and return a session for a remote cluster."""
  87. conf = config.service_providers.get(CONF, service_provider)
  88. local_auth = get_local_auth(user_token).auth
  89. LOG.debug("Getting session for (%s, %s, %s)" % (service_provider,
  90. user_token,
  91. remote_project_id))
  92. remote_auth = identity.v3.Keystone2Keystone(
  93. local_auth,
  94. conf.sp_name,
  95. project_id=remote_project_id
  96. )
  97. return session.Session(auth=remote_auth)