Decouple Fault Management from stx-config

Update NFV to use FM rest API service:
Add a NFVI open stack plugin for FM
Update the NFV infrastructure and web server to use FM plugin
Update sysinv plugin and remove get alarms and logs calls

Story: 2002828
Task: 22747

Depends-On: https://review.openstack.org/#/c/591452/

Change-Id: I60ff74ccfb2ec2eaad427a23fe4d58d4fc49ab79
Signed-off-by: Tao Liu <tao.liu@windriver.com>
This commit is contained in:
Tao Liu 2018-08-16 11:45:01 -04:00
parent 483a94531f
commit 935aa906ba
10 changed files with 115 additions and 92 deletions

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015-2016 Wind River Systems, Inc. # Copyright (c) 2015-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -71,6 +71,12 @@ service_name=patching
service_type=patching service_type=patching
endpoint_type=admin endpoint_type=admin
[fm]
region_name=RegionOne
service_name=fm
service_type=faultmanagement
endpoint_type=admin
[amqp] [amqp]
host=192.168.204.2 host=192.168.204.2
port=5672 port=5672

View File

@ -16,6 +16,7 @@ from openstack import rest_api
from openstack import exceptions from openstack import exceptions
from openstack import openstack from openstack import openstack
from openstack import sysinv from openstack import sysinv
from openstack import fm
from openstack import mtc from openstack import mtc
from openstack import nova from openstack import nova
from openstack import neutron from openstack import neutron
@ -2412,7 +2413,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
self._token = future.result.data self._token = future.result.data
future.work(sysinv.get_alarms, self._token) future.work(fm.get_alarms, self._token)
future.result = (yield) future.result = (yield)
if not future.result.is_complete(): if not future.result.is_complete():
@ -2420,7 +2421,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
alarms = list() alarms = list()
for alarm_data in future.result.data['ialarms']: for alarm_data in future.result.data['alarms']:
alarm = nfvi.objects.v1.Alarm( alarm = nfvi.objects.v1.Alarm(
alarm_data['uuid'], alarm_data['alarm_id'], alarm_data['uuid'], alarm_data['alarm_id'],
alarm_data['entity_instance_id'], alarm_data['severity'], alarm_data['entity_instance_id'], alarm_data['severity'],
@ -2470,7 +2471,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
self._token = future.result.data self._token = future.result.data
future.work(sysinv.get_logs, self._token, start_period, end_period) future.work(fm.get_logs, self._token, start_period, end_period)
future.result = (yield) future.result = (yield)
if not future.result.is_complete(): if not future.result.is_complete():
@ -2517,7 +2518,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
self._token = future.result.data self._token = future.result.data
future.work(sysinv.get_alarm_history, self._token, start_period, future.work(fm.get_alarm_history, self._token, start_period,
end_period) end_period)
future.result = (yield) future.result = (yield)

View File

@ -0,0 +1,84 @@
#
# Copyright (c) 2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from nfv_common import debug
from objects import OPENSTACK_SERVICE
from rest_api import rest_api_request
DLOG = debug.debug_get_logger('nfv_plugins.nfvi_plugins.openstack.fm')
def get_alarms(token):
"""
Asks Fault Management for customer alarms
"""
url = token.get_service_url(OPENSTACK_SERVICE.FM)
if url is None:
raise ValueError("OpenStack FM URL is invalid")
api_cmd = url + "/alarms?include_suppress=True"
response = rest_api_request(token, "GET", api_cmd)
return response
def get_logs(token, start=None, end=None):
"""
Asks Fault Management for customer logs
"""
url = token.get_service_url(OPENSTACK_SERVICE.FM)
if url is None:
raise ValueError("OpenStack SysInv URL is invalid")
api_cmd = url + "/event_log?logs=True"
if start is not None and end is not None:
api_cmd += ("&q.field=start&q.field=end&q.op=eq&q.op=eq"
"&q.value=%s&q.value=%s"
% (str(start).replace(' ', 'T').replace(':', '%3A'),
str(end).replace(' ', 'T').replace(':', '%3A')))
elif start is not None:
api_cmd += ("&q.field=start;q.op=eq;q.value=%s"
% str(start).replace(' ', 'T').replace(':', '%3A'))
elif end is not None:
api_cmd += ("&q.field=end;q.op=eq;q.value=%s"
% str(end).replace(' ', 'T').replace(':', '%3A'))
api_cmd += '&limit=100'
response = rest_api_request(token, "GET", api_cmd)
return response
def get_alarm_history(token, start=None, end=None):
"""
Asks Fault Management for customer alarm history
"""
url = token.get_service_url(OPENSTACK_SERVICE.FM)
if url is None:
raise ValueError("OpenStack SysInv URL is invalid")
api_cmd = url + "/event_log?alarms=True"
if start is not None and end is not None:
api_cmd += ("&q.field=start&q.field=end&q.op=eq&q.op=eq"
"&q.value=%s&q.value=%s"
% (str(start).replace(' ', 'T').replace(':', '%3A'),
str(end).replace(' ', 'T').replace(':', '%3A')))
elif start is not None:
api_cmd += ("&q.field=start;q.op=eq;q.value='%s'"
% str(start).replace(' ', 'T').replace(':', '%3A'))
elif end is not None:
api_cmd += ("&q.field=end;q.op=eq;q.value='%s'"
% str(end).replace(' ', 'T').replace(':', '%3A'))
api_cmd += '&limit=100'
response = rest_api_request(token, "GET", api_cmd)
return response

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015-2016 Wind River Systems, Inc. # Copyright (c) 2015-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -30,6 +30,7 @@ class OpenStackServices(Constants):
SYSINV = Constant('sysinv') SYSINV = Constant('sysinv')
HEAT = Constant('heat') HEAT = Constant('heat')
PATCHING = Constant('patching') PATCHING = Constant('patching')
FM = Constant('fm')
# OpenStack Services Constant # OpenStack Services Constant

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015-2016 Wind River Systems, Inc. # Copyright (c) 2015-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -443,75 +443,3 @@ def swact_from_host(token, host_uuid):
response = rest_api_request(token, "PATCH", api_cmd, api_cmd_headers, response = rest_api_request(token, "PATCH", api_cmd, api_cmd_headers,
json.dumps(api_cmd_payload)) json.dumps(api_cmd_payload))
return response return response
def get_alarms(token):
"""
Asks System Inventory for customer alarms
"""
url = token.get_service_url(OPENSTACK_SERVICE.SYSINV)
if url is None:
raise ValueError("OpenStack SysInv URL is invalid")
api_cmd = url + "/ialarms?include_suppress=True"
response = rest_api_request(token, "GET", api_cmd)
return response
def get_logs(token, start=None, end=None):
"""
Asks System Inventory for customer logs
"""
url = token.get_service_url(OPENSTACK_SERVICE.SYSINV)
if url is None:
raise ValueError("OpenStack SysInv URL is invalid")
api_cmd = url + "/event_log?logs=True"
if start is not None and end is not None:
api_cmd += ("&q.field=start&q.field=end&q.op=eq&q.op=eq"
"&q.value=%s&q.value=%s"
% (str(start).replace(' ', 'T').replace(':', '%3A'),
str(end).replace(' ', 'T').replace(':', '%3A')))
elif start is not None:
api_cmd += ("&q.field=start;q.op=eq;q.value=%s"
% str(start).replace(' ', 'T').replace(':', '%3A'))
elif end is not None:
api_cmd += ("&q.field=end;q.op=eq;q.value=%s"
% str(end).replace(' ', 'T').replace(':', '%3A'))
api_cmd += '&limit=100'
response = rest_api_request(token, "GET", api_cmd)
return response
def get_alarm_history(token, start=None, end=None):
"""
Asks System Inventory for customer alarm history
"""
url = token.get_service_url(OPENSTACK_SERVICE.SYSINV)
if url is None:
raise ValueError("OpenStack SysInv URL is invalid")
api_cmd = url + "/event_log?alarms=True"
if start is not None and end is not None:
api_cmd += ("&q.field=start&q.field=end&q.op=eq&q.op=eq"
"&q.value=%s&q.value=%s"
% (str(start).replace(' ', 'T').replace(':', '%3A'),
str(end).replace(' ', 'T').replace(':', '%3A')))
elif start is not None:
api_cmd += ("&q.field=start;q.op=eq;q.value='%s'"
% str(start).replace(' ', 'T').replace(':', '%3A'))
elif end is not None:
api_cmd += ("&q.field=end;q.op=eq;q.value='%s'"
% str(end).replace(' ', 'T').replace(':', '%3A'))
api_cmd += '&limit=100'
response = rest_api_request(token, "GET", api_cmd)
return response

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015-2016 Wind River Systems, Inc. # Copyright (c) 2015-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -7,7 +7,7 @@ from fm_api import constants as fm_constants
def _instance_alarm_raised(alarms, expected_alarm, instance): def _instance_alarm_raised(alarms, expected_alarm, instance):
for alarm in alarms['ialarms']: for alarm in alarms['alarms']:
if expected_alarm['alarm_id'] == str(alarm['alarm_id']): if expected_alarm['alarm_id'] == str(alarm['alarm_id']):
if expected_alarm['severity'] == str(alarm['severity']): if expected_alarm['severity'] == str(alarm['severity']):
return True return True

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015-2016 Wind River Systems, Inc. # Copyright (c) 2015-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -13,6 +13,7 @@ from nfv_common import debug
from nfv_plugins.nfvi_plugins import config from nfv_plugins.nfvi_plugins import config
from nfv_plugins.nfvi_plugins.openstack import nova from nfv_plugins.nfvi_plugins.openstack import nova
from nfv_plugins.nfvi_plugins.openstack import sysinv from nfv_plugins.nfvi_plugins.openstack import sysinv
from nfv_plugins.nfvi_plugins.openstack import fm
from nfv_plugins.nfvi_plugins.openstack import openstack from nfv_plugins.nfvi_plugins.openstack import openstack
import _hosts import _hosts
@ -175,7 +176,7 @@ class TestHost(_test_base.Test):
""" """
Fetch the customer alarms raised Fetch the customer alarms raised
""" """
self._customer_alarms = sysinv.get_alarms(self.token).result_data self._customer_alarms = fm.get_alarms(self.token).result_data
return return
@ -183,14 +184,14 @@ class TestHost(_test_base.Test):
""" """
Fetch the customer logs Fetch the customer logs
""" """
self._customer_logs = sysinv.get_logs(self.token, self.start_datetime, self._customer_logs = fm.get_logs(self.token, self.start_datetime,
self.end_datetime).result_data self.end_datetime).result_data
def _refresh_customer_alarm_history(self): def _refresh_customer_alarm_history(self):
""" """
Fetch the customer alarm history Fetch the customer alarm history
""" """
self._customer_alarm_history = sysinv.get_alarm_history( self._customer_alarm_history = fm.get_alarm_history(
self.token, self.start_datetime, self.end_datetime).result_data self.token, self.start_datetime, self.end_datetime).result_data

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015-2016 Wind River Systems, Inc. # Copyright (c) 2015-2018 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -13,6 +13,7 @@ from nfv_common import debug
from nfv_plugins.nfvi_plugins import config from nfv_plugins.nfvi_plugins import config
from nfv_plugins.nfvi_plugins.openstack import nova from nfv_plugins.nfvi_plugins.openstack import nova
from nfv_plugins.nfvi_plugins.openstack import sysinv from nfv_plugins.nfvi_plugins.openstack import sysinv
from nfv_plugins.nfvi_plugins.openstack import fm
from nfv_plugins.nfvi_plugins.openstack import openstack from nfv_plugins.nfvi_plugins.openstack import openstack
import _instances import _instances
@ -162,20 +163,20 @@ class TestInstance(_test_base.Test):
""" """
Fetch the customer alarms raised Fetch the customer alarms raised
""" """
self._customer_alarms = sysinv.get_alarms(self.token).result_data self._customer_alarms = fm.get_alarms(self.token).result_data
def _refresh_customer_logs(self): def _refresh_customer_logs(self):
""" """
Fetch the customer logs Fetch the customer logs
""" """
self._customer_logs = sysinv.get_logs(self.token, self.start_datetime, self._customer_logs = fm.get_logs(self.token, self.start_datetime,
self.end_datetime).result_data self.end_datetime).result_data
def _refresh_customer_alarm_history(self): def _refresh_customer_alarm_history(self):
""" """
Fetch the customer alarm history Fetch the customer alarm history
""" """
self._customer_alarm_history = sysinv.get_alarm_history( self._customer_alarm_history = fm.get_alarm_history(
self.token, self.start_datetime, self.end_datetime).result_data self.token, self.start_datetime, self.end_datetime).result_data

View File

@ -29,6 +29,7 @@ class OpenStackServices(Constants):
NOVA = Constant('nova') NOVA = Constant('nova')
SYSINV = Constant('sysinv') SYSINV = Constant('sysinv')
HEAT = Constant('heat') HEAT = Constant('heat')
FM = Constant('fm')
# OpenStack Services Constant # OpenStack Services Constant

View File

@ -15,7 +15,7 @@ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from nfv_common import debug from nfv_common import debug
from nfv_plugins.nfvi_plugins import config from nfv_plugins.nfvi_plugins import config
from nfv_plugins.nfvi_plugins.openstack import openstack from nfv_plugins.nfvi_plugins.openstack import openstack
from nfv_plugins.nfvi_plugins.openstack import sysinv from nfv_plugins.nfvi_plugins.openstack import fm
from nfv_vim import database from nfv_vim import database
DLOG = debug.debug_get_logger('nfv_vim.webserver.webserver') DLOG = debug.debug_get_logger('nfv_vim.webserver.webserver')
@ -226,9 +226,9 @@ class HTTPRequestHandler(BaseHTTPRequestHandler):
_token = openstack.get_token(_directory) _token = openstack.get_token(_directory)
_lock.release() _lock.release()
result = sysinv.get_alarms(_token) result = fm.get_alarms(_token)
if result.result_data: if result.result_data:
for alarm in result.result_data['ialarms']: for alarm in result.result_data['alarms']:
if 'critical' == alarm['severity']: if 'critical' == alarm['severity']:
critical_alarms += 1 critical_alarms += 1
elif 'major' == alarm['severity']: elif 'major' == alarm['severity']: