Merge "Sysinv healthy query API request failed"
This commit is contained in:
@@ -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
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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):
|
||||||
|
@@ -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())
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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,
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user