From: Zhang Rong(Jon) Date: Mon, 8 May 2023 13:08:24 +0000 (+0800) Subject: Add capabilities of the DMS query X-Git-Tag: 2.0.2~9^2~1 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=7035c7fbdc47ede3726570e7eaf00474d464d8b8;p=pti%2Fo2.git Add capabilities of the DMS query Issue-ID: INF-397 Signed-off-by: Zhang Rong(Jon) Change-Id: Ic5a40bbd25e38f19384dce443a55515a441a9618 --- diff --git a/o2ims/adapter/clients/ocloud_client.py b/o2ims/adapter/clients/ocloud_client.py index b8eeb21..a3cd6e0 100644 --- a/o2ims/adapter/clients/ocloud_client.py +++ b/o2ims/adapter/clients/ocloud_client.py @@ -15,6 +15,7 @@ # client talking to Stx standalone import uuid +import json from typing import List # Optional, Set @@ -333,6 +334,50 @@ class StxClientImp(object): return ocloudModel.StxGenericModel( ResourceTypeEnum.PSERVER, self._hostconverter(host)) + def _checkLabelExistOnHost(self, label_key, hostid) -> bool: + labels = self.stxclient.label.list(hostid) + return any(label_key == label.label_key for label in labels) + + def _checkLabelExistOnCluster(self, label_key) -> bool: + hosts = self.stxclient.ihost.list() + + def find_label_on_host(): + result = next( + ( + (host, True) + for host in hosts + if self._checkLabelExistOnHost(label_key, host.uuid) + ), + (None, False), + ) + + if result[1]: + logger.info("host %s has the label %s" % + (result[0].hostname, label_key)) + + return result[1] + + return find_label_on_host() + + # return any(self._checkLabelExistOnHost(label_key, host.uuid) for host + # in hosts) + + def _setK8sCapabilities(self, k8scluster): + capabilities = {} + if self._checkLabelExistOnCluster('OS'): + logger.debug("low latency host inside of the cluster") + capabilities['OS'] = 'low_latency' + setattr(k8scluster, 'capabilities', json.dumps(capabilities)) + return k8scluster + + def getLabelList(self, **filters) -> List[ocloudModel.StxGenericModel]: + hostid = filters.get('hostid', None) + assert (hostid is not None), 'missing hostid to query label list' + labels = self.stxclient.label.list(hostid) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_LABEL, + self._labelconverter(label)) for label in labels if label] + def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]: systems = self.stxclient.isystem.list() logger.debug('system controller distributed_cloud_role:' + @@ -342,9 +387,10 @@ class StxClientImp(object): systems[0].distributed_cloud_role != 'systemcontroller': k8sclusters = self.stxclient.kube_cluster.list() setattr(k8sclusters[0], 'cloud_name', systems[0].name) - logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) - # logger.debug('k8sresources[0] cluster_api_endpoint: ' + - # str(k8sclusters[0].cluster_api_endpoint)) + k8sclusters[0] = self._setK8sCapabilities(k8sclusters[0]) + # logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) + logger.debug('k8sresources[0] cluster_api_endpoint: ' + + str(k8sclusters[0].cluster_api_endpoint)) return [ocloudModel.StxGenericModel( ResourceTypeEnum.DMS, self._k8sconverter(k8sres), self._k8shasher(k8sres)) @@ -354,9 +400,10 @@ class StxClientImp(object): if config.get_system_controller_as_respool(): k8sclusters = self.stxclient.kube_cluster.list() setattr(k8sclusters[0], 'cloud_name', systems[0].name) - logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) - # logger.debug('k8sresources[0] cluster_api_endpoint: ' + - # str(k8sclusters[0].cluster_api_endpoint)) + k8sclusters[0] = self._setK8sCapabilities(k8sclusters[0]) + # logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) + logger.debug('k8sresources[0] cluster_api_endpoint: ' + + str(k8sclusters[0].cluster_api_endpoint)) k8s_list.append(k8sclusters[0]) subclouds = self.getSubcloudList() @@ -368,6 +415,7 @@ class StxClientImp(object): systems = subcloud_stxclient.isystem.list() k8sclusters = subcloud_stxclient.kube_cluster.list() setattr(k8sclusters[0], 'cloud_name', systems[0].name) + k8sclusters[0] = self._setK8sCapabilities(k8sclusters[0]) logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) # logger.debug('k8sresources[0] cluster_api_endpoint: ' + @@ -388,6 +436,7 @@ class StxClientImp(object): k8sclusters = self.stxclient.kube_cluster.list() # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict())) setattr(k8sclusters[0], 'cloud_name', systems[0].name) + k8sclusters[0] = self._setK8sCapabilities(k8sclusters[0]) k8scluster = k8sclusters.pop() else: sname = name.split('.') @@ -396,6 +445,7 @@ class StxClientImp(object): if cloud_name == systems[0].name: k8scluster = self.stxclient.kube_cluster.get(k8s_name) setattr(k8scluster, 'cloud_name', cloud_name) + k8scluster = self._setK8sCapabilities(k8scluster) else: subclouds = self.getSubcloudList() subcloud_id = [ @@ -404,6 +454,7 @@ class StxClientImp(object): subcloud_stxclient = self.getSubcloudClient(subcloud_id) k8scluster = subcloud_stxclient.kube_cluster.get(k8s_name) setattr(k8scluster, 'cloud_name', cloud_name) + k8scluster = self._setK8sCapabilities(k8scluster) # logger.debug('k8sresources[0]:' + # str(k8sclusters[0].to_dict())) # logger.debug('k8sresources[0] cluster_api_endpoint: ' + @@ -550,6 +601,22 @@ class StxClientImp(object): setattr(host, 'name', host.hostname) return host + @ staticmethod + def _labelconverter(label): + selected_keys = [ + "uuid", "label_key", "label_value", "host_uuid" + ] + content = label.to_dict() + print(content) + filtered = dict( + filter(lambda item: item[0] in selected_keys, content.items())) + setattr(label, 'filtered', filtered) + setattr(label, 'name', label.uuid.split( + '-', 1)[0] + '-label-' + label.label_key) + setattr(label, 'updated_at', None) + setattr(label, 'created_at', None) + return label + @ staticmethod def _cpuconverter(cpu): selected_keys = [ @@ -646,4 +713,5 @@ class StxClientImp(object): @ staticmethod def _k8shasher(cluster): return str(hash((cluster.cluster_name, cluster.cloud_name, - cluster.cluster_api_endpoint, cluster.admin_user))) + cluster.cluster_api_endpoint, cluster.admin_user, + cluster.capabilities))) diff --git a/o2ims/domain/ocloud.py b/o2ims/domain/ocloud.py index eb4f34b..ee3da89 100644 --- a/o2ims/domain/ocloud.py +++ b/o2ims/domain/ocloud.py @@ -63,6 +63,8 @@ class DeploymentManager(AgRoot, Serializer): elif profile == DeploymentManagerProfileSOL018HelmCLI: d['profileSupportList'].append(profile) + if 'capabilities' in d and d['capabilities'] != '': + d['capabilities'] = json.loads(d['capabilities']) return d diff --git a/o2ims/domain/resource_type.py b/o2ims/domain/resource_type.py index 84b9285..3564cd6 100644 --- a/o2ims/domain/resource_type.py +++ b/o2ims/domain/resource_type.py @@ -14,6 +14,7 @@ class ResourceTypeEnum(Enum): PSERVER_ETH = 16 PSERVER_PCI_DEV = 17 PSERVER_ACC = 18 + PSERVER_LABEL = 19 COMPUTE_AGGREGATE = 70 NETWORK_AGGREGATE = 80 STORAGE_AGGREGATE = 90 diff --git a/o2ims/domain/stx_object.py b/o2ims/domain/stx_object.py index 2eee7b7..549c4fc 100644 --- a/o2ims/domain/stx_object.py +++ b/o2ims/domain/stx_object.py @@ -36,14 +36,16 @@ class StxGenericModel(AgRoot): self.createtime = datetime.datetime.strptime( api_response.created_at.split('.')[0], "%Y-%m-%dT%H:%M:%S") \ if api_response.created_at else None - self.hash = content_hash - if not self.hash: - if hasattr(api_response, 'filtered'): - self.filtered = api_response.filtered - self.hash = str(hash((self.id, str(self.filtered)))) - else: - self.hash = str(hash((self.id, self.updatetime))) - self.content = json.dumps(api_response.to_dict()) + self.filtered = getattr(api_response, 'filtered', None) + self.hash = content_hash or str( + hash((self.id, str(self.filtered) + if self.filtered else self.updatetime))) + + def handle_non_serializable(obj): + return repr(obj) + self.content = json.dumps( + vars(api_response), default=handle_non_serializable) + if ResourceTypeEnum.RESOURCE_POOL == type: self.res_pool_id = self.id diff --git a/o2ims/service/auditor/dms_handler.py b/o2ims/service/auditor/dms_handler.py index f7d5405..11436b9 100644 --- a/o2ims/service/auditor/dms_handler.py +++ b/o2ims/service/auditor/dms_handler.py @@ -77,10 +77,12 @@ def is_outdated(ocloud: DeploymentManager, stxobj: StxGenericModel): def create_by(stxobj: StxGenericModel, parentid: str) -> DeploymentManager: description = "A DMS" ocloudid = parentid + content = json.loads(stxobj.content) + # logger.info(stxobj) + # logger.info(content) supportedLocations = '' - capabilities = '' + capabilities = content['capabilities'] capacity = '' - content = json.loads(stxobj.content) dmsendpoint = content['cluster_api_endpoint'] profile = _convert_content(content) localmodel = DeploymentManager( @@ -103,13 +105,16 @@ def update_by(target: DeploymentManager, stxobj: StxGenericModel, parentid: str) -> None: if target.deploymentManagerId != stxobj.id: raise MismatchedModel("Mismatched Id") + content = json.loads(stxobj.content) + logger.info(content) target.name = stxobj.name target.createtime = stxobj.createtime target.updatetime = stxobj.updatetime target.hash = stxobj.hash target.oCloudId = parentid + target.capabilities = content['capabilities'] target.version_number = target.version_number + 1 - target.profile = _convert_content(stxobj.content) + target.profile = _convert_content(content) target.events.append(events.DmsChanged( id=stxobj.id, diff --git a/o2ims/views/ocloud_dto.py b/o2ims/views/ocloud_dto.py index 3007024..622bc46 100644 --- a/o2ims/views/ocloud_dto.py +++ b/o2ims/views/ocloud_dto.py @@ -359,6 +359,14 @@ class ResourceDTO: class DeploymentManagerDTO: + capabilities = api_ims_inventory_v1.model( + "DeploymentManagerCapabilities", { + 'OS': fields.String( + example='low_latency', + description='Show the OS capablities of ' + + 'the Deployment Manager'), + }) + deployment_manager_list = api_ims_inventory_v1.model( "DeploymentManagerListDto", { @@ -380,11 +388,11 @@ class DeploymentManagerDTO: attribute='serviceUri', example='https://128.224.115.51:6443', description='The fully qualified URI to a Deployment ' + - 'Management server for O2dms services.'), + 'Management server for O2dms.'), # 'deploymentManagementServiceEndpoint': fields.String( # attribute='serviceUri'), # 'supportedLocations': fields.String, - # 'capabilities': fields.String, + 'capabilities': fields.Nested(capabilities, True, True), # 'capacity': fields.String, 'profileSupportList': fields.List( fields.String, @@ -469,11 +477,11 @@ class DeploymentManagerDTO: attribute='serviceUri', example='https://128.224.115.51:6443', description='The fully qualified URI to a Deployment ' + - 'Management server for O2dms services.'), + 'Management server for O2dms.'), # 'deploymentManagementServiceEndpoint': fields.String( # attribute='serviceUri'), # 'supportedLocations': fields.String, - # 'capabilities': fields.String, + 'capabilities': fields.Nested(capabilities, True, True), # 'capacity': fields.String, 'extensions': fields.Nested(extensions, True, True) }, diff --git a/tests/integration-ocloud/test_clientdriver_stx.py b/tests/integration-ocloud/test_clientdriver_stx.py index 8ca1780..a9f404b 100644 --- a/tests/integration-ocloud/test_clientdriver_stx.py +++ b/tests/integration-ocloud/test_clientdriver_stx.py @@ -89,6 +89,20 @@ def test_get_k8s_list(real_stx_aio_client): assert k8s3.id == k8s4.id +def test_get_label_list(real_stx_aio_client): + stxClientImp = StxClientImp(real_stx_aio_client) + assert stxClientImp is not None + hostlist = stxClientImp.getPserverList() + assert len(hostlist) > 0 + + print(hostlist[0].id) + + labellist = stxClientImp.getLabelList(hostid=hostlist[0].id) + assert len(labellist) > 0 + label1 = labellist[0] + assert label1.id == "test" + + def test_get_cpu_list(real_stx_aio_client): stxClientImp = StxClientImp(real_stx_aio_client) assert stxClientImp is not None