Add capacity values for the DMS K8S profile
[pti/o2.git] / o2ims / adapter / clients / ocloud_client.py
1 # Copyright (C) 2022 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 # client talking to Stx standalone
16
17 import base64
18 import uuid
19 import json
20 from typing import List
21 # Optional,  Set
22
23 from cgtsclient.client import get_client as get_stx_client
24 from cgtsclient.exc import EndpointException
25 from dcmanagerclient.api.client import client as get_dc_client
26 from kubernetes import client as k8sclient, config as k8sconfig
27
28 from o2common.config import config
29 from o2common.service.client.base_client import BaseClient
30 from o2ims.domain import stx_object as ocloudModel
31 from o2ims.domain.resource_type import ResourceTypeEnum
32
33 from o2common.helper import o2logging
34 logger = o2logging.get_logger(__name__)
35
36
37 CGTSCLIENT_ENDPOINT_ERROR_MSG = \
38     'Must provide Keystone credentials or user-defined endpoint and token'
39
40
41 class StxOcloudClient(BaseClient):
42     def __init__(self, driver=None):
43         super().__init__()
44         self.driver = driver if driver else StxClientImp()
45
46     def _get(self, id) -> ocloudModel.StxGenericModel:
47         return self.driver.getInstanceInfo()
48
49     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
50         return [self.driver.getInstanceInfo()]
51
52     def _set_stx_client(self):
53         pass
54
55
56 class StxResourcePoolClient(BaseClient):
57     def __init__(self):
58         super().__init__()
59         self.driver = StxClientImp()
60
61     def _get(self, id) -> ocloudModel.StxGenericModel:
62         return self.driver.getResourcePoolDetail(id)
63
64     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
65         return self.driver.getResourcePoolList(**filters)
66
67     def _set_stx_client(self):
68         pass
69
70
71 class StxDmsClient(BaseClient):
72     def __init__(self):
73         super().__init__()
74         self.driver = StxClientImp()
75
76     def _get(self, name) -> ocloudModel.StxGenericModel:
77         return self.driver.getK8sDetail(name)
78
79     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
80         return self.driver.getK8sList(**filters)
81
82     def _set_stx_client(self):
83         pass
84
85
86 class StxPserverClient(BaseClient):
87     def __init__(self):
88         super().__init__()
89         self.driver = StxClientImp()
90
91     def _get(self, id) -> ocloudModel.StxGenericModel:
92         return self.driver.getPserver(id)
93
94     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
95         return self.driver.getPserverList(**filters)
96
97     def _set_stx_client(self):
98         self.driver.setStxClient(self._pool_id)
99
100
101 class StxCpuClient(BaseClient):
102     def __init__(self):
103         super().__init__()
104         # self._pserver_id = pserver_id
105         self.driver = StxClientImp()
106
107     def _get(self, id) -> ocloudModel.StxGenericModel:
108         return self.driver.getCpu(id)
109
110     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
111         return self.driver.getCpuList(**filters)
112
113     def _set_stx_client(self):
114         self.driver.setStxClient(self._pool_id)
115
116
117 class StxMemClient(BaseClient):
118     def __init__(self):
119         super().__init__()
120         self.driver = StxClientImp()
121
122     def _get(self, id) -> ocloudModel.StxGenericModel:
123         return self.driver.getMem(id)
124
125     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
126         return self.driver.getMemList(**filters)
127
128     def _set_stx_client(self):
129         self.driver.setStxClient(self._pool_id)
130
131
132 class StxEthClient(BaseClient):
133     def __init__(self):
134         super().__init__()
135         self.driver = StxClientImp()
136
137     def _get(self, id) -> ocloudModel.StxGenericModel:
138         return self.driver.getEthernet(id)
139
140     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
141         return self.driver.getEthernetList(**filters)
142
143     def _set_stx_client(self):
144         self.driver.setStxClient(self._pool_id)
145
146
147 class StxIfClient(BaseClient):
148     def __init__(self):
149         super().__init__()
150         self.driver = StxClientImp()
151
152     def _get(self, id) -> ocloudModel.StxGenericModel:
153         return self.driver.getIf(id)
154
155     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
156         return self.driver.getIfList(**filters)
157
158     def _set_stx_client(self):
159         self.driver.setStxClient(self._pool_id)
160
161
162 class StxIfPortClient(BaseClient):
163     def __init__(self):
164         super().__init__()
165         self.driver = StxClientImp()
166
167     def _get(self, id) -> ocloudModel.StxGenericModel:
168         return self.driver.getPort(id)
169
170     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
171         return self.driver.getPortList(**filters)
172
173     def _set_stx_client(self):
174         self.driver.setStxClient(self._pool_id)
175
176
177 class StxDevClient(BaseClient):
178     def __init__(self):
179         super().__init__()
180         self.driver = StxClientImp()
181
182     def _get(self, id) -> ocloudModel.StxGenericModel:
183         return self.driver.getDevice(id)
184
185     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
186         return self.driver.getDeviceList(**filters)
187
188     def _set_stx_client(self):
189         self.driver.setStxClient(self._pool_id)
190
191
192 class StxAccClient(BaseClient):
193     def __init__(self):
194         super().__init__()
195         self.driver = StxClientImp()
196
197     def _get(self, id) -> ocloudModel.StxGenericModel:
198         return self.driver.getAccelerator(id)
199
200     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
201         return self.driver.getAcceleratorList(**filters)
202
203     def _set_stx_client(self):
204         self.driver.setStxClient(self._pool_id)
205
206
207 # internal driver which implement client call to Stx Standalone and DC instance
208 class StxClientImp(object):
209     def __init__(self, stx_client=None, dc_client=None):
210         super().__init__()
211         self.stxclient = stx_client if stx_client else self.getStxClient()
212         self.dcclient = dc_client if dc_client else self.getDcmanagerClient()
213         # if subcloud_id is not None:
214         # self.stxclient = self.getSubcloudClient(subcloud_id)
215
216     def getStxClient(self):
217         os_client_args = config.get_stx_access_info()
218         config_client = get_stx_client(**os_client_args)
219         return config_client
220
221     def getDcmanagerClient(self):
222         os_client_args = config.get_dc_access_info()
223         config_client = get_dc_client(**os_client_args)
224         return config_client
225
226     def getSubcloudClient(self, subcloud_id):
227         subcloud = self.dcclient.subcloud_manager.\
228             subcloud_additional_details(subcloud_id)
229         logger.debug('subcloud name: %s, oam_floating_ip: %s' %
230                      (subcloud[0].name, subcloud[0].oam_floating_ip))
231         if subcloud[0].oam_floating_ip == 'unavailable':
232             raise EnvironmentError(f"{subcloud[0].name} was unavailable")
233         try:
234             os_client_args = config.get_stx_access_info(
235                 region_name=subcloud[0].region_name,
236                 subcloud_hostname=subcloud[0].oam_floating_ip)
237             # logger.info(os_client_args)
238             config_client = get_stx_client(**os_client_args)
239         except EndpointException as e:
240             msg = e.format_message()
241             if CGTSCLIENT_ENDPOINT_ERROR_MSG in msg:
242                 os_client_args = config.get_stx_access_info(
243                     region_name=subcloud[0].region_name, sub_is_https=True,
244                     subcloud_hostname=subcloud[0].oam_floating_ip)
245                 # logger.info(os_client_args)
246                 config_client = get_stx_client(**os_client_args)
247             else:
248                 raise ValueError('Stx endpoint exception: %s' % msg)
249         except Exception:
250             raise ValueError('cgtsclient get subcloud client failed')
251
252         return config_client
253
254     def getK8sClient(self, k8scluster):
255         def _b64_encode_str(msg: str, encode: str = 'utf-8') -> str:
256             msg_bytes = msg.encode('utf-8')
257             base64_bytes = base64.b64encode(msg_bytes)
258             base64_msg = base64_bytes.decode('utf-8')
259             return base64_msg
260
261         conf_dict = config.gen_k8s_config_dict(
262             k8scluster.cluster_api_endpoint,
263             _b64_encode_str(k8scluster.cluster_ca_cert),
264             k8scluster.admin_user,
265             _b64_encode_str(k8scluster.admin_client_cert),
266             _b64_encode_str(k8scluster.admin_client_key),
267         )
268         k8sconfig.load_kube_config_from_dict(conf_dict)
269         v1 = k8sclient.CoreV1Api()
270         return v1
271
272     def setStxClient(self, resource_pool_id):
273         systems = self.stxclient.isystem.list()
274         if resource_pool_id == systems[0].uuid:
275             logger.debug('Stx Client not change: %s' % resource_pool_id)
276             return
277
278         subclouds = self.getSubcloudList()
279         for subcloud in subclouds:
280             subcloud_stxclient = self.getSubcloudClient(subcloud.subcloud_id)
281             systems = subcloud_stxclient.isystem.list()
282             # logger.debug('subcloud %s id: %s' %
283             #  (systems[0].name, systems[0].uuid))
284             # logger.debug('subcloud: %s' % (systems[0].to_dict()))
285             if resource_pool_id == systems[0].uuid:
286                 self.stxclient = subcloud_stxclient
287
288     def getInstanceInfo(self) -> ocloudModel.StxGenericModel:
289         systems = self.stxclient.isystem.list()
290         logger.debug('systems:' + str(systems[0].to_dict()))
291         # logger.debug('systems[0] uuid: ' + str(systems[0].uuid))
292         return ocloudModel.StxGenericModel(
293             ResourceTypeEnum.OCLOUD, systems[0]) if systems else None
294
295     def getSubcloudList(self):
296         self.dcclient = self.getDcmanagerClient()
297         subs = self.dcclient.subcloud_manager.list_subclouds()
298         known_subs = [sub for sub in subs if sub.sync_status != 'unknown']
299         return known_subs
300
301     def getResourcePoolList(self, **filters) -> List[
302             ocloudModel.StxGenericModel]:
303         systems = self.stxclient.isystem.list()
304         logger.debug('system controller distributed_cloud_role:' +
305                      str(systems[0].distributed_cloud_role))
306
307         if systems[0].distributed_cloud_role is None or \
308                 systems[0].distributed_cloud_role != 'systemcontroller':
309             return [ocloudModel.StxGenericModel(
310                 ResourceTypeEnum.RESOURCE_POOL,
311                 self._respoolconverter(systems[0]))]
312
313         pools = []
314         if config.get_system_controller_as_respool():
315             pools.append(systems[0])
316
317         subclouds = self.getSubcloudList()
318         logger.debug('subclouds numbers: %s' % len(subclouds))
319         for subcloud in subclouds:
320             try:
321                 subcloud_stxclient = self.getSubcloudClient(
322                     subcloud.subcloud_id)
323                 systems = subcloud_stxclient.isystem.list()
324                 logger.debug('subcloud system:' + str(systems[0].to_dict()))
325                 pools.append(systems[0])
326             except Exception as ex:
327                 logger.warning('Failed get cgstclient of subcloud %s: %s' %
328                                (subcloud.name, ex))
329                 continue
330
331         return [ocloudModel.StxGenericModel(
332             ResourceTypeEnum.RESOURCE_POOL,
333                 self._respoolconverter(
334                     respool)) for respool in pools if respool]
335
336     def getResourcePoolDetail(self, id):
337         self.setStxClient(id)
338         systems = self.stxclient.isystem.list()
339         logger.debug('systems:' + str(systems[0].to_dict()))
340         return ocloudModel.StxGenericModel(
341             ResourceTypeEnum.RESOURCE_POOL,
342             self._respoolconverter(systems[0])) if systems else None
343
344     def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]:
345         hosts = self.stxclient.ihost.list()
346         logger.debug('host 1:' + str(hosts[0].to_dict()))
347         return [ocloudModel.StxGenericModel(
348             ResourceTypeEnum.PSERVER, self._hostconverter(host))
349             for host in hosts if host and (host.availability == 'available'
350                                            or host.availability == 'online'
351                                            or host.availability == 'degraded')]
352
353     def getPserver(self, id) -> ocloudModel.StxGenericModel:
354         host = self.stxclient.ihost.get(id)
355         logger.debug('host:' + str(host.to_dict()))
356         return ocloudModel.StxGenericModel(
357             ResourceTypeEnum.PSERVER, self._hostconverter(host))
358
359     def _checkLabelExistOnHost(self, client, label_to_check, host_id,
360                                check_value=False) -> bool:
361         labels = client.label.list(host_id)
362         if check_value:
363             return any(label_to_check['key'] == label.label_key and
364                        label_to_check['value'] == label.label_value
365                        for label in labels)
366         else:
367             return any(label_to_check['key'] == label.label_key
368                        for label in labels)
369
370     def _checkLabelExistOnCluster(self, client, label_to_check,
371                                   check_value=False) -> bool:
372         hosts = client.ihost.list()
373         for host in hosts:
374             if self._checkLabelExistOnHost(client, label_to_check,
375                                            host.uuid, check_value):
376                 if check_value:
377                     logger.info(
378                         f"host {host.hostname} has the label "
379                         f"{label_to_check['key']} with value "
380                         f"{label_to_check['value']}")
381                 else:
382                     logger.info(
383                         f"host {host.hostname} has the label "
384                         f"{label_to_check['key']}")
385                 return True
386         return False
387
388     def _getK8sNodes(self, k8sclient):
389         return k8sclient.list_node()
390
391     def _getK8sNodeDetail(self, k8sclient, node_name):
392         return k8sclient.read_node(name=node_name)
393
394     def _getK8sCapabilities(self, k8s_client):
395         k8s_capabilities = {}
396         nodes = self._getK8sNodes(k8s_client)
397         for node in nodes.items:
398             logger.debug(f'k8s node {node.metadata.name} allocatable: '
399                          f'{node.status.allocatable}')
400             for allocatable in node.status.allocatable:
401                 if allocatable.startswith('intel.com/pci_sriov_net_'):
402                     k8s_capabilities[f'{node.metadata.name}_sriov'] = True
403                 if allocatable == 'windriver.com/isolcpus':
404                     k8s_capabilities[f'{node.metadata.name}_isolcpus'] = True
405         return k8s_capabilities
406
407     def _setK8sCapabilities(self, k8scluster, client, k8s_client):
408         capabilities = {}
409         label_OS_2chk = {'key': 'OS', 'value': 'low_latency'}
410         if self._checkLabelExistOnCluster(client, label_OS_2chk, True):
411             logger.debug("low latency host inside of the k8s cluster")
412             capabilities[label_OS_2chk['key']] = label_OS_2chk['value']
413
414         # Add Kubernetes capabilities
415         k8s_capabilities = self._getK8sCapabilities(k8s_client)
416         capabilities.update(k8s_capabilities)
417
418         setattr(k8scluster, 'capabilities', json.dumps(capabilities))
419         return k8scluster
420
421     def _getK8sCapacity(self, k8s_client):
422         k8s_capacity = {}
423         nodes = self._getK8sNodes(k8s_client)
424         for node in nodes.items:
425             logger.debug(f'k8s node {node.metadata.name} capacity: '
426                          f'{node.status.capacity}')
427             for key, value in node.status.capacity.items():
428                 k8s_capacity[f'{node.metadata.name}_{key}'] = value
429         return k8s_capacity
430
431     def _setK8sCapacity(self, k8scluster, client, k8s_client):
432         capacity = {}
433
434         # Add Kubernetes capacity
435         k8s_capacity = self._getK8sCapacity(k8s_client)
436         capacity.update(k8s_capacity)
437
438         setattr(k8scluster, 'capacity', json.dumps(capacity))
439         return k8scluster
440
441     def getLabelList(self, **filters) -> List[ocloudModel.StxGenericModel]:
442         hostid = filters.get('hostid', None)
443         assert (hostid is not None), 'missing hostid to query label list'
444         labels = self.stxclient.label.list(hostid)
445         return [ocloudModel.StxGenericModel(
446             ResourceTypeEnum.PSERVER_LABEL,
447             self._labelconverter(label)) for label in labels if label]
448
449     def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]:
450         def process_cluster(client, cluster):
451             setattr(cluster, 'cloud_name', systems[0].name)
452             setattr(cluster, 'cloud_uuid', systems[0].uuid)
453
454             k8s_client = self.getK8sClient(cluster)
455             cluster = self._setK8sCapabilities(cluster, client, k8s_client)
456             cluster = self._setK8sCapacity(cluster, client, k8s_client)
457
458             logger.debug('k8sresources cluster_api_endpoint: ' +
459                          str(cluster.cluster_api_endpoint))
460             return ocloudModel.StxGenericModel(ResourceTypeEnum.DMS,
461                                                self._k8sconverter(cluster),
462                                                self._k8shasher(cluster))
463
464         systems = self.stxclient.isystem.list()
465         distributed_cloud_role = systems[0].distributed_cloud_role
466         logger.debug((
467             f'system controller distributed_cloud_role: '
468             f'{distributed_cloud_role}'))
469
470         k8s_list = []
471
472         if distributed_cloud_role is None or distributed_cloud_role != \
473                 'systemcontroller':
474             k8s_list.extend(
475                 [process_cluster(self.stxclient, k8s)
476                  for k8s in self.stxclient.kube_cluster.list() if k8s])
477             return k8s_list
478
479         if config.get_system_controller_as_respool():
480             k8s_list.extend(
481                 [process_cluster(self.stxclient, k8s)
482                  for k8s in self.stxclient.kube_cluster.list() if k8s])
483
484         subclouds = self.getSubcloudList()
485         logger.debug(f'subclouds numbers: {len(subclouds)}')
486
487         for subcloud in subclouds:
488             try:
489                 subcloud_stxclient = self.getSubcloudClient(
490                     subcloud.subcloud_id)
491                 systems = subcloud_stxclient.isystem.list()
492                 k8sclusters = subcloud_stxclient.kube_cluster.list()
493                 k8s_list.extend([process_cluster(subcloud_stxclient, k8s)
494                                 for k8s in k8sclusters if k8s])
495             except Exception as ex:
496                 logger.warning((
497                     f'Failed to get cgstclient of subcloud '
498                     f'{subcloud.name}: {ex}'))
499                 continue
500
501         return k8s_list
502
503     def getK8sDetail(self, name) -> ocloudModel.StxGenericModel:
504         def process_k8s_cluster(client, k8s_cluster, cloud_name, cloud_uuid):
505             setattr(k8s_cluster, 'cloud_name', cloud_name)
506             setattr(k8s_cluster, 'cloud_uuid', cloud_uuid)
507
508             k8s_client = self.getK8sClient(k8s_cluster)
509             cluster = self._setK8sCapabilities(k8s_cluster, client, k8s_client)
510             cluster = self._setK8sCapacity(cluster, client, k8s_client)
511             return k8s_cluster
512
513         systems = self.stxclient.isystem.list()
514         system_name = systems[0].name
515         system_uuid = systems[0].uuid
516
517         if not name:
518             k8s_clusters = self.stxclient.kube_cluster.list()
519             k8s_cluster = process_k8s_cluster(
520                 self.stxclient, k8s_clusters.pop(), system_name)
521         else:
522             sname = name.split('.')
523             cloud_name = '.'.join(sname[:-1])
524             k8s_name = sname[-1]
525
526             if cloud_name == system_name:
527                 k8s_cluster = process_k8s_cluster(
528                     self.stxclient,
529                     self.stxclient.kube_cluster.get(k8s_name), cloud_name,
530                     system_uuid)
531             else:
532                 subclouds = self.getSubcloudList()
533                 subcloud_id = next(
534                     sub.subcloud_id for sub in subclouds
535                     if sub.name == cloud_name)
536                 subcloud_stxclient = self.getSubcloudClient(subcloud_id)
537                 systems = subcloud_stxclient.isystem.list()
538                 system_uuid = systems[0].uuid
539                 k8s_cluster = process_k8s_cluster(
540                     subcloud_stxclient,
541                     subcloud_stxclient.kube_cluster.get(k8s_name), cloud_name,
542                     system_uuid)
543
544         if not k8s_cluster:
545             return None
546
547         logger.debug(f'k8sresource: {k8s_cluster.to_dict()}')
548         return ocloudModel.StxGenericModel(
549             ResourceTypeEnum.DMS, self._k8sconverter(k8s_cluster),
550             self._k8shasher(k8s_cluster))
551
552     def getCpuList(self, **filters) -> List[ocloudModel.StxGenericModel]:
553         hostid = filters.get('hostid', None)
554         assert (hostid is not None), 'missing hostid to query icpu list'
555         cpulist = self.stxclient.icpu.list(hostid)
556         return [ocloudModel.StxGenericModel(
557             ResourceTypeEnum.PSERVER_CPU,
558             self._cpuconverter(cpures)) for cpures in cpulist if cpures]
559
560     def getCpu(self, id) -> ocloudModel.StxGenericModel:
561         cpuinfo = self.stxclient.icpu.get(id)
562         return ocloudModel.StxGenericModel(
563             ResourceTypeEnum.PSERVER_CPU, self._cpuconverter(cpuinfo))
564
565     def getMemList(self, **filters) -> List[ocloudModel.StxGenericModel]:
566         hostid = filters.get('hostid', None)
567         assert (hostid is not None), 'missing hostid to query imem list'
568         memlist = self.stxclient.imemory.list(hostid)
569         return [ocloudModel.StxGenericModel(
570             ResourceTypeEnum.PSERVER_RAM,
571             self._memconverter(memories)) for memories in memlist if memories]
572
573     def getMem(self, id) -> ocloudModel.StxGenericModel:
574         meminfo = self.stxclient.imemory.get(id)
575         return ocloudModel.StxGenericModel(
576             ResourceTypeEnum.PSERVER_RAM, self._memconverter(meminfo))
577
578     def getEthernetList(self, **filters) -> List[ocloudModel.StxGenericModel]:
579         hostid = filters.get('hostid', None)
580         assert (hostid is not None), 'missing hostid to query port list'
581         ethlist = self.stxclient.ethernet_port.list(hostid)
582         return [ocloudModel.StxGenericModel(
583             ResourceTypeEnum.PSERVER_ETH,
584             self._ethconverter(eth)) for eth in ethlist if eth]
585
586     def getEthernet(self, id) -> ocloudModel.StxGenericModel:
587         ethinfo = self.stxclient.ethernet_port.get(id)
588         return ocloudModel.StxGenericModel(
589             ResourceTypeEnum.PSERVER_ETH, self._ethconverter(ethinfo))
590
591     def getIfList(self, **filters) -> List[ocloudModel.StxGenericModel]:
592         hostid = filters.get('hostid', None)
593         assert (hostid is not None), 'missing hostid to query iinterface list'
594         iflist = self.stxclient.iinterface.list(hostid)
595         return [ocloudModel.StxGenericModel(
596             ResourceTypeEnum.PSERVER_IF,
597             self._ifconverter(ifs)) for ifs in iflist if ifs]
598
599     def getIf(self, id) -> ocloudModel.StxGenericModel:
600         ifinfo = self.stxclient.iinterface.get(id)
601         return ocloudModel.StxGenericModel(
602             ResourceTypeEnum.PSERVER_IF, self._ifconverter(ifinfo))
603
604     def getPortList(self, **filters) -> List[ocloudModel.StxGenericModel]:
605         ifid = filters.get('interfaceid', None)
606         assert (ifid is not None), 'missing interface id to query port list'
607         portlist = self.stxclient.iinterface.list_ports(ifid)
608         return [ocloudModel.StxGenericModel(
609             ResourceTypeEnum.PSERVER_IF_PORT,
610             port) for port in portlist if port]
611
612     def getPort(self, id) -> ocloudModel.StxGenericModel:
613         portinfo = self.stxclient.port.get(id)
614         return ocloudModel.StxGenericModel(
615             ResourceTypeEnum.PSERVER_IF_PORT, portinfo)
616
617     def getDeviceList(self, **filters) -> List[ocloudModel.StxGenericModel]:
618         hostid = filters.get('hostid', None)
619         assert (hostid is not None), 'missing hostid to query pci device list'
620         pci_dev_list = self.stxclient.pci_device.list(hostid)
621         return [ocloudModel.StxGenericModel(
622             ResourceTypeEnum.PSERVER_PCI_DEV,
623             self._devconverter(pci_dev))
624             for pci_dev in pci_dev_list if pci_dev]
625
626     def getDevice(self, id) -> ocloudModel.StxGenericModel:
627         pciinfo = self.stxclient.pci_device.get(id)
628         return ocloudModel.StxGenericModel(
629             ResourceTypeEnum.PSERVER_PCI_DEV, self._devconverter(pciinfo))
630
631     def getAcceleratorList(self, **filters) -> \
632             List[ocloudModel.StxGenericModel]:
633         hostid = filters.get('hostid', None)
634         assert (hostid is not None), 'missing hostid to query accelerator list'
635         pci_dev_list = self.stxclient.pci_device.list(hostid)
636         acc_list = []
637         for pci_dev in pci_dev_list:
638             if pci_dev.pvendor_id in ['8086']:
639                 if pci_dev.pdevice_id in ['0d5c', '0d5d']:
640                     logger.info('Accelerator vendor ID: {}, device ID: {}'.
641                                 format(pci_dev.pvendor_id, pci_dev.pdevice_id))
642                     acc_list.append(ocloudModel.StxGenericModel(
643                         ResourceTypeEnum.PSERVER_ACC,
644                         self._devconverter(pci_dev)))
645         return acc_list
646
647     def getAccelerator(self, id) -> ocloudModel.StxGenericModel:
648         pciinfo = self.stxclient.pci_device.get(id)
649         return ocloudModel.StxGenericModel(
650             ResourceTypeEnum.PSERVER_ACC, self._devconverter(pciinfo))
651
652     def _getIsystems(self):
653         return self.stxclient.isystem.list()
654
655     def _getIsystem(self, id=None):
656         if id:
657             return self.stxclient.isystem.get(id)
658         else:
659             isystems = self.stxclient.isystem.list()
660             if len(isystems) != 1 and not id:
661                 raise Exception('No system uuid was provided and '
662                                 'more than one system exists in the account.')
663             return isystems[0]
664
665     @staticmethod
666     def _respoolconverter(res_pool):
667         setattr(res_pool, 'name', res_pool.region_name)
668         return res_pool
669
670     @staticmethod
671     def _hostconverter(host):
672         selected_keys = [
673             "hostname", "personality", "id", "mgmt_ip", "mgmt_mac",
674             "software_load", "capabilities",
675             "operational", "availability", "administrative",
676             "boot_device", "rootfs_device", "install_state", "subfunctions",
677             "clock_synchronization", "max_cpu_mhz_allowed"
678         ]
679         content = host.to_dict()
680         filtered = dict(
681             filter(lambda item: item[0] in selected_keys, content.items()))
682         setattr(host, 'filtered', filtered)
683         setattr(host, 'name', host.hostname)
684         return host
685
686     @staticmethod
687     def _labelconverter(label):
688         selected_keys = [
689             "uuid", "label_key", "label_value", "host_uuid"
690         ]
691         content = label.to_dict()
692         print(content)
693         filtered = dict(
694             filter(lambda item: item[0] in selected_keys, content.items()))
695         setattr(label, 'filtered', filtered)
696         setattr(label, 'name', label.uuid.split(
697             '-', 1)[0] + '-label-' + label.label_key)
698         setattr(label, 'updated_at', None)
699         setattr(label, 'created_at', None)
700         return label
701
702     @staticmethod
703     def _cpuconverter(cpu):
704         selected_keys = [
705             "cpu", "core", "thread", "allocated_function", "numa_node",
706             "cpu_model", "cpu_family"
707         ]
708         content = cpu.to_dict()
709         filtered = dict(
710             filter(lambda item: item[0] in selected_keys, content.items()))
711         setattr(cpu, 'filtered', filtered)
712         setattr(cpu, 'name', cpu.ihost_uuid.split(
713             '-', 1)[0] + '-cpu-'+str(cpu.cpu))
714         return cpu
715
716     @staticmethod
717     def _memconverter(mem):
718         selected_keys = [
719             "memtotal_mib", "memavail_mib", "vm_hugepages_use_1G",
720             "vm_hugepages_possible_1G", "hugepages_configured",
721             "vm_hugepages_avail_1G", "vm_hugepages_nr_1G",
722             "vm_hugepages_nr_4K", "vm_hugepages_nr_2M",
723             "vm_hugepages_possible_2M", "vm_hugepages_avail_2M",
724             "platform_reserved_mib", "numa_node"
725         ]
726         content = mem.to_dict()
727         filtered = dict(
728             filter(lambda item: item[0] in selected_keys, content.items()))
729         setattr(mem, 'filtered', filtered)
730         setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] +
731                 '-mem-node-'+str(mem.numa_node))
732         return mem
733
734     @staticmethod
735     def _ethconverter(eth):
736         selected_keys = [
737             "name", "namedisplay", "dev_id", "pdevice", "capabilities",
738             "type", "driver", "mac", "numa_node",
739             "pciaddr", "pclass", "psvendor", "psdevice",
740             "sriov_totalvfs", "sriov_numvfs", "dpdksupport",
741             "sriov_vf_driver", "sriov_vf_pdevice_id", "interface_uuid"
742         ]
743         content = eth.to_dict()
744         filtered = dict(
745             filter(lambda item: item[0] in selected_keys, content.items()))
746         setattr(eth, 'filtered', filtered)
747         setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name)
748         setattr(eth, 'updated_at', None)
749         setattr(eth, 'created_at', None)
750         return eth
751
752     @staticmethod
753     def _ifconverter(ifs):
754         selected_keys = [
755             "ifname", "iftype", "imac", "vlan_id", "imtu",
756             "ifclass", "uses", "max_tx_rate",
757             "sriov_vf_driver", "sriov_numvfs", "ptp_role"
758         ]
759         content = ifs.to_dict()
760         filtered = dict(
761             filter(lambda item: item[0] in selected_keys, content.items()))
762         setattr(ifs, 'filtered', filtered)
763         setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname)
764         setattr(ifs, 'updated_at', None)
765         setattr(ifs, 'created_at', None)
766         return ifs
767
768     @staticmethod
769     def _devconverter(dev):
770         selected_keys = [
771             "name", "pdevice", "pciaddr", "pvendor_id", "pvendor",
772             "pclass_id", "pclass", "psvendor", "psdevice",
773             "sriov_totalvfs", "sriov_numvfs", "numa_node"
774         ]
775         content = dev.to_dict()
776         filtered = dict(
777             filter(lambda item: item[0] in selected_keys, content.items()))
778         setattr(dev, 'filtered', filtered)
779         setattr(dev, 'name', dev.host_uuid.split('-', 1)[0] + '-'+dev.name)
780         return dev
781
782     @staticmethod
783     def _k8sconverter(cluster):
784         setattr(cluster, 'name', cluster.cloud_name +
785                 '.' + cluster.cluster_name)
786         setattr(cluster, 'uuid',
787                 uuid.uuid3(uuid.NAMESPACE_URL, cluster.cloud_uuid))
788         setattr(cluster, 'updated_at', None)
789         setattr(cluster, 'created_at', None)
790         setattr(cluster, 'events', [])
791         logger.debug('k8s cluster name/uuid:' +
792                      cluster.name + '/' + str(cluster.uuid))
793         return cluster
794
795     @staticmethod
796     def _k8shasher(cluster):
797         return str(hash((cluster.cluster_name, cluster.cloud_name,
798                          cluster.cluster_api_endpoint, cluster.admin_user,
799                          cluster.capabilities)))