Fix the hardcoding of user role using sdk_adapter approach

1. Refer to nova's latest code, use get_sdk to create the client[1].

2. Move placement_client define from default to seperate placement file.

Note:
The new method for get nova and placement client has been tested in latest
cyborg devstack environment. And the test results are good.

Because now cyborg does not have unit tests for the common and conf directory,
unit tests related to this patch will be added in the future, but not in this patch.

Reference:
[1]. 3f019f2db3/nova/utils.py (L1013)

Change-Id: I2a335d47ee3cc24f78b4d49942f1cccd586a0dcc
This commit is contained in:
chenke 2019-09-17 15:42:12 +08:00
parent a7f1df1596
commit 71df0a289d
9 changed files with 153 additions and 69 deletions

View File

@ -196,6 +196,10 @@ class NotFound(CyborgException):
code = http_client.NOT_FOUND
class ServiceUnavailable(Invalid):
msg_fmt = _("Service is unavailable at this time.")
class ServiceNotFound(NotFound):
msg_fmt = _("Service %(service_id)s could not be found.")

View File

@ -12,8 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from cyborg.conf import CONF
from openstack import connection
from cyborg.common import utils
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
@ -21,13 +20,7 @@ LOG = logging.getLogger(__name__)
class NovaAPI(object):
def __init__(self):
default_user = "devstack-admin"
try:
auth_user = CONF.compute.username
except Exception:
auth_user = default_user
self.conn = connection.Connection(cloud=auth_user)
self.nova_client = self.conn.compute
self.nova_client = utils.get_sdk_adapter('compute')
def _get_acc_changed_event(self, instance_uuid, dev_profile_name, status):
return [{'name': 'accelerator-requests-bound',

View File

@ -14,33 +14,22 @@
# under the License.
from cyborg.common import exception
from cyborg.conf import CONF
from cyborg.common import utils
from keystoneauth1 import exceptions as ks_exc
from oslo_log import log as logging
from oslo_middleware import request_id
from openstack import connection
LOG = logging.getLogger(__name__)
NESTED_PROVIDER_API_VERSION = '1.14'
POST_RPS_RETURNS_PAYLOAD_API_VERSION = '1.20'
PLACEMENT_CLIENT_SEMAPHORE = 'placement_client'
_CONN = None
class PlacementClient(object):
"""Client class for reporting to placement."""
def __init__(self):
global _CONN
if _CONN is None:
default_user = 'devstack-admin'
try:
auth_user = CONF.placement.username or default_user
except Exception:
auth_user = default_user
_CONN = connection.Connection(cloud=auth_user)
self._client = _CONN.placement
self._client = utils.get_sdk_adapter('placement')
def get(self, url, version=None, global_request_id=None):
return self._client.get(url, microversion=version,

View File

@ -19,17 +19,19 @@ import six
from keystoneauth1 import exceptions as ks_exc
from keystoneauth1 import loading as ks_loading
from openstack import connection
from openstack import exceptions as sdk_exc
from os_service_types import service_types
from oslo_concurrency import lockutils
from oslo_log import log
from cyborg.common import exception
from cyborg.common.i18n import _
import cyborg.conf
LOG = log.getLogger(__name__)
synchronized = lockutils.synchronized_with_prefix('cyborg-')
_SERVICE_TYPES = service_types.ServiceTypes()
CONF = cyborg.conf.CONF
@ -111,6 +113,47 @@ def get_ksa_adapter(service_type, ksa_auth=None, ksa_session=None,
min_version=min_version, max_version=max_version)
def _get_conf_group(service_type):
# Get the conf group corresponding to the service type.
confgrp = _SERVICE_TYPES.get_project_name(service_type)
if not confgrp or not hasattr(CONF, confgrp):
raise exception.ConfGroupForServiceTypeNotFound(stype=service_type)
return confgrp
def _get_auth_and_session(confgrp):
ksa_auth = ks_loading.load_auth_from_conf_options(CONF, confgrp)
return ks_loading.load_session_from_conf_options(
CONF, confgrp, auth=ksa_auth)
def get_sdk_adapter(service_type, check_service=False):
"""Construct an openstacksdk-brokered Adapter for a given service type.
We expect to find a conf group whose name corresponds to the service_type's
project according to the service-types-authority. That conf group must
provide ksa auth, session, and adapter options.
:param service_type: String name of the service type for which the Adapter
is to be constructed.
:param check_service: If True, we will query the endpoint to make sure the
service is alive, raising ServiceUnavailable if it is not.
:return: An openstack.proxy.Proxy object for the specified service_type.
:raise: ConfGroupForServiceTypeNotFound If no conf group name could be
found for the specified service_type.
:raise: ServiceUnavailable if check_service is True and the service is down
"""
confgrp = _get_conf_group(service_type)
sess = _get_auth_and_session(confgrp)
try:
conn = connection.Connection(
session=sess, oslo_conf=CONF, service_types={service_type},
strict_proxies=check_service)
except sdk_exc.ServiceDiscoveryException as e:
raise exception.ServiceUnavailable(
_("The %(service_type)s service is unavailable: %(error)s") %
{'service_type': service_type, 'error': six.text_type(e)})
return getattr(conn, service_type)
def get_endpoint(ksa_adapter):
"""Get the endpoint URL represented by a keystoneauth1 Adapter.

View File

@ -21,6 +21,8 @@ from cyborg.conf import database
from cyborg.conf import default
from cyborg.conf import glance
from cyborg.conf import keystone
from cyborg.conf import nova
from cyborg.conf import placement
from cyborg.conf import service_token
CONF = cfg.CONF
@ -29,7 +31,8 @@ api.register_opts(CONF)
agent.register_opts(CONF)
database.register_opts(CONF)
default.register_opts(CONF)
default.register_placement_opts(CONF)
service_token.register_opts(CONF)
glance.register_opts(CONF)
keystone.register_opts(CONF)
nova.register_opts(CONF)
placement.register_opts(CONF)

View File

@ -18,11 +18,9 @@
import os
import socket
from keystoneauth1 import loading as k_loading
from oslo_config import cfg
from cyborg.common.i18n import _
from cyborg.conf import utils as confutils
exc_log_opts = [
@ -65,33 +63,6 @@ path_opts = [
help=_("Top-level directory for maintaining cyborg's state.")),
]
PLACEMENT_CONF_SECTION = 'placement'
DEFAULT_SERVICE_TYPE = 'placement'
placement_group = cfg.OptGroup(
PLACEMENT_CONF_SECTION,
title='Placement Service Options',
help="Configuration options for connecting to the placement API service")
placement_opts = [
cfg.StrOpt('endpoint_type',
default='public',
choices=['public', 'admin', 'internal'],
help=_('Type of the placement endpoint to use. This endpoint '
'will be looked up in the keystone catalog and should '
'be one of public, internal or admin.')),
cfg.BoolOpt(
'randomize_allocation_candidates',
default=False,
help=_('If True, when limiting allocation candidate results, the '
'results will be a random sampling of the full result set. '
'If False, allocation candidates are returned in a '
'deterministic but undefined order. That is, all things '
'being equal, two requests for allocation candidates will '
'return the same results in the same order; but no guarantees '
'are made as to how that order is determined.')),
]
def register_opts(conf):
conf.register_opts(exc_log_opts)
@ -99,24 +70,10 @@ def register_opts(conf):
conf.register_opts(path_opts)
def register_placement_opts(cfg=cfg.CONF):
cfg.register_group(placement_group)
cfg.register_opts(placement_opts, group=PLACEMENT_CONF_SECTION)
confutils.register_ksa_opts(cfg, placement_group, DEFAULT_SERVICE_TYPE)
DEFAULT_OPTS = (exc_log_opts + service_opts + path_opts)
def list_opts():
return {
PLACEMENT_CONF_SECTION: (
placement_opts +
k_loading.get_session_conf_options() +
k_loading.get_auth_common_conf_options() +
k_loading.get_auth_plugin_conf_options('password') +
k_loading.get_auth_plugin_conf_options('v2password') +
k_loading.get_auth_plugin_conf_options('v3password') +
confutils.get_ksa_adapter_opts(DEFAULT_SERVICE_TYPE)),
'DEFAULT': DEFAULT_OPTS
}

42
cyborg/conf/nova.py Normal file
View File

@ -0,0 +1,42 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from keystoneauth1 import loading as ks_loading
from oslo_config import cfg
from cyborg.conf import utils as confutils
DEFAULT_SERVICE_TYPE = 'compute'
nova_group = cfg.OptGroup(
'nova',
title='Nova Service Options',
help="Configuration options for connecting to the Nova API service")
def register_opts(conf):
conf.register_group(nova_group)
confutils.register_ksa_opts(conf, nova_group, DEFAULT_SERVICE_TYPE)
def list_opts():
return {
nova_group.name: (
ks_loading.get_session_conf_options() +
ks_loading.get_auth_common_conf_options() +
ks_loading.get_auth_plugin_conf_options('password') +
ks_loading.get_auth_plugin_conf_options('v2password') +
ks_loading.get_auth_plugin_conf_options('v3password') +
confutils.get_ksa_adapter_opts(DEFAULT_SERVICE_TYPE))
}

42
cyborg/conf/placement.py Normal file
View File

@ -0,0 +1,42 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from keystoneauth1 import loading as ks_loading
from oslo_config import cfg
from cyborg.conf import utils as confutils
PLACEMENT_CONF_SECTION = 'placement'
DEFAULT_SERVICE_TYPE = 'placement'
placement_group = cfg.OptGroup(
PLACEMENT_CONF_SECTION,
title='Placement Service Options',
help="Configuration options for connecting to the placement API service")
def register_opts(conf):
conf.register_group(placement_group)
confutils.register_ksa_opts(conf, placement_group, DEFAULT_SERVICE_TYPE)
def list_opts():
return {
PLACEMENT_CONF_SECTION: (
ks_loading.get_session_conf_options() +
ks_loading.get_auth_common_conf_options() +
ks_loading.get_auth_plugin_conf_options('password') +
ks_loading.get_auth_plugin_conf_options('v2password') +
ks_loading.get_auth_plugin_conf_options('v3password') +
confutils.get_ksa_adapter_opts(DEFAULT_SERVICE_TYPE))
}

View File

@ -199,7 +199,6 @@ function configure_cyborg_placement {
# Use the provided config file path or default to $CYBORG_CONF.
local section=${1:-placement}
local auth_section=${2:-keystone_authtoken}
iniset $CYBORG_CONF_FILE $section auth_section $auth_section
iniset $CYBORG_CONF_FILE $section auth_type "password"
iniset $CYBORG_CONF_FILE $section auth_url "$KEYSTONE_SERVICE_URI"
iniset $CYBORG_CONF_FILE $section username $section
@ -218,7 +217,6 @@ function configure_cyborg_placement {
function configure_cyborg_glance {
local section=${1:-glance}
local auth_section=${2:-keystone_authtoken}
iniset $CYBORG_CONF_FILE $section auth_section $auth_section
iniset $CYBORG_CONF_FILE $section auth_type "password"
iniset $CYBORG_CONF_FILE $section auth_url "$KEYSTONE_SERVICE_URI"
iniset $CYBORG_CONF_FILE $section username $section
@ -229,6 +227,18 @@ function configure_cyborg_glance {
iniset $CYBORG_CONF_FILE $section api_servers "$GLANCE_URL"
}
function configure_cyborg_nova {
local section=${1:-nova}
local auth_section=${2:-keystone_authtoken}
iniset $CYBORG_CONF_FILE $section auth_type "password"
iniset $CYBORG_CONF_FILE $section auth_url "$KEYSTONE_SERVICE_URI"
iniset $CYBORG_CONF_FILE $section username $section
iniset $CYBORG_CONF_FILE $section password "$SERVICE_PASSWORD"
iniset $CYBORG_CONF_FILE $section user_domain_name "$SERVICE_DOMAIN_NAME"
iniset $CYBORG_CONF_FILE $section project_name "$SERVICE_TENANT_NAME"
iniset $CYBORG_CONF_FILE $section project_domain_name "$SERVICE_DOMAIN_NAME"
}
# configure_cyborg_conductor() - Is used by configure_cyborg().
# Sets conductor specific settings.
function configure_cyborg_conductor {
@ -240,6 +250,7 @@ function configure_cyborg_conductor {
configure_auth_for service_catalog
configure_cyborg_placement
configure_cyborg_glance
configure_cyborg_nova
sudo cp $CYBORG_DIR/etc/cyborg/rootwrap.conf $CYBORG_ROOTWRAP_CONF
sudo cp -r $CYBORG_DIR/etc/cyborg/rootwrap.d $CYBORG_CONF_DIR