Codebase list python-castellan / 17cd833
Merge "barbican key manager: Add support for service user" Zuul authored 2 years ago Gerrit Code Review committed 2 years ago
3 changed file(s) with 78 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
2424 from cryptography import x509 as cryptography_x509
2525 from keystoneauth1 import identity
2626 from keystoneauth1 import loading
27 from keystoneauth1 import service_token
2728 from keystoneauth1 import session
2829 from oslo_config import cfg
2930 from oslo_log import log as logging
7980 cfg.StrOpt('barbican_region_name',
8081 default=None,
8182 help='Specifies the region of the chosen endpoint.'),
82
83 cfg.BoolOpt('send_service_user_token',
84 default=False,
85 help="""
86 When True, if sending a user token to a REST API, also send a service token.
87
88 Nova often reuses the user token provided to the nova-api to talk to other REST
89 APIs, such as Cinder, Glance and Neutron. It is possible that while the user
90 token was valid when the request was made to Nova, the token may expire before
91 it reaches the other service. To avoid any failures, and to make it clear it is
92 Nova calling the service on the user's behalf, we include a service token along
93 with the user token. Should the user's token have expired, a valid service
94 token ensures the REST API request will still be accepted by the keystone
95 middleware.
96 """),
8397 ]
8498
99
85100 _BARBICAN_OPT_GROUP = 'barbican'
101 _BARBICAN_SERVICE_USER_OPT_GROUP = 'barbican_service_user'
86102
87103 LOG = logging.getLogger(__name__)
88104
97113 self.conf.register_opts(_barbican_opts, group=_BARBICAN_OPT_GROUP)
98114 loading.register_session_conf_options(self.conf, _BARBICAN_OPT_GROUP)
99115
116 loading.register_session_conf_options(self.conf,
117 _BARBICAN_SERVICE_USER_OPT_GROUP)
118 loading.register_auth_conf_options(self.conf,
119 _BARBICAN_SERVICE_USER_OPT_GROUP)
120
100121 def _get_barbican_client(self, context):
101122 """Creates a client to connect to the Barbican service.
102123
143164
144165 def _get_keystone_auth(self, context):
145166 if context.__class__.__name__ == 'KeystonePassword':
146 return identity.Password(
167 auth = identity.Password(
147168 auth_url=context.auth_url,
148169 username=context.username,
149170 password=context.password,
159180 project_domain_name=context.project_domain_name,
160181 reauthenticate=context.reauthenticate)
161182 elif context.__class__.__name__ == 'KeystoneToken':
162 return identity.Token(
183 auth = identity.Token(
163184 auth_url=context.auth_url,
164185 token=context.token,
165186 trust_id=context.trust_id,
174195 # projects begin to use utils.credential_factory
175196 elif context.__class__.__name__ == 'RequestContext':
176197 if getattr(context, 'get_auth_plugin', None):
177 return context.get_auth_plugin()
198 auth = context.get_auth_plugin()
178199 else:
179 return identity.Token(
200 auth = identity.Token(
180201 auth_url=self.conf.barbican.auth_endpoint,
181202 token=context.auth_token,
182203 project_id=context.project_id,
188209 "KeystoneToken, or RequestContext.")
189210 LOG.error(msg)
190211 raise exception.Forbidden(reason=msg)
212
213 if self.conf.barbican.send_service_user_token:
214 service_auth = loading.load_auth_from_conf_options(
215 self.conf,
216 group=_BARBICAN_SERVICE_USER_OPT_GROUP)
217 auth = service_token.ServiceTokenAuthWrapper(
218 user_auth=auth,
219 service_auth=service_auth)
220
221 return auth
191222
192223 def _get_barbican_endpoint(self, auth, sess):
193224 if self.conf.barbican.barbican_endpoint:
652683 return objects
653684
654685 def list_options_for_discovery(self):
655 return [(_BARBICAN_OPT_GROUP, _barbican_opts)]
686 barbican_service_user_opts = loading.get_session_conf_options()
687 barbican_service_user_opts += loading.get_auth_common_conf_options()
688
689 return [
690 (_BARBICAN_OPT_GROUP, _barbican_opts),
691 (_BARBICAN_SERVICE_USER_OPT_GROUP, barbican_service_user_opts),
692 ]
1919 from unittest import mock
2020
2121 from barbicanclient import exceptions as barbican_exceptions
22 from keystoneauth1 import identity
23 from keystoneauth1 import service_token
24 from oslo_context import context
2225 from oslo_utils import timeutils
2326
2427 from castellan.common import exception
3639 super(BarbicanKeyManagerTestCase, self).setUp()
3740
3841 # Create fake auth_token
39 self.ctxt = mock.Mock()
42 self.ctxt = mock.Mock(spec=context.RequestContext)
4043 self.ctxt.auth_token = "fake_token"
44 self.ctxt.project_name = "foo"
45 self.ctxt.project_domain_name = "foo"
4146
4247 # Create mock barbican client
4348 self._build_mock_barbican()
161166 auth.get_endpoint.assert_called_once_with(
162167 sess, service_type='key-manager', interface='public',
163168 region_name='regionOne')
169
170 def test__get_keystone_auth(self):
171 auth = self.key_mgr._get_keystone_auth(self.ctxt)
172 self.assertIsInstance(auth, identity.Token)
173
174 def test__get_keystone_auth_service_user(self):
175 self.key_mgr.conf.barbican.send_service_user_token = True
176 auth = self.key_mgr._get_keystone_auth(self.ctxt)
177 self.assertIsInstance(auth, service_token.ServiceTokenAuthWrapper)
164178
165179 def test_base_url_old_version(self):
166180 version = "v1"
606620 def test_list_with_invalid_object_type(self):
607621 self.assertRaises(exception.KeyManagerError,
608622 self.key_mgr.list, self.ctxt, "invalid_type")
623
624 def test_list_options_for_discovery(self):
625 opts = self.key_mgr.list_options_for_discovery()
626 expected_sections = ['barbican', 'barbican_service_user']
627 self.assertEqual(expected_sections, [section[0] for section in opts])
628 barbican_opts = [opt.name for opt in opts[0][1]]
629 # From Castellan opts.
630 self.assertIn('barbican_endpoint', barbican_opts)
631 barbican_service_user_opts = [opt.name for opt in opts[1][1]]
632 # From session opts.
633 self.assertIn('cafile', barbican_service_user_opts)
634 # From auth common opts.
635 self.assertIn('auth_section', barbican_service_user_opts)
0 ---
1 features:
2 - |
3 Adds support for using a service user with the Barbican key manager.
4 This is enabled via ``[barbican] send_service_user_token``, with
5 credentials for the service user configured via keystoneauth options in the
6 ``[barbican_service_user]`` group.