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 o2common.service.client.base_client import BaseClient
19 from typing import List
21 from o2ims.domain import stx_object as ocloudModel
22 from o2common.config import config
23 from o2ims.domain.resource_type import ResourceTypeEnum
25 # from dcmanagerclient.api import client
26 from cgtsclient.client import get_client as get_stx_client
27 from cgtsclient.exc import EndpointException
28 from dcmanagerclient.api.client import client as get_dc_client
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 filters['resourcepoolid']
93 return self.driver.getPserverList(**filters)
95 def _set_stx_client(self):
96 self.driver.setStxClient(self._pool_id)
99 class StxCpuClient(BaseClient):
102 # self._pserver_id = pserver_id
103 self.driver = StxClientImp()
105 def _get(self, id) -> ocloudModel.StxGenericModel:
106 return self.driver.getCpu(id)
108 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
109 return self.driver.getCpuList(**filters)
111 def _set_stx_client(self):
112 self.driver.setStxClient(self._pool_id)
115 class StxMemClient(BaseClient):
118 self.driver = StxClientImp()
120 def _get(self, id) -> ocloudModel.StxGenericModel:
121 return self.driver.getMem(id)
123 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
124 return self.driver.getMemList(**filters)
126 def _set_stx_client(self):
127 self.driver.setStxClient(self._pool_id)
130 class StxEthClient(BaseClient):
133 self.driver = StxClientImp()
135 def _get(self, id) -> ocloudModel.StxGenericModel:
136 return self.driver.getEthernet(id)
138 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
139 return self.driver.getEthernetList(**filters)
141 def _set_stx_client(self):
142 self.driver.setStxClient(self._pool_id)
145 class StxIfClient(BaseClient):
148 self.driver = StxClientImp()
150 def _get(self, id) -> ocloudModel.StxGenericModel:
151 return self.driver.getIf(id)
153 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
154 return self.driver.getIfList(**filters)
156 def _set_stx_client(self):
157 self.driver.setStxClient(self._pool_id)
160 class StxIfPortClient(BaseClient):
163 self.driver = StxClientImp()
165 def _get(self, id) -> ocloudModel.StxGenericModel:
166 return self.driver.getPort(id)
168 def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
169 return self.driver.getPortList(**filters)
171 def _set_stx_client(self):
172 self.driver.setStxClient(self._pool_id)
175 # internal driver which implement client call to Stx Standalone instance
176 class StxClientImp(object):
177 def __init__(self, stx_client=None, dc_client=None):
179 self.stxclient = stx_client if stx_client else self.getStxClient()
180 self.dcclient = dc_client if dc_client else self.getDcmanagerClient()
181 # if subcloud_id is not None:
182 # self.stxclient = self.getSubcloudClient(subcloud_id)
184 def getStxClient(self):
185 os_client_args = config.get_stx_access_info()
186 config_client = get_stx_client(**os_client_args)
189 def getDcmanagerClient(self):
190 os_client_args = config.get_dc_access_info()
191 config_client = get_dc_client(**os_client_args)
194 def getSubcloudClient(self, subcloud_id):
195 subcloud = self.dcclient.subcloud_manager.\
196 subcloud_additional_details(subcloud_id)
197 logger.debug('subcloud name: %s, oam_floating_ip: %s' %
198 (subcloud[0].name, subcloud[0].oam_floating_ip))
200 os_client_args = config.get_stx_access_info(
201 region_name=subcloud[0].name,
202 subcloud_hostname=subcloud[0].oam_floating_ip)
203 logger.warning(os_client_args)
204 config_client = get_stx_client(**os_client_args)
205 except EndpointException as e:
206 msg = e.format_message()
207 if CGTSCLIENT_ENDPOINT_ERROR_MSG in msg:
208 os_client_args = config.get_stx_access_info(
209 region_name=subcloud[0].name, sub_is_https=True,
210 subcloud_hostname=subcloud[0].oam_floating_ip)
211 logger.warning(os_client_args)
212 config_client = get_stx_client(**os_client_args)
214 raise ValueError('Stx endpoint exception: %s' % msg)
216 raise ValueError('cgtsclient get subcloud client failed')
219 def setStxClient(self, resource_pool_id):
220 systems = self.stxclient.isystem.list()
221 if resource_pool_id == systems[0].uuid:
222 logger.debug('Stx Client not change: %s' % resource_pool_id)
225 subclouds = self.getSubcloudList()
226 for subcloud in subclouds:
227 subcloud_stxclient = self.getSubcloudClient(subcloud.subcloud_id)
228 systems = subcloud_stxclient.isystem.list()
229 # logger.debug('subcloud %s id: %s' %
230 # (systems[0].name, systems[0].uuid))
231 # logger.debug('subcloud: %s' % (systems[0].to_dict()))
232 if resource_pool_id == systems[0].uuid:
233 self.stxclient = subcloud_stxclient
235 def getInstanceInfo(self) -> ocloudModel.StxGenericModel:
236 systems = self.stxclient.isystem.list()
237 logger.debug('systems:' + str(systems[0].to_dict()))
238 # logger.debug('systems[0] uuid: ' + str(systems[0].uuid))
239 return ocloudModel.StxGenericModel(
240 ResourceTypeEnum.OCLOUD, systems[0]) if systems else None
242 def getSubcloudList(self):
243 subs = self.dcclient.subcloud_manager.list_subclouds()
244 known_subs = [sub for sub in subs if sub.sync_status != 'unknown']
247 def getResourcePoolList(self, **filters) -> List[
248 ocloudModel.StxGenericModel]:
249 systems = self.stxclient.isystem.list()
250 logger.debug('system controller distributed_cloud_role:' +
251 str(systems[0].distributed_cloud_role))
253 if systems[0].distributed_cloud_role is None or \
254 systems[0].distributed_cloud_role != 'systemcontroller':
255 return [ocloudModel.StxGenericModel(
256 ResourceTypeEnum.RESOURCE_POOL, systems[0])]
259 if config.get_system_controller_as_respool():
260 pools.append(systems[0])
262 subclouds = self.getSubcloudList()
263 logger.debug('subclouds numbers: %s' % len(subclouds))
264 for subcloud in subclouds:
266 subcloud_stxclient = self.getSubcloudClient(
267 subcloud.subcloud_id)
268 systems = subcloud_stxclient.isystem.list()
269 logger.debug('systems:' + str(systems[0].to_dict()))
270 pools.append(systems[0])
271 except Exception as ex:
272 logger.warning('Failed get cgstclient of subcloud %s: %s' %
276 return [ocloudModel.StxGenericModel(
277 ResourceTypeEnum.RESOURCE_POOL,
278 respool) for respool in pools if respool]
280 def getResourcePoolDetail(self, id):
281 self.setStxClient(id)
282 systems = self.stxclient.isystem.list()
283 logger.debug('systems:' + str(systems[0].to_dict()))
284 return ocloudModel.StxGenericModel(
285 ResourceTypeEnum.RESOURCE_POOL, systems[0]) if systems else None
287 def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]:
288 hosts = self.stxclient.ihost.list()
289 logger.debug('host 1:' + str(hosts[0].to_dict()))
290 return [ocloudModel.StxGenericModel(
291 ResourceTypeEnum.PSERVER, self._hostconverter(host))
292 for host in hosts if host and (host.availability == 'available'
293 or host.availability == 'degraded')]
295 def getPserver(self, id) -> ocloudModel.StxGenericModel:
296 host = self.stxclient.ihost.get(id)
297 logger.debug('host:' + str(host.to_dict()))
298 return ocloudModel.StxGenericModel(
299 ResourceTypeEnum.PSERVER, self._hostconverter(host))
301 def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]:
302 systems = self.stxclient.isystem.list()
303 logger.debug('system controller distributed_cloud_role:' +
304 str(systems[0].distributed_cloud_role))
306 if systems[0].distributed_cloud_role is None or \
307 systems[0].distributed_cloud_role != 'systemcontroller':
308 k8sclusters = self.stxclient.kube_cluster.list()
309 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
310 logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict()))
311 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
312 # str(k8sclusters[0].cluster_api_endpoint))
313 return [ocloudModel.StxGenericModel(
314 ResourceTypeEnum.DMS,
315 self._k8sconverter(k8sres), self._k8shasher(k8sres))
316 for k8sres in k8sclusters if k8sres]
319 if config.get_system_controller_as_respool():
320 k8sclusters = self.stxclient.kube_cluster.list()
321 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
322 logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict()))
323 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
324 # str(k8sclusters[0].cluster_api_endpoint))
325 k8s_list.append(k8sclusters[0])
327 subclouds = self.getSubcloudList()
328 logger.debug('subclouds numbers: %s' % len(subclouds))
329 for subcloud in subclouds:
331 subcloud_stxclient = self.getSubcloudClient(
332 subcloud.subcloud_id)
333 systems = subcloud_stxclient.isystem.list()
334 k8sclusters = subcloud_stxclient.kube_cluster.list()
335 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
336 logger.debug('k8sresources[0]:' +
337 str(k8sclusters[0].to_dict()))
338 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
339 # str(k8sclusters[0].cluster_api_endpoint))
340 k8s_list.append(k8sclusters[0])
341 except Exception as ex:
342 logger.warning('Failed get cgstclient of subcloud %s: %s' %
346 return [ocloudModel.StxGenericModel(ResourceTypeEnum.DMS,
347 self._k8sconverter(k8sres), self._k8shasher(k8sres))
348 for k8sres in k8s_list if k8sres]
350 def getK8sDetail(self, name) -> ocloudModel.StxGenericModel:
351 systems = self.stxclient.isystem.list()
353 k8sclusters = self.stxclient.kube_cluster.list()
354 # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict()))
355 setattr(k8sclusters[0], 'cloud_name', systems[0].name)
356 k8scluster = k8sclusters.pop()
358 sname = name.split('.')
359 cloud_name = '.'.join(sname[:-1])
361 if cloud_name == systems[0].name:
362 k8scluster = self.stxclient.kube_cluster.get(k8s_name)
363 setattr(k8scluster, 'cloud_name', cloud_name)
365 subclouds = self.getSubcloudList()
367 sub.subcloud_id for sub in subclouds
368 if sub.name == cloud_name][0]
369 subcloud_stxclient = self.getSubcloudClient(subcloud_id)
370 k8scluster = subcloud_stxclient.kube_cluster.get(k8s_name)
371 setattr(k8scluster, 'cloud_name', cloud_name)
372 # logger.debug('k8sresources[0]:' +
373 # str(k8sclusters[0].to_dict()))
374 # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
375 # str(k8sclusters[0].cluster_api_endpoint))
379 logger.debug('k8sresource:' + str(k8scluster.to_dict()))
380 return ocloudModel.StxGenericModel(
381 ResourceTypeEnum.DMS,
382 self._k8sconverter(k8scluster), self._k8shasher(k8scluster))
384 def getCpuList(self, **filters) -> List[ocloudModel.StxGenericModel]:
385 hostid = filters.get('hostid', None)
386 assert (hostid is not None), 'missing hostid to query icpu list'
387 cpulist = self.stxclient.icpu.list(hostid)
388 return [ocloudModel.StxGenericModel(
389 ResourceTypeEnum.PSERVER_CPU,
390 self._cpuconverter(cpures)) for cpures in cpulist if cpures]
392 def getCpu(self, id) -> ocloudModel.StxGenericModel:
393 cpuinfo = self.stxclient.icpu.get(id)
394 return ocloudModel.StxGenericModel(
395 ResourceTypeEnum.PSERVER_CPU, self._cpuconverter(cpuinfo))
397 def getMemList(self, **filters) -> List[ocloudModel.StxGenericModel]:
398 hostid = filters.get('hostid', None)
399 assert (hostid is not None), 'missing hostid to query imem list'
400 memlist = self.stxclient.imemory.list(hostid)
401 return [ocloudModel.StxGenericModel(
402 ResourceTypeEnum.PSERVER_RAM,
403 self._memconverter(memories)) for memories in memlist if memories]
405 def getMem(self, id) -> ocloudModel.StxGenericModel:
406 meminfo = self.stxclient.imemory.get(id)
407 return ocloudModel.StxGenericModel(
408 ResourceTypeEnum.PSERVER_RAM, self._memconverter(meminfo))
410 def getEthernetList(self, **filters) -> List[ocloudModel.StxGenericModel]:
411 hostid = filters.get('hostid', None)
412 assert (hostid is not None), 'missing hostid to query port list'
413 ethlist = self.stxclient.ethernet_port.list(hostid)
414 return [ocloudModel.StxGenericModel(
415 ResourceTypeEnum.PSERVER_ETH,
416 self._ethconverter(eth)) for eth in ethlist if eth]
418 def getEthernet(self, id) -> ocloudModel.StxGenericModel:
419 ethinfo = self.stxclient.ethernet_port.get(id)
420 return ocloudModel.StxGenericModel(
421 ResourceTypeEnum.PSERVER_ETH, self._ethconverter(ethinfo))
423 def getIfList(self, **filters) -> List[ocloudModel.StxGenericModel]:
424 hostid = filters.get('hostid', None)
425 assert (hostid is not None), 'missing hostid to query iinterface list'
426 iflist = self.stxclient.iinterface.list(hostid)
427 return [ocloudModel.StxGenericModel(
428 ResourceTypeEnum.PSERVER_IF,
429 self._ifconverter(ifs)) for ifs in iflist if ifs]
431 def getIf(self, id) -> ocloudModel.StxGenericModel:
432 ifinfo = self.stxclient.iinterface.get(id)
433 return ocloudModel.StxGenericModel(
434 ResourceTypeEnum.PSERVER_IF, self._ifconverter(ifinfo))
436 def getPortList(self, **filters) -> List[ocloudModel.StxGenericModel]:
437 ifid = filters.get('interfaceid', None)
438 assert (ifid is not None), 'missing interface id to query port list'
439 portlist = self.stxclient.iinterface.list_ports(ifid)
440 return [ocloudModel.StxGenericModel(
441 ResourceTypeEnum.PSERVER_IF_PORT,
442 port) for port in portlist if port]
444 def getPort(self, id) -> ocloudModel.StxGenericModel:
445 portinfo = self.stxclient.port.get(id)
446 return ocloudModel.StxGenericModel(
447 ResourceTypeEnum.PSERVER_IF_PORT, portinfo)
449 def _getIsystems(self):
450 return self.stxclient.isystem.list()
452 def _getIsystem(self, id=None):
454 return self.stxclient.isystem.get(id)
456 isystems = self.stxclient.isystem.list()
457 if len(isystems) != 1 and not id:
458 raise Exception('No system uuid was provided and '
459 'more than one system exists in the account.')
463 def _hostconverter(host):
464 setattr(host, 'name', host.hostname)
468 def _cpuconverter(cpu):
469 setattr(cpu, 'name', cpu.ihost_uuid.split(
470 '-', 1)[0] + '-cpu-'+str(cpu.cpu))
474 def _memconverter(mem):
475 setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] +
476 '-mem-node-'+str(mem.numa_node))
480 def _ethconverter(eth):
481 setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name)
482 setattr(eth, 'updated_at', None)
483 setattr(eth, 'created_at', None)
487 def _ifconverter(ifs):
488 setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname)
489 setattr(ifs, 'updated_at', None)
490 setattr(ifs, 'created_at', None)
494 def _k8sconverter(cluster):
495 setattr(cluster, 'name', cluster.cloud_name +
496 '.' + cluster.cluster_name)
497 setattr(cluster, 'uuid',
498 uuid.uuid3(uuid.NAMESPACE_URL, cluster.name))
499 setattr(cluster, 'updated_at', None)
500 setattr(cluster, 'created_at', None)
501 setattr(cluster, 'events', [])
502 logger.debug('k8s cluster name/uuid:' +
503 cluster.name + '/' + str(cluster.uuid))
507 def _k8shasher(cluster):
508 return str(hash((cluster.cluster_name, cluster.cloud_name,
509 cluster.cluster_api_endpoint, cluster.admin_user)))