d7abd87fc5750d505edf402265a94e84199207e9
[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 uuid
18 from o2common.service.client.base_client import BaseClient
19 from typing import List
20 # Optional,  Set
21 from o2ims.domain import stx_object as ocloudModel
22 from o2common.config import config
23 from o2ims.domain.resource_type import ResourceTypeEnum
24
25 # from dcmanagerclient.api import client
26 from cgtsclient.client import get_client as get_stx_client
27 from dcmanagerclient.api.client import client as get_dc_client
28
29 from o2common.helper import o2logging
30 logger = o2logging.get_logger(__name__)
31
32
33 class StxOcloudClient(BaseClient):
34     def __init__(self, driver=None):
35         super().__init__()
36         self.driver = driver if driver else StxClientImp()
37
38     def _get(self, id) -> ocloudModel.StxGenericModel:
39         return self.driver.getInstanceInfo()
40
41     def _list(self, **filters):
42         return [self.driver.getInstanceInfo()]
43
44     def _set_stx_client(self):
45         pass
46
47
48 class StxResourcePoolClient(BaseClient):
49     def __init__(self):
50         super().__init__()
51         self.driver = StxClientImp()
52
53     def _get(self, id) -> ocloudModel.StxGenericModel:
54         return self.driver.getResourcePoolDetail(id)
55
56     def _list(self, **filters):
57         return self.driver.getResourcePoolList(**filters)
58
59     def _set_stx_client(self):
60         pass
61
62
63 class StxDmsClient(BaseClient):
64     def __init__(self):
65         super().__init__()
66         self.driver = StxClientImp()
67
68     def _get(self, name) -> ocloudModel.StxGenericModel:
69         return self.driver.getK8sDetail(name)
70
71     def _list(self, **filters):
72         return self.driver.getK8sList(**filters)
73
74     def _set_stx_client(self):
75         pass
76
77
78 class StxPserverClient(BaseClient):
79     def __init__(self):
80         super().__init__()
81         self.driver = StxClientImp()
82
83     def _get(self, id) -> ocloudModel.StxGenericModel:
84         return self.driver.getPserver(id)
85
86     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
87         filters['resourcepoolid']
88         return self.driver.getPserverList(**filters)
89
90     def _set_stx_client(self):
91         self.driver.setStxClient(self._pool_id)
92
93
94 class StxCpuClient(BaseClient):
95     def __init__(self):
96         super().__init__()
97         # self._pserver_id = pserver_id
98         self.driver = StxClientImp()
99
100     def _get(self, id) -> ocloudModel.StxGenericModel:
101         return self.driver.getCpu(id)
102
103     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
104         return self.driver.getCpuList(**filters)
105
106     def _set_stx_client(self):
107         self.driver.setStxClient(self._pool_id)
108
109
110 class StxMemClient(BaseClient):
111     def __init__(self):
112         super().__init__()
113         self.driver = StxClientImp()
114
115     def _get(self, id) -> ocloudModel.StxGenericModel:
116         return self.driver.getMem(id)
117
118     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
119         return self.driver.getMemList(**filters)
120
121     def _set_stx_client(self):
122         self.driver.setStxClient(self._pool_id)
123
124
125 class StxEthClient(BaseClient):
126     def __init__(self):
127         super().__init__()
128         self.driver = StxClientImp()
129
130     def _get(self, id) -> ocloudModel.StxGenericModel:
131         return self.driver.getEthernet(id)
132
133     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
134         return self.driver.getEthernetList(**filters)
135
136     def _set_stx_client(self):
137         self.driver.setStxClient(self._pool_id)
138
139
140 class StxIfClient(BaseClient):
141     def __init__(self):
142         super().__init__()
143         self.driver = StxClientImp()
144
145     def _get(self, id) -> ocloudModel.StxGenericModel:
146         return self.driver.getIf(id)
147
148     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
149         return self.driver.getIfList(**filters)
150
151     def _set_stx_client(self):
152         self.driver.setStxClient(self._pool_id)
153
154
155 class StxIfPortClient(BaseClient):
156     def __init__(self):
157         super().__init__()
158         self.driver = StxClientImp()
159
160     def _get(self, id) -> ocloudModel.StxGenericModel:
161         return self.driver.getPort(id)
162
163     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
164         return self.driver.getPortList(**filters)
165
166     def _set_stx_client(self):
167         self.driver.setStxClient(self._pool_id)
168
169
170 # internal driver which implement client call to Stx Standalone instance
171 class StxClientImp(object):
172     def __init__(self, stx_client=None, dc_client=None):
173         super().__init__()
174         self.stxclient = stx_client if stx_client else self.getStxClient()
175         self.dcclient = dc_client if dc_client else self.getDcmanagerClient()
176         # if subcloud_id is not None:
177         # self.stxclient = self.getSubcloudClient(subcloud_id)
178
179     def getStxClient(self):
180         os_client_args = config.get_stx_access_info()
181         config_client = get_stx_client(**os_client_args)
182         return config_client
183
184     def getDcmanagerClient(self):
185         os_client_args = config.get_dc_access_info()
186         config_client = get_dc_client(**os_client_args)
187         return config_client
188
189     def getSubcloudClient(self, subcloud_id):
190         subcloud = self.dcclient.subcloud_manager.\
191             subcloud_additional_details(subcloud_id)
192         logger.debug('subcloud name: %s, oam_floating_ip: %s' %
193                      (subcloud[0].name, subcloud[0].oam_floating_ip))
194         os_client_args = config.get_stx_access_info(
195             region_name=subcloud[0].name,
196             subcloud_hostname=subcloud[0].oam_floating_ip)
197         config_client = get_stx_client(**os_client_args)
198         return config_client
199
200     def setStxClient(self, resource_pool_id):
201         systems = self.stxclient.isystem.list()
202         if resource_pool_id == systems[0].uuid:
203             logger.debug('Stx Client not change: %s' % resource_pool_id)
204             return
205
206         subclouds = self.getSubcloudList()
207         for subcloud in subclouds:
208             subcloud_stxclient = self.getSubcloudClient(subcloud.subcloud_id)
209             systems = subcloud_stxclient.isystem.list()
210             # logger.debug('subcloud %s id: %s' %
211             #  (systems[0].name, systems[0].uuid))
212             # logger.debug('subcloud: %s' % (systems[0].to_dict()))
213             if resource_pool_id == systems[0].uuid:
214                 self.stxclient = subcloud_stxclient
215
216     def getInstanceInfo(self) -> ocloudModel.StxGenericModel:
217         systems = self.stxclient.isystem.list()
218         logger.debug('systems:' + str(systems[0].to_dict()))
219         # logger.debug('systems[0] uuid: ' + str(systems[0].uuid))
220         return ocloudModel.StxGenericModel(
221             ResourceTypeEnum.OCLOUD, systems[0]) if systems else None
222
223     def getSubcloudList(self):
224         subs = self.dcclient.subcloud_manager.list_subclouds()
225         known_subs = [sub for sub in subs if sub.sync_status != 'unknown']
226         return known_subs
227
228     def getResourcePoolList(self, **filters) -> List[
229             ocloudModel.StxGenericModel]:
230         systems = self.stxclient.isystem.list()
231         logger.debug('system controller distributed_cloud_role:' +
232                      str(systems[0].distributed_cloud_role))
233
234         if systems[0].distributed_cloud_role is None or \
235                 systems[0].distributed_cloud_role != 'systemcontroller':
236             return [ocloudModel.StxGenericModel(
237                 ResourceTypeEnum.RESOURCE_POOL, systems[0])]
238
239         pools = []
240         if config.get_system_controller_as_respool():
241             pools.append(systems[0])
242
243         subclouds = self.getSubcloudList()
244         logger.debug('subclouds numbers: %s' % len(subclouds))
245         for subcloud in subclouds:
246             subcloud_stxclient = self.getSubcloudClient(subcloud.subcloud_id)
247             try:
248                 systems = subcloud_stxclient.isystem.list()
249                 logger.debug('systems:' + str(systems[0].to_dict()))
250                 pools.append(systems[0])
251             except Exception as ex:
252                 logger.warning('Failed get cgstclient of subcloud %s: %s' %
253                                (subcloud.name, ex))
254                 continue
255
256         return [ocloudModel.StxGenericModel(
257             ResourceTypeEnum.RESOURCE_POOL,
258             respool) for respool in pools if respool]
259
260     def getResourcePoolDetail(self, id):
261         self.setStxClient(id)
262         systems = self.stxclient.isystem.list()
263         logger.debug('systems:' + str(systems[0].to_dict()))
264         return ocloudModel.StxGenericModel(
265             ResourceTypeEnum.RESOURCE_POOL, systems[0]) if systems else None
266
267     def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]:
268         hosts = self.stxclient.ihost.list()
269         logger.debug('host 1:' + str(hosts[0].to_dict()))
270         return [ocloudModel.StxGenericModel(
271             ResourceTypeEnum.PSERVER, self._hostconverter(host))
272             for host in hosts if host and (host.availability == 'available'
273                                            or host.availability == 'degraded')]
274
275     def getPserver(self, id) -> ocloudModel.StxGenericModel:
276         host = self.stxclient.ihost.get(id)
277         logger.debug('host:' + str(host.to_dict()))
278         return ocloudModel.StxGenericModel(
279             ResourceTypeEnum.PSERVER, self._hostconverter(host))
280
281     def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]:
282         k8sclusters = self.stxclient.kube_cluster.list()
283         logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict()))
284         # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
285         #  str(k8sclusters[0].cluster_api_endpoint))
286         return [ocloudModel.StxGenericModel(
287             ResourceTypeEnum.DMS,
288             self._k8sconverter(k8sres), self._k8shasher(k8sres))
289             for k8sres in k8sclusters if k8sres]
290
291     def getK8sDetail(self, name) -> ocloudModel.StxGenericModel:
292         if not name:
293             k8sclusters = self.stxclient.kube_cluster.list()
294             # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict()))
295             k8scluster = k8sclusters.pop()
296         else:
297             k8scluster = self.stxclient.kube_cluster.get(name)
298
299         if not k8scluster:
300             return None
301         logger.debug('k8sresource:' + str(k8scluster.to_dict()))
302         return ocloudModel.StxGenericModel(
303             ResourceTypeEnum.DMS,
304             self._k8sconverter(k8scluster), self._k8shasher(k8scluster))
305
306     def getCpuList(self, **filters) -> List[ocloudModel.StxGenericModel]:
307         hostid = filters.get('hostid', None)
308         assert (hostid is not None), 'missing hostid to query icpu list'
309         cpulist = self.stxclient.icpu.list(hostid)
310         return [ocloudModel.StxGenericModel(
311             ResourceTypeEnum.PSERVER_CPU,
312             self._cpuconverter(cpures)) for cpures in cpulist if cpures]
313
314     def getCpu(self, id) -> ocloudModel.StxGenericModel:
315         cpuinfo = self.stxclient.icpu.get(id)
316         return ocloudModel.StxGenericModel(
317             ResourceTypeEnum.PSERVER_CPU, self._cpuconverter(cpuinfo))
318
319     def getMemList(self, **filters) -> List[ocloudModel.StxGenericModel]:
320         hostid = filters.get('hostid', None)
321         assert (hostid is not None), 'missing hostid to query imem list'
322         memlist = self.stxclient.imemory.list(hostid)
323         return [ocloudModel.StxGenericModel(
324             ResourceTypeEnum.PSERVER_RAM,
325             self._memconverter(memories)) for memories in memlist if memories]
326
327     def getMem(self, id) -> ocloudModel.StxGenericModel:
328         meminfo = self.stxclient.imemory.get(id)
329         return ocloudModel.StxGenericModel(
330             ResourceTypeEnum.PSERVER_RAM, self._memconverter(meminfo))
331
332     def getEthernetList(self, **filters) -> List[ocloudModel.StxGenericModel]:
333         hostid = filters.get('hostid', None)
334         assert (hostid is not None), 'missing hostid to query port list'
335         ethlist = self.stxclient.ethernet_port.list(hostid)
336         return [ocloudModel.StxGenericModel(
337             ResourceTypeEnum.PSERVER_ETH,
338             self._ethconverter(eth)) for eth in ethlist if eth]
339
340     def getEthernet(self, id) -> ocloudModel.StxGenericModel:
341         ethinfo = self.stxclient.ethernet_port.get(id)
342         return ocloudModel.StxGenericModel(
343             ResourceTypeEnum.PSERVER_ETH, self._ethconverter(ethinfo))
344
345     def getIfList(self, **filters) -> List[ocloudModel.StxGenericModel]:
346         hostid = filters.get('hostid', None)
347         assert (hostid is not None), 'missing hostid to query iinterface list'
348         iflist = self.stxclient.iinterface.list(hostid)
349         return [ocloudModel.StxGenericModel(
350             ResourceTypeEnum.PSERVER_IF,
351             self._ifconverter(ifs)) for ifs in iflist if ifs]
352
353     def getIf(self, id) -> ocloudModel.StxGenericModel:
354         ifinfo = self.stxclient.iinterface.get(id)
355         return ocloudModel.StxGenericModel(
356             ResourceTypeEnum.PSERVER_IF, self._ifconverter(ifinfo))
357
358     def getPortList(self, **filters) -> List[ocloudModel.StxGenericModel]:
359         ifid = filters.get('interfaceid', None)
360         assert (ifid is not None), 'missing interface id to query port list'
361         portlist = self.stxclient.iinterface.list_ports(ifid)
362         return [ocloudModel.StxGenericModel(
363             ResourceTypeEnum.PSERVER_IF_PORT,
364             port) for port in portlist if port]
365
366     def getPort(self, id) -> ocloudModel.StxGenericModel:
367         portinfo = self.stxclient.port.get(id)
368         return ocloudModel.StxGenericModel(
369             ResourceTypeEnum.PSERVER_IF_PORT, portinfo)
370
371     def _getIsystems(self):
372         return self.stxclient.isystem.list()
373
374     def _getIsystem(self, id=None):
375         if id:
376             return self.stxclient.isystem.get(id)
377         else:
378             isystems = self.stxclient.isystem.list()
379             if len(isystems) != 1 and not id:
380                 raise Exception('No system uuid was provided and '
381                                 'more than one system exists in the account.')
382             return isystems[0]
383
384     @ staticmethod
385     def _hostconverter(host):
386         setattr(host, 'name', host.hostname)
387         return host
388
389     @ staticmethod
390     def _cpuconverter(cpu):
391         setattr(cpu, 'name', cpu.ihost_uuid.split(
392             '-', 1)[0] + '-cpu-'+str(cpu.cpu))
393         return cpu
394
395     @ staticmethod
396     def _memconverter(mem):
397         setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] +
398                 '-mem-node-'+str(mem.numa_node))
399         return mem
400
401     @ staticmethod
402     def _ethconverter(eth):
403         setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name)
404         setattr(eth, 'updated_at', None)
405         setattr(eth, 'created_at', None)
406         return eth
407
408     @ staticmethod
409     def _ifconverter(ifs):
410         setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname)
411         setattr(ifs, 'updated_at', None)
412         setattr(ifs, 'created_at', None)
413         return ifs
414
415     @ staticmethod
416     def _k8sconverter(cluster):
417         setattr(cluster, 'name', cluster.cluster_name)
418         setattr(cluster, 'uuid',
419                 uuid.uuid3(uuid.NAMESPACE_URL, cluster.cluster_name))
420         setattr(cluster, 'updated_at', None)
421         setattr(cluster, 'created_at', None)
422         setattr(cluster, 'events', [])
423         logger.debug('k8s cluster name/uuid:' +
424                      cluster.name + '/' + str(cluster.uuid))
425         return cluster
426
427     @ staticmethod
428     def _k8shasher(cluster):
429         return str(hash((cluster.cluster_name,
430                          cluster.cluster_api_endpoint, cluster.admin_user)))