1 # Copyright (C) 2022 Wind River Systems, Inc.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # client talking to Stx standalone
18 from typing import List
21 from cgtsclient.client import get_client as get_stx_client
22 from cgtsclient.exc import EndpointException
23 from dcmanagerclient.api.client import client as get_dc_client
25 from o2common.config import config
26 from o2common.service.client.base_client import BaseClient
27 from o2ims.domain import stx_object as ocloudModel
28 from o2ims.domain.resource_type import ResourceTypeEnum
30 from o2common.helper import o2logging
31 logger = o2logging.get_logger(__name__)
34 CGTSCLIENT_ENDPOINT_ERROR_MSG = \
35 'Must provide Keystone credentials or user-defined endpoint and token'
38 class StxOcloudClient(BaseClient):
39 def __init__(self, driver=None):
41 self.driver = driver if driver else StxClientImp()
43 def _get(self, id) -> ocloudModel.StxGenericModel:
44 return self.driver.getInstanceInfo()
46 def _list(self, **filters):
47 return [self.driver.getInstanceInfo()]
49 def _set_stx_client(self):
53 class StxResourcePoolClient(BaseClient):
56 self.driver = StxClientImp()
58 def _get(self, id) -> ocloudModel.StxGenericModel:
59 return self.driver.getResourcePoolDetail(id)
61 def _list(self, **filters):
62 return self.driver.getResourcePoolList(**filters)
64 def _set_stx_client(self):
68 class StxDmsClient(BaseClient):
71 self.driver = StxClientImp()
73 def _get(self, name) -> ocloudModel.StxGenericModel:
74 return self.driver.getK8sDetail(name)
76 def _list(self, **filters):
77 return self.driver.getK8sList(**filters)
79 def _set_stx_client(self):
83 class StxPserverClient(BaseClient):
86 self.driver = StxClientImp()
88 def _get(self, id) -> ocloudModel.StxGenericModel:
89 return self.driver.getPserver(id)
91 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
92 return self.driver.getPserverList(**filters)
94 def _set_stx_client(self):
95 self.driver.setStxClient(self._pool_id)
98 class StxCpuClient(BaseClient):
101 # self._pserver_id = pserver_id
102 self.driver = StxClientImp()
104 def _get(self, id) -> ocloudModel.StxGenericModel:
105 return self.driver.getCpu(id)
107 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
108 return self.driver.getCpuList(**filters)
110 def _set_stx_client(self):
111 self.driver.setStxClient(self._pool_id)
114 class StxMemClient(BaseClient):
117 self.driver = StxClientImp()
119 def _get(self, id) -> ocloudModel.StxGenericModel:
120 return self.driver.getMem(id)
122 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
123 return self.driver.getMemList(**filters)
125 def _set_stx_client(self):
126 self.driver.setStxClient(self._pool_id)
129 class StxEthClient(BaseClient):
132 self.driver = StxClientImp()
134 def _get(self, id) -> ocloudModel.StxGenericModel:
135 return self.driver.getEthernet(id)
137 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
138 return self.driver.getEthernetList(**filters)
140 def _set_stx_client(self):
141 self.driver.setStxClient(self._pool_id)
144 class StxIfClient(BaseClient):
147 self.driver = StxClientImp()
149 def _get(self, id) -> ocloudModel.StxGenericModel:
150 return self.driver.getIf(id)
152 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
153 return self.driver.getIfList(**filters)
155 def _set_stx_client(self):
156 self.driver.setStxClient(self._pool_id)
159 class StxIfPortClient(BaseClient):
162 self.driver = StxClientImp()
164 def _get(self, id) -> ocloudModel.StxGenericModel:
165 return self.driver.getPort(id)
167 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
168 return self.driver.getPortList(**filters)
170 def _set_stx_client(self):
171 self.driver.setStxClient(self._pool_id)
174 class StxDevClient(BaseClient):
177 self.driver = StxClientImp()
179 def _get(self, id) -> ocloudModel.StxGenericModel:
180 return self.driver.getDevice(id)
182 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
183 return self.driver.getDeviceList(**filters)
185 def _set_stx_client(self):
186 self.driver.setStxClient(self._pool_id)
189 class StxAccClient(BaseClient):
192 self.driver = StxClientImp()
194 def _get(self, id) -> ocloudModel.StxGenericModel:
195 return self.driver.getAccelerator(id)
197 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
198 return self.driver.getAcceleratorList(**filters)
200 def _set_stx_client(self):
201 self.driver.setStxClient(self._pool_id)
204 # internal driver which implement client call to Stx Standalone and DC instance
205 class StxClientImp(object):
206 def __init__(self, stx_client=None, dc_client=None):
208 self.stxclient = stx_client if stx_client else self.getStxClient()
209 self.dcclient = dc_client if dc_client else self.getDcmanagerClient()
210 # if subcloud_id is not None:
211 # self.stxclient = self.getSubcloudClient(subcloud_id)
213 def getStxClient(self):
214 os_client_args = config.get_stx_access_info()
215 config_client = get_stx_client(**os_client_args)
218 def getDcmanagerClient(self):
219 os_client_args = config.get_dc_access_info()
220 config_client = get_dc_client(**os_client_args)
223 def getSubcloudClient(self, subcloud_id):
224 subcloud = self.dcclient.subcloud_manager.\
225 subcloud_additional_details(subcloud_id)
226 logger.debug('subcloud name: %s, oam_floating_ip: %s' %
227 (subcloud[0].name, subcloud[0].oam_floating_ip))
229 os_client_args = config.get_stx_access_info(
230 region_name=subcloud[0].name,
231 subcloud_hostname=subcloud[0].oam_floating_ip)
232 # logger.info(os_client_args)
233 config_client = get_stx_client(**os_client_args)
234 except EndpointException as e:
235 msg = e.format_message()
236 if CGTSCLIENT_ENDPOINT_ERROR_MSG in msg:
237 os_client_args = config.get_stx_access_info(
238 region_name=subcloud[0].name, sub_is_https=True,
239 subcloud_hostname=subcloud[0].oam_floating_ip)
240 # logger.info(os_client_args)
241 config_client = get_stx_client(**os_client_args)
243 raise ValueError('Stx endpoint exception: %s' % msg)
245 raise ValueError('cgtsclient get subcloud client failed')
249 def setStxClient(self, resource_pool_id):
250 systems = self.stxclient.isystem.list()
251 if resource_pool_id == systems[0].uuid:
252 logger.debug('Stx Client not change: %s' % resource_pool_id)
255 subclouds = self.getSubcloudList()
256 for subcloud in subclouds:
257 subcloud_stxclient = self.getSubcloudClient(subcloud.subcloud_id)
258 systems = subcloud_stxclient.isystem.list()
259 # logger.debug('subcloud %s id: %s' %
260 # (systems[0].name, systems[0].uuid))
261 # logger.debug('subcloud: %s' % (systems[0].to_dict()))
262 if resource_pool_id == systems[0].uuid:
263 self.stxclient = subcloud_stxclient
265 def getInstanceInfo(self) -> ocloudModel.StxGenericModel:
266 systems = self.stxclient.isystem.list()
267 logger.debug('systems:' + str(systems[0].to_dict()))
268 # logger.debug('systems[0] uuid: ' + str(systems[0].uuid))
269 return ocloudModel.StxGenericModel(
270 ResourceTypeEnum.OCLOUD, systems[0]) if systems else None
272 def getSubcloudList(self):
273 self.dcclient = self.getDcmanagerClient()
274 subs = self.dcclient.subcloud_manager.list_subclouds()
275 known_subs = [sub for sub in subs if sub.sync_status != 'unknown']
278 def getResourcePoolList(self, **filters) -> List[
279 ocloudModel.StxGenericModel]:
280 systems = self.stxclient.isystem.list()
281 logger.debug('system controller distributed_cloud_role:' +
282 str(systems[0].distributed_cloud_role))
284 if systems[0].distributed_cloud_role is None or \
285 systems[0].distributed_cloud_role != 'systemcontroller':
286 return [ocloudModel.StxGenericModel(
287 ResourceTypeEnum.RESOURCE_POOL,
288 self._respoolconverter(systems[0]))]
291 if config.get_system_controller_as_respool():
292 pools.append(systems[0])
294 subclouds = self.getSubcloudList()
295 logger.debug('subclouds numbers: %s' % len(subclouds))
296 for subcloud in subclouds:
298 subcloud_stxclient = self.getSubcloudClient(
299 subcloud.subcloud_id)
300 systems = subcloud_stxclient.isystem.list()
301 logger.debug('systems:' + str(systems[0].to_dict()))
302 pools.append(systems[0])
303 except Exception as ex:
304 logger.warning('Failed get cgstclient of subcloud %s: %s' %
308 return [ocloudModel.StxGenericModel(
309 ResourceTypeEnum.RESOURCE_POOL,
310 self._respoolconverter(
311 respool)) for respool in pools if respool]
313 def getResourcePoolDetail(self, id):
314 self.setStxClient(id)
315 systems = self.stxclient.isystem.list()
316 logger.debug('systems:' + str(systems[0].to_dict()))
317 return ocloudModel.StxGenericModel(
318 ResourceTypeEnum.RESOURCE_POOL,
319 self._respoolconverter(systems[0])) if systems else None
321 def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]:
322 hosts = self.stxclient.ihost.list()
323 logger.debug('host 1:' + str(hosts[0].to_dict()))
324 return [ocloudModel.StxGenericModel(
325 ResourceTypeEnum.PSERVER, self._hostconverter(host))
326 for host in hosts if host and (host.availability == 'available'
327 or host.availability == 'online'
328 or host.availability == 'degraded')]
330 def getPserver(self, id) -> ocloudModel.StxGenericModel:
331 host = self.stxclient.ihost.get(id)
332 logger.debug('host:' + str(host.to_dict()))
333 return ocloudModel.StxGenericModel(
334 ResourceTypeEnum.PSERVER, self._hostconverter(host))
336 def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]:
337 systems = self.stxclient.isystem.list()
338 logger.debug('system controller distributed_cloud_role:' +
339 str(systems[0].distributed_cloud_role))
341 if systems[0].distributed_cloud_role is None or \
342 systems[0].distributed_cloud_role != 'systemcontroller':
343 k8sclusters = self.stxclient.kube_cluster.list()
344 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
345 logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict()))
346 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
347 # str(k8sclusters[0].cluster_api_endpoint))
348 return [ocloudModel.StxGenericModel(
349 ResourceTypeEnum.DMS,
350 self._k8sconverter(k8sres), self._k8shasher(k8sres))
351 for k8sres in k8sclusters if k8sres]
354 if config.get_system_controller_as_respool():
355 k8sclusters = self.stxclient.kube_cluster.list()
356 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
357 logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict()))
358 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
359 # str(k8sclusters[0].cluster_api_endpoint))
360 k8s_list.append(k8sclusters[0])
362 subclouds = self.getSubcloudList()
363 logger.debug('subclouds numbers: %s' % len(subclouds))
364 for subcloud in subclouds:
366 subcloud_stxclient = self.getSubcloudClient(
367 subcloud.subcloud_id)
368 systems = subcloud_stxclient.isystem.list()
369 k8sclusters = subcloud_stxclient.kube_cluster.list()
370 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
371 logger.debug('k8sresources[0]:' +
372 str(k8sclusters[0].to_dict()))
373 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
374 # str(k8sclusters[0].cluster_api_endpoint))
375 k8s_list.append(k8sclusters[0])
376 except Exception as ex:
377 logger.warning('Failed get cgstclient of subcloud %s: %s' %
381 return [ocloudModel.StxGenericModel(ResourceTypeEnum.DMS,
382 self._k8sconverter(k8sres), self._k8shasher(k8sres))
383 for k8sres in k8s_list if k8sres]
385 def getK8sDetail(self, name) -> ocloudModel.StxGenericModel:
386 systems = self.stxclient.isystem.list()
388 k8sclusters = self.stxclient.kube_cluster.list()
389 # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict()))
390 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
391 k8scluster = k8sclusters.pop()
393 sname = name.split('.')
394 cloud_name = '.'.join(sname[:-1])
396 if cloud_name == systems[0].name:
397 k8scluster = self.stxclient.kube_cluster.get(k8s_name)
398 setattr(k8scluster, 'cloud_name', cloud_name)
400 subclouds = self.getSubcloudList()
402 sub.subcloud_id for sub in subclouds
403 if sub.name == cloud_name][0]
404 subcloud_stxclient = self.getSubcloudClient(subcloud_id)
405 k8scluster = subcloud_stxclient.kube_cluster.get(k8s_name)
406 setattr(k8scluster, 'cloud_name', cloud_name)
407 # logger.debug('k8sresources[0]:' +
408 # str(k8sclusters[0].to_dict()))
409 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
410 # str(k8sclusters[0].cluster_api_endpoint))
414 logger.debug('k8sresource:' + str(k8scluster.to_dict()))
415 return ocloudModel.StxGenericModel(
416 ResourceTypeEnum.DMS,
417 self._k8sconverter(k8scluster), self._k8shasher(k8scluster))
419 def getCpuList(self, **filters) -> List[ocloudModel.StxGenericModel]:
420 hostid = filters.get('hostid', None)
421 assert (hostid is not None), 'missing hostid to query icpu list'
422 cpulist = self.stxclient.icpu.list(hostid)
423 return [ocloudModel.StxGenericModel(
424 ResourceTypeEnum.PSERVER_CPU,
425 self._cpuconverter(cpures)) for cpures in cpulist if cpures]
427 def getCpu(self, id) -> ocloudModel.StxGenericModel:
428 cpuinfo = self.stxclient.icpu.get(id)
429 return ocloudModel.StxGenericModel(
430 ResourceTypeEnum.PSERVER_CPU, self._cpuconverter(cpuinfo))
432 def getMemList(self, **filters) -> List[ocloudModel.StxGenericModel]:
433 hostid = filters.get('hostid', None)
434 assert (hostid is not None), 'missing hostid to query imem list'
435 memlist = self.stxclient.imemory.list(hostid)
436 return [ocloudModel.StxGenericModel(
437 ResourceTypeEnum.PSERVER_RAM,
438 self._memconverter(memories)) for memories in memlist if memories]
440 def getMem(self, id) -> ocloudModel.StxGenericModel:
441 meminfo = self.stxclient.imemory.get(id)
442 return ocloudModel.StxGenericModel(
443 ResourceTypeEnum.PSERVER_RAM, self._memconverter(meminfo))
445 def getEthernetList(self, **filters) -> List[ocloudModel.StxGenericModel]:
446 hostid = filters.get('hostid', None)
447 assert (hostid is not None), 'missing hostid to query port list'
448 ethlist = self.stxclient.ethernet_port.list(hostid)
449 return [ocloudModel.StxGenericModel(
450 ResourceTypeEnum.PSERVER_ETH,
451 self._ethconverter(eth)) for eth in ethlist if eth]
453 def getEthernet(self, id) -> ocloudModel.StxGenericModel:
454 ethinfo = self.stxclient.ethernet_port.get(id)
455 return ocloudModel.StxGenericModel(
456 ResourceTypeEnum.PSERVER_ETH, self._ethconverter(ethinfo))
458 def getIfList(self, **filters) -> List[ocloudModel.StxGenericModel]:
459 hostid = filters.get('hostid', None)
460 assert (hostid is not None), 'missing hostid to query iinterface list'
461 iflist = self.stxclient.iinterface.list(hostid)
462 return [ocloudModel.StxGenericModel(
463 ResourceTypeEnum.PSERVER_IF,
464 self._ifconverter(ifs)) for ifs in iflist if ifs]
466 def getIf(self, id) -> ocloudModel.StxGenericModel:
467 ifinfo = self.stxclient.iinterface.get(id)
468 return ocloudModel.StxGenericModel(
469 ResourceTypeEnum.PSERVER_IF, self._ifconverter(ifinfo))
471 def getPortList(self, **filters) -> List[ocloudModel.StxGenericModel]:
472 ifid = filters.get('interfaceid', None)
473 assert (ifid is not None), 'missing interface id to query port list'
474 portlist = self.stxclient.iinterface.list_ports(ifid)
475 return [ocloudModel.StxGenericModel(
476 ResourceTypeEnum.PSERVER_IF_PORT,
477 port) for port in portlist if port]
479 def getPort(self, id) -> ocloudModel.StxGenericModel:
480 portinfo = self.stxclient.port.get(id)
481 return ocloudModel.StxGenericModel(
482 ResourceTypeEnum.PSERVER_IF_PORT, portinfo)
484 def getDeviceList(self, **filters) -> List[ocloudModel.StxGenericModel]:
485 hostid = filters.get('hostid', None)
486 assert (hostid is not None), 'missing hostid to query pci device list'
487 pci_dev_list = self.stxclient.pci_device.list(hostid)
488 return [ocloudModel.StxGenericModel(
489 ResourceTypeEnum.PSERVER_PCI_DEV,
490 self._devconverter(pci_dev))
491 for pci_dev in pci_dev_list if pci_dev]
493 def getDevice(self, id) -> ocloudModel.StxGenericModel:
494 pciinfo = self.stxclient.pci_device.get(id)
495 return ocloudModel.StxGenericModel(
496 ResourceTypeEnum.PSERVER_PCI_DEV, self._devconverter(pciinfo))
498 def getAcceleratorList(self, **filters) -> \
499 List[ocloudModel.StxGenericModel]:
500 hostid = filters.get('hostid', None)
501 assert (hostid is not None), 'missing hostid to query accelerator list'
502 pci_dev_list = self.stxclient.pci_device.list(hostid)
504 for pci_dev in pci_dev_list:
505 if pci_dev.pvendor_id in ['8086']:
506 if pci_dev.pdevice_id in ['0d5c', '0d5d']:
507 logger.info('Accelerator vendor ID: {}, device ID: {}'.
508 format(pci_dev.pvendor_id, pci_dev.pdevice_id))
509 acc_list.append(ocloudModel.StxGenericModel(
510 ResourceTypeEnum.PSERVER_ACC,
511 self._devconverter(pci_dev)))
514 def getAccelerator(self, id) -> ocloudModel.StxGenericModel:
515 pciinfo = self.stxclient.pci_device.get(id)
516 return ocloudModel.StxGenericModel(
517 ResourceTypeEnum.PSERVER_ACC, self._devconverter(pciinfo))
519 def _getIsystems(self):
520 return self.stxclient.isystem.list()
522 def _getIsystem(self, id=None):
524 return self.stxclient.isystem.get(id)
526 isystems = self.stxclient.isystem.list()
527 if len(isystems) != 1 and not id:
528 raise Exception('No system uuid was provided and '
529 'more than one system exists in the account.')
533 def _respoolconverter(res_pool):
534 setattr(res_pool, 'name', res_pool.region_name)
538 def _hostconverter(host):
539 setattr(host, 'name', host.hostname)
543 def _cpuconverter(cpu):
544 setattr(cpu, 'name', cpu.ihost_uuid.split(
545 '-', 1)[0] + '-cpu-'+str(cpu.cpu))
549 def _memconverter(mem):
550 setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] +
551 '-mem-node-'+str(mem.numa_node))
555 def _ethconverter(eth):
556 setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name)
557 setattr(eth, 'updated_at', None)
558 setattr(eth, 'created_at', None)
562 def _ifconverter(ifs):
563 setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname)
564 setattr(ifs, 'updated_at', None)
565 setattr(ifs, 'created_at', None)
569 def _devconverter(dev):
570 setattr(dev, 'name', dev.host_uuid.split('-', 1)[0] + '-'+dev.name)
574 def _k8sconverter(cluster):
575 setattr(cluster, 'name', cluster.cloud_name +
576 '.' + cluster.cluster_name)
577 setattr(cluster, 'uuid',
578 uuid.uuid3(uuid.NAMESPACE_URL, cluster.name))
579 setattr(cluster, 'updated_at', None)
580 setattr(cluster, 'created_at', None)
581 setattr(cluster, 'events', [])
582 logger.debug('k8s cluster name/uuid:' +
583 cluster.name + '/' + str(cluster.uuid))
587 def _k8shasher(cluster):
588 return str(hash((cluster.cluster_name, cluster.cloud_name,
589 cluster.cluster_api_endpoint, cluster.admin_user)))