Merge "Sysinv healthy query API request failed"

This commit is contained in:
Zuul
2018-09-13 19:53:09 +00:00
committed by Gerrit Code Review
8 changed files with 104 additions and 16 deletions

View File

@@ -2,6 +2,7 @@ class platform::sysinv::params (
$api_port = 6385, $api_port = 6385,
$region_name = undef, $region_name = undef,
$service_create = false, $service_create = false,
$fm_catalog_info = 'faultmanagement:fm:internalURL',
) { } ) { }
class platform::sysinv class platform::sysinv
@@ -45,6 +46,7 @@ class platform::sysinv
rabbit_port => $::platform::amqp::params::port, rabbit_port => $::platform::amqp::params::port,
rabbit_userid => $::platform::amqp::params::auth_user, rabbit_userid => $::platform::amqp::params::auth_user,
rabbit_password => $::platform::amqp::params::auth_password, rabbit_password => $::platform::amqp::params::auth_password,
fm_catalog_info => $fm_catalog_info,
} }
# Note: The log format strings are prefixed with "sysinv" because it is # Note: The log format strings are prefixed with "sysinv" because it is

View File

@@ -1,7 +1,7 @@
# #
# Files in this package are licensed under Apache; see LICENSE file. # Files in this package are licensed under Apache; see LICENSE file.
# #
# Copyright (c) 2013-2016 Wind River Systems, Inc. # Copyright (c) 2013-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@@ -69,7 +69,8 @@ class sysinv (
$neutron_region_name = 'RegionOne', $neutron_region_name = 'RegionOne',
$cinder_region_name = 'RegionOne', $cinder_region_name = 'RegionOne',
$nova_region_name = 'RegionOne', $nova_region_name = 'RegionOne',
$magnum_region_name = 'RegionOne' $magnum_region_name = 'RegionOne',
$fm_catalog_info = undef,
) { ) {
include sysinv::params include sysinv::params
@@ -200,6 +201,11 @@ class sysinv (
'keystone_authtoken/magnum_region_name': value => $magnum_region_name; 'keystone_authtoken/magnum_region_name': value => $magnum_region_name;
} }
sysinv_config {
'fm/catalog_info': value => $fm_catalog_info;
'fm/os_region_name': value => $region_name;
}
sysinv_api_paste_ini { sysinv_api_paste_ini {
'filter:authtoken/region_name': value => $region_name; 'filter:authtoken/region_name': value => $region_name;
} }

View File

@@ -16,13 +16,15 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2014 Wind River Systems, Inc. # Copyright (c) 2013-2018 Wind River Systems, Inc.
# #
import time import time
import urlparse import urlparse
import webob
from oslo_config import cfg from oslo_config import cfg
from oslo_serialization import jsonutils
from pecan import hooks from pecan import hooks
from sysinv.common import context from sysinv.common import context
@@ -33,6 +35,7 @@ from sysinv.openstack.common import policy
from webob import exc from webob import exc
from sysinv.openstack.common import log from sysinv.openstack.common import log
from sysinv.openstack.common.gettextutils import _
import eventlet.semaphore import eventlet.semaphore
import re import re
@@ -78,6 +81,9 @@ class ContextHook(hooks.PecanHook):
The flag is set to True, if X-Roles contains either an administrator The flag is set to True, if X-Roles contains either an administrator
or admin substring. Otherwise it is set to False. or admin substring. Otherwise it is set to False.
X-Service_Catalog:
Used for context.service_catalog.
""" """
def __init__(self, public_api_routes): def __init__(self, public_api_routes):
self.public_api_routes = public_api_routes self.public_api_routes = public_api_routes
@@ -92,6 +98,14 @@ class ContextHook(hooks.PecanHook):
domain_name = state.request.headers.get('X-User-Domain-Name') domain_name = state.request.headers.get('X-User-Domain-Name')
auth_token = state.request.headers.get('X-Auth-Token', None) auth_token = state.request.headers.get('X-Auth-Token', None)
creds = {'roles': state.request.headers.get('X-Roles', '').split(',')} creds = {'roles': state.request.headers.get('X-Roles', '').split(',')}
catalog_header = state.request.headers.get('X-Service-Catalog')
service_catalog = None
if catalog_header:
try:
service_catalog = jsonutils.loads(catalog_header)
except ValueError:
raise webob.exc.HTTPInternalServerError(
_('Invalid service catalog json.'))
is_admin = policy.check('admin', state.request.headers, creds) is_admin = policy.check('admin', state.request.headers, creds)
@@ -105,7 +119,9 @@ class ContextHook(hooks.PecanHook):
domain_id=domain_id, domain_id=domain_id,
domain_name=domain_name, domain_name=domain_name,
is_admin=is_admin, is_admin=is_admin,
is_public_api=is_public_api) is_public_api=is_public_api,
service_catalog=service_catalog
)
class RPCHook(hooks.PecanHook): class RPCHook(hooks.PecanHook):

View File

@@ -16,18 +16,23 @@ from sysinv.db import api as dbapi
from sysinv.openstack.common import context from sysinv.openstack.common import context
REQUIRED_SERVICE_TYPES = ('faultmanagement',)
class RequestContext(context.RequestContext): class RequestContext(context.RequestContext):
"""Extends security contexts from the OpenStack common library.""" """Extends security contexts from the OpenStack common library."""
def __init__(self, auth_token=None, domain_id=None, domain_name=None, def __init__(self, auth_token=None, domain_id=None, domain_name=None,
user=None, tenant=None, is_admin=False, is_public_api=False, user=None, tenant=None, is_admin=False, is_public_api=False,
read_only=False, show_deleted=False, request_id=None): read_only=False, show_deleted=False, request_id=None,
service_catalog=None):
"""Stores several additional request parameters: """Stores several additional request parameters:
:param domain_id: The ID of the domain. :param domain_id: The ID of the domain.
:param domain_name: The name of the domain. :param domain_name: The name of the domain.
:param is_public_api: Specifies whether the request should be processed :param is_public_api: Specifies whether the request should be processed
without authentication. without authentication.
:param service_catalog: Specifies the service_catalog
""" """
self.is_public_api = is_public_api self.is_public_api = is_public_api
self.domain_id = domain_id self.domain_id = domain_id
@@ -40,6 +45,13 @@ class RequestContext(context.RequestContext):
read_only=read_only, read_only=read_only,
show_deleted=show_deleted, show_deleted=show_deleted,
request_id=request_id) request_id=request_id)
if service_catalog:
# Only include required parts of service_catalog
self.service_catalog = [s for s in service_catalog
if s.get('type') in REQUIRED_SERVICE_TYPES]
else:
# if list is empty or none
self.service_catalog = []
@property @property
def session(self): def session(self):
@@ -51,7 +63,8 @@ class RequestContext(context.RequestContext):
def to_dict(self): def to_dict(self):
result = {'domain_id': self.domain_id, result = {'domain_id': self.domain_id,
'domain_name': self.domain_name, 'domain_name': self.domain_name,
'is_public_api': self.is_public_api} 'is_public_api': self.is_public_api,
'service_catalog': self.service_catalog}
result.update(super(RequestContext, self).to_dict()) result.update(super(RequestContext, self).to_dict())

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2016 Wind River Systems, Inc. # Copyright (c) 2016-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@@ -7,13 +7,36 @@
# FM Fault Management Handling # FM Fault Management Handling
from keystoneauth1.access import service_catalog as k_service_catalog
from oslo_config import cfg
from fm_api import constants as fm_constants from fm_api import constants as fm_constants
from fm_api import fm_api from fm_api import fm_api
import fmclient as fm_client
from sysinv.openstack.common import log from sysinv.openstack.common import log
CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
fm_group = cfg.OptGroup(
'fm',
title='FM Options',
help="Configuration options for the fault management service")
fm_opts = [
cfg.StrOpt('catalog_info',
default='faultmanagement:fm:internalURL',
help="Service catalog Look up info."),
cfg.StrOpt('os_region_name',
default='RegionOne',
help="Region name of this node. It is used for catalog lookup")
]
CONF.register_group(fm_group)
CONF.register_opts(fm_opts, group=fm_group)
class FmCustomerLog(object): class FmCustomerLog(object):
""" """
Fault Management Customer Log Fault Management Customer Log
@@ -55,3 +78,27 @@ class FmCustomerLog(object):
LOG.info("Generated customer log, fm_uuid=%s." % fm_uuid) LOG.info("Generated customer log, fm_uuid=%s." % fm_uuid)
else: else:
LOG.error("Unknown event id (%s) given." % fm_event_id) LOG.error("Unknown event id (%s) given." % fm_event_id)
def fmclient(context, version=1, endpoint=None):
"""Constructs a fm client object for making API requests.
:param context: The request context for auth.
:param version: API endpoint version.
:param endpoint: Optional If the endpoint is not available, it will be
retrieved from context
"""
auth_token = context.auth_token
if endpoint is None:
sc = k_service_catalog.ServiceCatalogV2(context.service_catalog)
service_type, service_name, interface = \
CONF.fm.catalog_info.split(':')
service_parameters = {'service_type': service_type,
'service_name': service_name,
'interface': interface,
'region_name': CONF.fm.os_region_name}
endpoint = sc.url_for(**service_parameters)
return fm_client.Client(version=version,
endpoint=endpoint,
auth_token=auth_token)

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2016 Wind River Systems, Inc. # Copyright (c) 2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@@ -13,6 +13,7 @@ from fm_api import fm_api
from sysinv.common import ceph from sysinv.common import ceph
from sysinv.common import constants from sysinv.common import constants
from sysinv.common import utils from sysinv.common import utils
from sysinv.common.fm import fmclient
from sysinv.common.storage_backend_conf import StorageBackendConfig from sysinv.common.storage_backend_conf import StorageBackendConfig
from sysinv.api.controllers.v1 import patch_api from sysinv.api.controllers.v1 import patch_api
from sysinv.api.controllers.v1 import vim_api from sysinv.api.controllers.v1 import vim_api
@@ -95,9 +96,9 @@ class Health(object):
success = not not_patch_current_hosts and not hostnames success = not not_patch_current_hosts and not hostnames
return success, not_patch_current_hosts, hostnames return success, not_patch_current_hosts, hostnames
def _check_alarms(self, force=False): def _check_alarms(self, context, force=False):
"""Checks that no alarms are active""" """Checks that no alarms are active"""
db_alarms = self._dbapi.ialarm_get_all(include_suppress=True) db_alarms = fmclient(context).alarm.list(include_suppress=True)
success = True success = True
allowed = 0 allowed = 0
@@ -210,7 +211,7 @@ class Health(object):
return True return True
def get_system_health(self, force=False): def get_system_health(self, context, force=False):
"""Returns the general health of the system""" """Returns the general health of the system"""
# Checks the following: # Checks the following:
# All hosts are provisioned # All hosts are provisioned
@@ -277,7 +278,7 @@ class Health(object):
health_ok = health_ok and success health_ok = health_ok and success
success, allowed, affecting = self._check_alarms(force) success, allowed, affecting = self._check_alarms(context, force)
output += _('No alarms: [%s]\n') \ output += _('No alarms: [%s]\n') \
% (Health.SUCCESS_MSG if success else Health.FAIL_MSG) % (Health.SUCCESS_MSG if success else Health.FAIL_MSG)
if not success: if not success:
@@ -288,7 +289,7 @@ class Health(object):
return health_ok, output return health_ok, output
def get_system_health_upgrade(self, force=False): def get_system_health_upgrade(self, context, force=False):
"""Ensures the system is in a valid state for an upgrade""" """Ensures the system is in a valid state for an upgrade"""
# Does a general health check then does the following: # Does a general health check then does the following:
# A load is imported # A load is imported
@@ -298,7 +299,7 @@ class Health(object):
system_mode = self._dbapi.isystem_get_one().system_mode system_mode = self._dbapi.isystem_get_one().system_mode
simplex = (system_mode == constants.SYSTEM_MODE_SIMPLEX) simplex = (system_mode == constants.SYSTEM_MODE_SIMPLEX)
health_ok, output = self.get_system_health(force) health_ok, output = self.get_system_health(context, force)
loads = self._dbapi.load_get_list() loads = self._dbapi.load_get_list()
try: try:
imported_load = utils.get_imported_load(loads) imported_load = utils.get_imported_load(loads)

View File

@@ -8948,9 +8948,11 @@ class ConductorManager(service.PeriodicService):
health_util = health.Health(self.dbapi) health_util = health.Health(self.dbapi)
if upgrade is True: if upgrade is True:
return health_util.get_system_health_upgrade(force=force) return health_util.get_system_health_upgrade(context=context,
force=force)
else: else:
return health_util.get_system_health(force=force) return health_util.get_system_health(context=context,
force=force)
def _get_cinder_address_name(self, network_type): def _get_cinder_address_name(self, network_type):
ADDRESS_FORMAT_ARGS = (constants.CONTROLLER_HOSTNAME, ADDRESS_FORMAT_ARGS = (constants.CONTROLLER_HOSTNAME,

View File

@@ -41,6 +41,7 @@ deps = -r{toxinidir}/requirements.txt
-e{[tox]cgcsdir}/stx-update/tsconfig/tsconfig -e{[tox]cgcsdir}/stx-update/tsconfig/tsconfig
-e{[tox]cgcsdir}/stx-config/configutilities/configutilities -e{[tox]cgcsdir}/stx-config/configutilities/configutilities
-e{[tox]cgcsdir}/stx-fault/fm-api -e{[tox]cgcsdir}/stx-fault/fm-api
-e{[tox]cgcsdir}/stx-fault/python-fmclient/fmclient
-e{[tox]cgcsdir}/stx-config/controllerconfig/controllerconfig -e{[tox]cgcsdir}/stx-config/controllerconfig/controllerconfig
-e{[tox]cgcsdir}/stx-update/cgcs-patch/cgcs-patch -e{[tox]cgcsdir}/stx-update/cgcs-patch/cgcs-patch
-e{[tox]cgcsdir}/stx-integ/utilities/platform-util/platform-util -e{[tox]cgcsdir}/stx-integ/utilities/platform-util/platform-util