From: Zhang Rong(Jon) Date: Wed, 16 Nov 2022 06:45:53 +0000 (+0800) Subject: Fix INF-359 and INF-352 about the alarm event record X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=157a0e594ef55da669ed6ca8ff2d62aae409fb9f;p=pti%2Fo2.git Fix INF-359 and INF-352 about the alarm event record Issue-ID: INF-352 Issue-ID: INF-359 Signed-off-by: Zhang Rong(Jon) Change-Id: Ida4cc2b2f1afc93502c0cff4753afd55882b7fd0 --- diff --git a/o2app/entrypoints/resource_watcher.py b/o2app/entrypoints/resource_watcher.py index 2e9e0c0..b557054 100644 --- a/o2app/entrypoints/resource_watcher.py +++ b/o2app/entrypoints/resource_watcher.py @@ -83,6 +83,8 @@ class WatcherService(cotyledon.Service): child_respool = root.addchild( ResourcePoolWatcher(StxResourcePoolClient(), self.bus)) + + # Add Aggregate watch child_respool.addchild( ComputeAggWatcher(ComputeAggClient(), self.bus)) child_respool.addchild( @@ -92,6 +94,7 @@ class WatcherService(cotyledon.Service): child_respool.addchild( UndefinedAggWatcher(UndefinedAggClient(), self.bus)) + # Add Resource watch child_pserver = child_respool.addchild( PServerWatcher(StxPserverClient(), self.bus)) child_pserver.addchild( @@ -109,11 +112,10 @@ class WatcherService(cotyledon.Service): child_pserver.addchild( PServerAccWatcher(StxAccClient(), self.bus)) - self.worker.add_watcher(root) - # Add Alarm watch - root = WatcherTree( + child_respool.addchild( AlarmWatcher(StxAlarmClient(self.bus.uow), self.bus)) + self.worker.add_watcher(root) self.worker.start() diff --git a/o2common/config/config.py b/o2common/config/config.py index d4e7107..54d6d0f 100644 --- a/o2common/config/config.py +++ b/o2common/config/config.py @@ -193,7 +193,8 @@ def get_dc_access_info(): return os_client_args -def get_fm_access_info(): +def get_fm_access_info(subcloud_hostname: str = "", + sub_is_https: bool = False): try: # client_args = dict( # auth_url=os.environ.get('OS_AUTH_URL', _DEFAULT_STX_URL), @@ -210,11 +211,24 @@ def get_fm_access_info(): os_client_args = {} for key, val in client_args.items(): os_client_args['os_{key}'.format(key=key)] = val + auth_url = urlparse(os_client_args.pop('os_auth_url')) + os_client_args['auth_url'] = auth_url.geturl() + + if "" != subcloud_hostname: + orig_auth_url = urlparse(_DEFAULT_STX_URL) + new_auth_url = orig_auth_url._replace( + netloc=orig_auth_url.netloc.replace( + orig_auth_url.hostname, subcloud_hostname)) + if sub_is_https: + new_auth_url = new_auth_url._replace( + scheme=new_auth_url.scheme. + replace(new_auth_url.scheme, 'https')) + os_client_args['auth_url'] = new_auth_url.geturl() + os_client_args['endpoint_type'] = 'publicURL' os_client_args['insecure'] = True - os_client_args['auth_url'] = auth_url.geturl() os_client_args['username'] = os_client_args.pop('os_username') os_client_args['password'] = os_client_args.pop('os_api_key') os_client_args['project_name'] = os_client_args.pop('os_project_name') diff --git a/o2ims/adapter/clients/fault_client.py b/o2ims/adapter/clients/fault_client.py index 45a27ff..78bd7bb 100644 --- a/o2ims/adapter/clients/fault_client.py +++ b/o2ims/adapter/clients/fault_client.py @@ -17,17 +17,16 @@ from typing import List # Optional, Set import uuid as uuid -# from dcmanagerclient.api import client -# from cgtsclient.client import get_client as get_stx_client -# from cgtsclient.exc import EndpointException -# from dcmanagerclient.api.client import client as get_dc_client +from cgtsclient.client import get_client as get_stx_client +from cgtsclient.exc import EndpointException +from dcmanagerclient.api.client import client as get_dc_client from fmclient.client import get_client as get_fm_client from fmclient.common.exceptions import HTTPNotFound -from o2common.service.client.base_client import BaseClient +from o2app.adapter import unit_of_work from o2common.config import config +from o2common.service.client.base_client import BaseClient from o2ims.domain import alarm_obj as alarmModel -from o2app.adapter import unit_of_work from o2common.helper import o2logging logger = o2logging.get_logger(__name__) @@ -47,7 +46,6 @@ class StxAlarmClient(BaseClient): return self.driver.getAlarmInfo(id) def _list(self, **filters) -> List[alarmModel.FaultGenericModel]: - # filters['resourcetypeid'] newmodels = self.driver.getAlarmList(**filters) uow = self.uow exist_alarms = {} @@ -81,13 +79,18 @@ class StxAlarmClient(BaseClient): if exist_alarms[alarm]: # exist alarm is active continue - event = self._get(alarm) + try: + event = self._get(alarm) + except HTTPNotFound: + logger.debug('alarm {} not in this resource pool {}' + .format(alarm, self._pool_id)) + continue ret.append(event) return ret def _set_stx_client(self): - pass + self.driver.setFaultClient(self._pool_id) class StxEventClient(BaseClient): @@ -102,22 +105,83 @@ class StxEventClient(BaseClient): return self.driver.getEventList(**filters) def _set_stx_client(self): - pass + self.driver.setFaultClient(self._pool_id) # internal driver which implement client call to Stx Fault Management instance class StxFaultClientImp(object): - def __init__(self, fm_client=None): + def __init__(self, fm_client=None, stx_client=None, dc_client=None): super().__init__() self.fmclient = fm_client if fm_client else self.getFmClient() - # if subcloud_id is not None: - # self.stxclient = self.getSubcloudClient(subcloud_id) + self.stxclient = stx_client if stx_client else self.getStxClient() + self.dcclient = dc_client if dc_client else self.getDcmanagerClient() + + def getStxClient(self): + os_client_args = config.get_stx_access_info() + config_client = get_stx_client(**os_client_args) + return config_client + + def getDcmanagerClient(self): + os_client_args = config.get_dc_access_info() + config_client = get_dc_client(**os_client_args) + return config_client def getFmClient(self): os_client_args = config.get_fm_access_info() config_client = get_fm_client(1, **os_client_args) return config_client + def getSubcloudList(self): + subs = self.dcclient.subcloud_manager.list_subclouds() + known_subs = [sub for sub in subs if sub.sync_status != 'unknown'] + return known_subs + + def getSubcloudFaultClient(self, subcloud_id): + subcloud = self.dcclient.subcloud_manager.\ + subcloud_additional_details(subcloud_id) + logger.debug('subcloud name: %s, oam_floating_ip: %s' % + (subcloud[0].name, subcloud[0].oam_floating_ip)) + try: + sub_is_https = False + os_client_args = config.get_stx_access_info( + region_name=subcloud[0].name, + subcloud_hostname=subcloud[0].oam_floating_ip) + stx_client = get_stx_client(**os_client_args) + except EndpointException as e: + msg = e.format_message() + if CGTSCLIENT_ENDPOINT_ERROR_MSG in msg: + sub_is_https = True + os_client_args = config.get_stx_access_info( + region_name=subcloud[0].name, sub_is_https=sub_is_https, + subcloud_hostname=subcloud[0].oam_floating_ip) + stx_client = get_stx_client(**os_client_args) + else: + raise ValueError('Stx endpoint exception: %s' % msg) + except Exception: + raise ValueError('cgtsclient get subcloud client failed') + + os_client_args = config.get_fm_access_info( + sub_is_https=sub_is_https, + subcloud_hostname=subcloud[0].oam_floating_ip) + fm_client = get_fm_client(1, **os_client_args) + + return stx_client, fm_client + + def setFaultClient(self, resource_pool_id): + systems = self.stxclient.isystem.list() + if resource_pool_id == systems[0].uuid: + logger.debug('Fault Client not change: %s' % resource_pool_id) + self.fmclient = self.getFmClient() + return + + subclouds = self.getSubcloudList() + for subcloud in subclouds: + substxclient, subfaultclient = self.getSubcloudFaultClient( + subcloud.subcloud_id) + systems = substxclient.isystem.list() + if resource_pool_id == systems[0].uuid: + self.fmclient = subfaultclient + def getAlarmList(self, **filters) -> List[alarmModel.FaultGenericModel]: alarms = self.fmclient.alarm.list(expand=True) if len(alarms) == 0: @@ -132,7 +196,6 @@ class StxFaultClientImp(object): try: alarm = self.fmclient.alarm.get(id) logger.debug('get alarm id ' + id + ':' + str(alarm.to_dict())) - # print(alarm.to_dict()) except HTTPNotFound: event = self.fmclient.event_log.get(id) return alarmModel.FaultGenericModel( @@ -152,7 +215,6 @@ class StxFaultClientImp(object): def getEventInfo(self, id) -> alarmModel.FaultGenericModel: event = self.fmclient.event_log.get(id) logger.debug('get event id ' + id + ':' + str(event.to_dict())) - # print(event.to_dict()) return alarmModel.FaultGenericModel( alarmModel.EventTypeEnum.EVENT, self._eventconverter(event)) diff --git a/o2ims/adapter/clients/ocloud_client.py b/o2ims/adapter/clients/ocloud_client.py index 9af3b7a..9fea66c 100644 --- a/o2ims/adapter/clients/ocloud_client.py +++ b/o2ims/adapter/clients/ocloud_client.py @@ -15,18 +15,18 @@ # client talking to Stx standalone import uuid -from o2common.service.client.base_client import BaseClient from typing import List # Optional, Set -from o2ims.domain import stx_object as ocloudModel -from o2common.config import config -from o2ims.domain.resource_type import ResourceTypeEnum -# from dcmanagerclient.api import client from cgtsclient.client import get_client as get_stx_client from cgtsclient.exc import EndpointException from dcmanagerclient.api.client import client as get_dc_client +from o2common.config import config +from o2common.service.client.base_client import BaseClient +from o2ims.domain import stx_object as ocloudModel +from o2ims.domain.resource_type import ResourceTypeEnum + from o2common.helper import o2logging logger = o2logging.get_logger(__name__) @@ -229,7 +229,7 @@ class StxClientImp(object): os_client_args = config.get_stx_access_info( region_name=subcloud[0].name, subcloud_hostname=subcloud[0].oam_floating_ip) - logger.info(os_client_args) + # logger.info(os_client_args) config_client = get_stx_client(**os_client_args) except EndpointException as e: msg = e.format_message() @@ -237,7 +237,7 @@ class StxClientImp(object): os_client_args = config.get_stx_access_info( region_name=subcloud[0].name, sub_is_https=True, subcloud_hostname=subcloud[0].oam_floating_ip) - logger.info(os_client_args) + # logger.info(os_client_args) config_client = get_stx_client(**os_client_args) else: raise ValueError('Stx endpoint exception: %s' % msg) diff --git a/o2ims/domain/commands.py b/o2ims/domain/commands.py index 349188f..4f86a6f 100644 --- a/o2ims/domain/commands.py +++ b/o2ims/domain/commands.py @@ -136,4 +136,4 @@ class UpdatePserverAcc(UpdateResource): @dataclass class UpdateAlarm(UpdateFaultObject): - pass + parentid: str diff --git a/o2ims/service/auditor/alarm_handler.py b/o2ims/service/auditor/alarm_handler.py index 2bd2681..36be48f 100644 --- a/o2ims/service/auditor/alarm_handler.py +++ b/o2ims/service/auditor/alarm_handler.py @@ -37,6 +37,8 @@ def update_alarm( + " id: " + str(fmobj.id) + " hash: " + str(fmobj.hash)) with uow: + resourcepool = uow.resource_pools.get(cmd.parentid) + alarm_event_record = uow.alarm_event_records.get(fmobj.id) if not alarm_event_record: logger.info("add alarm event record:" + fmobj.name @@ -52,13 +54,10 @@ def update_alarm( # TODO: handle different resource type hostname = entity_instance_id.split('.')[0].split('=')[1] logger.debug('hostname: ' + hostname) - respools = uow.resource_pools.list() - respoolids = [respool.resourcePoolId for respool in - respools if respool.oCloudId == - respool.resourcePoolId] + restype = uow.resource_types.get_by_name('pserver') localmodel.resourceTypeId = restype.resourceTypeId - hosts = uow.resources.list(respoolids[0], **{ + hosts = uow.resources.list(resourcepool.resourcePoolId, **{ 'resourceTypeId': restype.resourceTypeId }) for host in hosts: @@ -72,6 +71,18 @@ def update_alarm( # localmodel.resourceId = check_res_id(uow, fmobj) # logger.debug("resource ID: " + localmodel.resourceId) # uow.alarm_event_records.add(localmodel) + else: + restype = uow.resource_types.get_by_name('undefined_aggregate') + localmodel.resourceTypeId = restype.resourceTypeId + + undefined_res = uow.resources.list( + resourcepool.resourcePoolId, **{ + 'resourceTypeId': restype.resourceTypeId + }) + localmodel.resourceId = undefined_res[0].resourceId + uow.alarm_event_records.add(localmodel) + logger.info("Add the alarm event record: " + fmobj.id + + ", name: " + fmobj.name) else: localmodel = alarm_event_record diff --git a/o2ims/service/watcher/alarm_watcher.py b/o2ims/service/watcher/alarm_watcher.py index 3581ef2..b4af164 100644 --- a/o2ims/service/watcher/alarm_watcher.py +++ b/o2ims/service/watcher/alarm_watcher.py @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -# from o2ims.domain.resource_type import ResourceTypeEnum -from o2common.service.client.base_client import BaseClient -# from o2ims.domain.stx_object import StxGenericModel -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.service.watcher.base import BaseWatcher +from o2common.domain import tags from o2common.service.messagebus import MessageBus +from o2common.service.watcher.base import BaseWatcher +from o2common.service.client.base_client import BaseClient + from o2ims.domain import commands +from o2ims.domain.stx_object import StxGenericModel from o2common.helper import o2logging logger = o2logging.get_logger(__name__) @@ -28,65 +28,22 @@ class AlarmWatcher(BaseWatcher): def __init__(self, fault_client: BaseClient, bus: MessageBus) -> None: super().__init__(fault_client, bus) + self._tags = tags.Tag() + self.poolid = None def _targetname(self): return "alarm" - def _probe(self, parent: object = None, tags: object = None): - newmodels = self._client.list() - # if len(newmodels) == 0: - # return [] - - # uow = self._bus.uow - # exist_alarms = {} - # with uow: - # rs = uow.session.execute( - # ''' - # SELECT "alarmEventRecordId" - # FROM "alarmEventRecord" - # WHERE "perceivedSeverity" != :perceived_severity_enum - # ''', - # dict(perceived_severity_enum=alarm_obj.PerceivedSeverityEnum. - # CLEARED) - # ) - # for row in rs: - # id = row[0] - # # logger.debug('Exist alarm: ' + id) - # exist_alarms[id] = False + def _probe(self, parent: StxGenericModel, tags: object = None): + # Set a tag for children resource + self._tags.pool = parent.res_pool_id + self._set_respool_client() - # ret = [] - # for m in newmodels: - # try: - # if exist_alarms[m.id]: - # ret.append(commands.UpdateAlarm(m)) - # exist_alarms[m.id] = True - # except KeyError: - # logger.debug('alarm new: ' + m.id) - # ret.append(commands.UpdateAlarm(m)) - - # for alarm in exist_alarms: - # logger.debug('exist alarm: ' + alarm) - # if exist_alarms[alarm]: - # # exist alarm is active - # continue - # event = self._client.get(alarm) - # ret.append(commands.UpdateAlarm(event)) - - # return ret - - return [commands.UpdateAlarm(m) for m in newmodels] \ + resourcepoolid = parent.id + newmodels = self._client.list() + return [commands.UpdateAlarm(m, resourcepoolid) for m in newmodels] \ if len(newmodels) > 0 else [] - -# class EventWatcher(BaseWatcher): -# def __init__(self, fault_client: BaseClient, -# bus: MessageBus) -> None: -# super().__init__(fault_client, bus) - -# def _targetname(self): -# return "event" - -# def _probe(self, parent: object = None, tags: object = None): -# newmodels = self._client.list() -# return [commands.UpdateAlarm(m) for m in newmodels] \ -# if len(newmodels) > 0 else [] + def _set_respool_client(self): + self.poolid = self._tags.pool + self._client.set_pool_driver(self.poolid) diff --git a/tests/integration-ocloud/test_clientdriver_stx_fault.py b/tests/integration-ocloud/test_clientdriver_stx_fault.py index 3c8699b..f94b28a 100644 --- a/tests/integration-ocloud/test_clientdriver_stx_fault.py +++ b/tests/integration-ocloud/test_clientdriver_stx_fault.py @@ -87,3 +87,17 @@ def test_get_eventinfo(real_stx_fm_client): event2 = fmClientImp.getEventInfo(event1.id) assert event1 != event2 assert event1.id == event2.id + + +def test_get_subcloud_alarmlist(real_stx_fm_client, real_stx_dc_client): + fmClientImp = StxFaultClientImp( + real_stx_fm_client, dc_client=real_stx_dc_client) + assert fmClientImp is not None + subclouds = fmClientImp.getSubcloudList() + stxclient, _ = fmClientImp.getSubcloudFaultClient(subclouds[0].subcloud_id) + res_pool_id = stxclient.isystem.list()[0].uuid + + fmClientImp.setFaultClient(res_pool_id) + alarms = fmClientImp.getAlarmList() + assert alarms is not None + assert len(alarms) > 0 diff --git a/tests/unit/test_alarm.py b/tests/unit/test_alarm.py index 0c0b3e5..1503d09 100644 --- a/tests/unit/test_alarm.py +++ b/tests/unit/test_alarm.py @@ -314,7 +314,12 @@ def test_probe_new_alarm(): bus = create_alarm_fake_bus(fakeuow) fakeClient = FakeAlarmClient() alarmwatcher = AlarmWatcher(fakeClient, bus) - cmds = alarmwatcher.probe() + parent = type('obj', (object,), { + 'data': type('obj', (object,), { + 'id': 'test_parent_id', + 'res_pool_id': 'test_res_pool' + })}) + cmds = alarmwatcher.probe(parent) assert cmds is not None assert len(cmds) == 1 assert cmds[0].data.name == "alarm"