rework creating admin context - use keystoneauth1 lib
rather than own creator of session and auth_plugin from keystoneclient library. Change-Id: Id7f71e08de13e77586832f6d12cba1caff3772fe
This commit is contained in:
parent
590ff04f07
commit
d67adb7223
@ -28,6 +28,7 @@ EC2API_CONF_DIR=${EC2API_CONF_DIR:-/etc/ec2api}
|
||||
EC2API_CONF_FILE=${EC2API_CONF_DIR}/ec2api.conf
|
||||
EC2API_DEBUG=${EC2API_DEBUG:-True}
|
||||
EC2API_STATE_PATH=${EC2API_STATE_PATH:=$DATA_DIR/ec2api}
|
||||
EC2API_AUTH_CACHE_DIR=${EC2API_AUTH_CACHE_DIR:-/var/cache/ec2api}
|
||||
|
||||
EC2API_SERVICE_PORT=${EC2API_SERVICE_PORT:-8788}
|
||||
EC2API_S3_SERVICE_PORT=${EC2API_S3_SERVICE_PORT:-3334}
|
||||
@ -178,12 +179,9 @@ function configure_ec2api {
|
||||
# ec2api Api Configuration
|
||||
#-------------------------
|
||||
|
||||
iniset $EC2API_CONF_FILE DEFAULT admin_tenant_name $SERVICE_TENANT_NAME
|
||||
iniset $EC2API_CONF_FILE DEFAULT admin_user $EC2API_ADMIN_USER
|
||||
iniset $EC2API_CONF_FILE DEFAULT admin_password $SERVICE_PASSWORD
|
||||
configure_auth_token_middleware $EC2API_CONF_FILE $EC2API_ADMIN_USER $EC2API_AUTH_CACHE_DIR
|
||||
|
||||
iniset $EC2API_CONF_FILE DEFAULT ec2api_workers "$API_WORKERS"
|
||||
iniset $EC2API_CONF_FILE DEFAULT keystone_url "$KEYSTONE_SERVICE_URI"
|
||||
iniset $EC2API_CONF_FILE DEFAULT keystone_ec2_tokens_url "$KEYSTONE_SERVICE_URI_V3/ec2tokens"
|
||||
iniset $EC2API_CONF_FILE DEFAULT region_list "$REGION_NAME"
|
||||
|
||||
|
@ -47,6 +47,10 @@ LOG = logging.getLogger(__name__)
|
||||
ec2_opts = [
|
||||
cfg.StrOpt('keystone_url',
|
||||
default='http://localhost:5000/',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='code was switched to common section '
|
||||
'"keystone_authtoken"',
|
||||
deprecated_since='Newton',
|
||||
help='URL for getting admin session.'),
|
||||
cfg.StrOpt('keystone_ec2_tokens_url',
|
||||
default='http://localhost:5000/v3/ec2tokens',
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
from cinderclient import client as cinderclient
|
||||
from glanceclient import client as glanceclient
|
||||
from keystoneauth1 import loading as ks_loading
|
||||
from keystoneclient.auth.identity.generic import password as keystone_auth
|
||||
from keystoneclient import client as keystoneclient
|
||||
from keystoneclient import session as keystone_session
|
||||
@ -31,8 +32,16 @@ logger = logging.getLogger(__name__)
|
||||
ec2_opts = [
|
||||
cfg.BoolOpt('ssl_insecure',
|
||||
default=False,
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='code was switched to common section '
|
||||
'"keystone_authtoken"',
|
||||
deprecated_since='Newton',
|
||||
help="Verify HTTPS connections."),
|
||||
cfg.StrOpt('ssl_ca_file',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='code was switched to common section '
|
||||
'"keystone_authtoken"',
|
||||
deprecated_since='Newton',
|
||||
help="CA certificate file to use to verify "
|
||||
"connecting clients"),
|
||||
cfg.StrOpt('nova_service_type',
|
||||
@ -45,20 +54,34 @@ ec2_opts = [
|
||||
default='volumev2',
|
||||
help='Service type of Volume API, registered in Keystone '
|
||||
'catalog.'),
|
||||
# TODO(andrey-mp): keystone v3 allows to pass domain_name
|
||||
# or domain_id to auth. This code should support this feature.
|
||||
cfg.StrOpt('admin_user',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='code was switched to common section '
|
||||
'"keystone_authtoken"',
|
||||
deprecated_since='Newton',
|
||||
help=_("Admin user to access specific cloud resourses")),
|
||||
cfg.StrOpt('admin_password',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='code was switched to common section '
|
||||
'"keystone_authtoken"',
|
||||
deprecated_since='Newton',
|
||||
help=_("Admin password"),
|
||||
secret=True),
|
||||
cfg.StrOpt('admin_tenant_name',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='code was switched to common section '
|
||||
'"keystone_authtoken"',
|
||||
deprecated_since='Newton',
|
||||
help=_("Admin tenant name")),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(ec2_opts)
|
||||
|
||||
GROUP_AUTHTOKEN = 'keystone_authtoken'
|
||||
ks_loading.register_session_conf_options(CONF, GROUP_AUTHTOKEN)
|
||||
ks_loading.register_auth_conf_options(CONF, GROUP_AUTHTOKEN)
|
||||
|
||||
|
||||
# Nova API version with microversions support
|
||||
REQUIRED_NOVA_API_VERSION = '2.1'
|
||||
@ -106,8 +129,8 @@ def cinder(context):
|
||||
|
||||
|
||||
def keystone(context):
|
||||
auth_url = context.session.get_endpoint(service_type='identity')
|
||||
return keystoneclient.Client(auth_url=auth_url,
|
||||
url = context.session.get_endpoint(service_type='identity')
|
||||
return keystoneclient.Client(auth_url=url,
|
||||
session=context.session)
|
||||
|
||||
|
||||
@ -202,12 +225,7 @@ class _rpc_RequestContextSerializer(messaging.NoOpSerializer):
|
||||
_admin_session = None
|
||||
|
||||
|
||||
def get_os_admin_session():
|
||||
"""Create a context to interact with OpenStack as an administrator."""
|
||||
# NOTE(ft): this is a singletone because keystone's session looks thread
|
||||
# safe for both regular and token renewal requests
|
||||
global _admin_session
|
||||
if not _admin_session:
|
||||
def get_session_from_deprecated():
|
||||
auth = keystone_auth.Password(
|
||||
username=CONF.admin_user,
|
||||
password=CONF.admin_password,
|
||||
@ -217,12 +235,31 @@ def get_os_admin_session():
|
||||
)
|
||||
params = {'auth': auth}
|
||||
update_request_params_with_ssl(params)
|
||||
_admin_session = keystone_session.Session(**params)
|
||||
return keystone_session.Session(**params)
|
||||
|
||||
|
||||
def get_os_admin_session():
|
||||
"""Create a context to interact with OpenStack as an administrator."""
|
||||
# NOTE(ft): this is a singletone because keystone's session looks thread
|
||||
# safe for both regular and token renewal requests
|
||||
global _admin_session
|
||||
if not _admin_session:
|
||||
if not CONF[GROUP_AUTHTOKEN].auth_type:
|
||||
_admin_session = get_session_from_deprecated()
|
||||
else:
|
||||
auth_plugin = ks_loading.load_auth_from_conf_options(
|
||||
CONF, GROUP_AUTHTOKEN)
|
||||
_admin_session = ks_loading.load_session_from_conf_options(
|
||||
CONF, GROUP_AUTHTOKEN, auth=auth_plugin)
|
||||
|
||||
return _admin_session
|
||||
|
||||
|
||||
def update_request_params_with_ssl(params):
|
||||
if not CONF[GROUP_AUTHTOKEN].auth_type:
|
||||
verify = CONF.ssl_ca_file or not CONF.ssl_insecure
|
||||
else:
|
||||
verify = (CONF[GROUP_AUTHTOKEN].cafile or
|
||||
not CONF[GROUP_AUTHTOKEN].insecure)
|
||||
if verify is not True:
|
||||
params['verify'] = verify
|
||||
|
@ -11,6 +11,10 @@
|
||||
# limitations under the License.
|
||||
|
||||
import itertools
|
||||
import operator
|
||||
|
||||
from keystoneauth1 import loading as ks_loading
|
||||
from oslo_config import cfg
|
||||
|
||||
import ec2api.clients
|
||||
import ec2api.db.api
|
||||
@ -21,6 +25,9 @@ import ec2api.utils
|
||||
import ec2api.wsgi
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def list_opts():
|
||||
return [
|
||||
('DEFAULT',
|
||||
@ -34,3 +41,20 @@ def list_opts():
|
||||
ec2api.wsgi.wsgi_opts,
|
||||
)),
|
||||
]
|
||||
|
||||
|
||||
GROUP_AUTHTOKEN = 'keystone_authtoken'
|
||||
|
||||
|
||||
def list_auth_opts():
|
||||
opt_list = ks_loading.register_session_conf_options(CONF, GROUP_AUTHTOKEN)
|
||||
opt_list.insert(0, ks_loading.get_auth_common_conf_options()[0])
|
||||
# NOTE(mhickey): There are a lot of auth plugins, we just generate
|
||||
# the config options for a few common ones
|
||||
plugins = ['password', 'v2password', 'v3password']
|
||||
for name in plugins:
|
||||
for plugin_option in ks_loading.get_auth_plugin_conf_options(name):
|
||||
if all(option.name != plugin_option.name for option in opt_list):
|
||||
opt_list.append(plugin_option)
|
||||
opt_list.sort(key=operator.attrgetter('name'))
|
||||
return [(GROUP_AUTHTOKEN, opt_list)]
|
||||
|
@ -20,22 +20,59 @@ from oslo_config import fixture as config_fixture
|
||||
from oslo_context import context
|
||||
from oslotest import base as test_base
|
||||
|
||||
from ec2api import clients
|
||||
from ec2api import context as ec2_context
|
||||
|
||||
|
||||
cfg.CONF.import_opt('keystone_url', 'ec2api.api')
|
||||
GROUP_AUTHTOKEN = 'keystone_authtoken'
|
||||
|
||||
|
||||
class ContextTestCase(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ContextTestCase, self).setUp()
|
||||
@mock.patch('keystoneauth1.loading.load_auth_from_conf_options')
|
||||
@mock.patch('keystoneauth1.loading.load_session_from_conf_options')
|
||||
def test_get_os_admin_context(self, session, auth):
|
||||
conf = config_fixture.Config()
|
||||
clients._admin_session = None
|
||||
conf.config(auth_type='fake', group=GROUP_AUTHTOKEN)
|
||||
|
||||
imp.reload(ec2_context)
|
||||
# NOTE(ft): initialize a regular context to populate oslo_context's
|
||||
# local storage to prevent admin context to populate it.
|
||||
# Used to implicitly validate overwrite=False argument of the call
|
||||
# RequestContext constructor from inside get_os_admin_context
|
||||
if not context.get_current():
|
||||
ec2_context.RequestContext(None, None)
|
||||
|
||||
ctx = ec2_context.get_os_admin_context()
|
||||
conf = cfg.CONF
|
||||
auth.assert_called_once_with(conf, GROUP_AUTHTOKEN)
|
||||
auth_plugin = auth.return_value
|
||||
session.assert_called_once_with(conf, GROUP_AUTHTOKEN,
|
||||
auth=auth_plugin)
|
||||
self.assertIsNone(ctx.user_id)
|
||||
self.assertIsNone(ctx.project_id)
|
||||
self.assertIsNone(ctx.auth_token)
|
||||
self.assertEqual([], ctx.service_catalog)
|
||||
self.assertTrue(ctx.is_os_admin)
|
||||
self.assertIsNotNone(ctx.session)
|
||||
self.assertIsNotNone(ctx.session.auth)
|
||||
self.assertNotEqual(context.get_current(), ctx)
|
||||
|
||||
session.reset_mock()
|
||||
ec2_context.get_os_admin_context()
|
||||
self.assertFalse(session.called)
|
||||
|
||||
@mock.patch('keystoneclient.auth.identity.generic.password.Password')
|
||||
def test_get_os_admin_context_deprecated(self, password_plugin):
|
||||
conf = config_fixture.Config()
|
||||
clients._admin_session = None
|
||||
conf.config(auth_type=None, group=GROUP_AUTHTOKEN)
|
||||
conf.config(admin_user='admin',
|
||||
admin_password='password',
|
||||
admin_tenant_name='service')
|
||||
|
||||
@mock.patch('keystoneclient.auth.identity.generic.password.Password')
|
||||
def test_get_os_admin_context(self, password_plugin):
|
||||
imp.reload(ec2_context)
|
||||
# NOTE(ft): initialize a regular context to populate oslo_context's
|
||||
# local storage to prevent admin context to populate it.
|
||||
|
@ -2,6 +2,7 @@
|
||||
output_file = etc/ec2api/ec2api.conf.sample
|
||||
wrap_width = 79
|
||||
namespace = ec2api
|
||||
namespace = keystoneauth1
|
||||
namespace = ec2api.api
|
||||
namespace = ec2api.metadata
|
||||
namespace = ec2api.s3
|
||||
|
17
install.sh
17
install.sh
@ -4,6 +4,8 @@
|
||||
SERVICE_USERNAME=ec2api
|
||||
SERVICE_PASSWORD=ec2api
|
||||
SERVICE_TENANT=service
|
||||
# this domain name will be used for project and user
|
||||
SERVICE_DOMAIN_NAME=Default
|
||||
EC2API_PORT=8788
|
||||
CONNECTION="mysql://ec2api:ec2api@127.0.0.1/ec2api?charset=utf8"
|
||||
LOG_DIR=/var/log/ec2api
|
||||
@ -267,15 +269,22 @@ iniset $CONF_FILE DEFAULT api_paste_config $APIPASTE_FILE
|
||||
iniset $CONF_FILE DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
|
||||
iniset $CONF_FILE DEFAULT log_dir "$LOG_DIR"
|
||||
iniset $CONF_FILE DEFAULT verbose True
|
||||
iniset $CONF_FILE DEFAULT keystone_url "$OS_AUTH_URL"
|
||||
iniset $CONF_FILE DEFAULT keystone_ec2_tokens_url "$OS_AUTH_URL/v3/ec2tokens"
|
||||
iniset $CONF_FILE database connection "$CONNECTION"
|
||||
iniset $CONF_FILE DEFAULT full_vpc_support "$VPC_SUPPORT"
|
||||
iniset $CONF_FILE DEFAULT external_network "$EXTERNAL_NETWORK"
|
||||
|
||||
iniset $CONF_FILE DEFAULT admin_user $SERVICE_USERNAME
|
||||
iniset $CONF_FILE DEFAULT admin_password $SERVICE_PASSWORD
|
||||
iniset $CONF_FILE DEFAULT admin_tenant_name $SERVICE_TENANT
|
||||
GROUP_AUTHTOKEN="keystone_authtoken"
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN signing_dir "$AUTH_CACHE_DIR"
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN auth_uri "$OS_AUTH_URL"
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN auth_url "$OS_AUTH_URL"
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN username $SERVICE_USERNAME
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN password $SERVICE_PASSWORD
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN project_name $SERVICE_TENANT
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN project_domain_name $SERVICE_DOMAIN_NAME
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN user_domain_name $SERVICE_DOMAIN_NAME
|
||||
iniset $CONF_FILE $GROUP_AUTHTOKEN auth_type password
|
||||
|
||||
|
||||
if [[ -f "$NOVA_CONF" ]]; then
|
||||
# NOTE(ft): use swift instead internal s3 server if enabled
|
||||
|
@ -20,6 +20,7 @@ oslo.utils>=3.16.0 # Apache-2.0
|
||||
Paste # MIT
|
||||
PasteDeploy>=1.5.0 # MIT
|
||||
pbr>=1.6 # Apache-2.0
|
||||
keystoneauth1>=2.10.0 # Apache-2.0
|
||||
python-cinderclient!=1.7.0,!=1.7.1,>=1.6.0 # Apache-2.0
|
||||
python-glanceclient!=2.4.0,>=2.3.0 # Apache-2.0
|
||||
python-keystoneclient!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
|
Loading…
Reference in New Issue
Block a user