Fix the watcher not add the host resource in subcloud
[pti/o2.git] / o2ims / adapter / clients / ocloud_client.py
index d7abd87..9af3b7a 100644 (file)
@@ -24,12 +24,17 @@ from o2ims.domain.resource_type import ResourceTypeEnum
 
 # from dcmanagerclient.api import client
 from cgtsclient.client import get_client as get_stx_client
+from cgtsclient.exc import EndpointException
 from dcmanagerclient.api.client import client as get_dc_client
 
 from o2common.helper import o2logging
 logger = o2logging.get_logger(__name__)
 
 
+CGTSCLIENT_ENDPOINT_ERROR_MSG = \
+    'Must provide Keystone credentials or user-defined endpoint and token'
+
+
 class StxOcloudClient(BaseClient):
     def __init__(self, driver=None):
         super().__init__()
@@ -84,7 +89,6 @@ class StxPserverClient(BaseClient):
         return self.driver.getPserver(id)
 
     def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
-        filters['resourcepoolid']
         return self.driver.getPserverList(**filters)
 
     def _set_stx_client(self):
@@ -167,7 +171,37 @@ class StxIfPortClient(BaseClient):
         self.driver.setStxClient(self._pool_id)
 
 
-# internal driver which implement client call to Stx Standalone instance
+class StxDevClient(BaseClient):
+    def __init__(self):
+        super().__init__()
+        self.driver = StxClientImp()
+
+    def _get(self, id) -> ocloudModel.StxGenericModel:
+        return self.driver.getDevice(id)
+
+    def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
+        return self.driver.getDeviceList(**filters)
+
+    def _set_stx_client(self):
+        self.driver.setStxClient(self._pool_id)
+
+
+class StxAccClient(BaseClient):
+    def __init__(self):
+        super().__init__()
+        self.driver = StxClientImp()
+
+    def _get(self, id) -> ocloudModel.StxGenericModel:
+        return self.driver.getAccelerator(id)
+
+    def _list(self, **filters) -> List[ocloudModel.StxGenericModel]:
+        return self.driver.getAcceleratorList(**filters)
+
+    def _set_stx_client(self):
+        self.driver.setStxClient(self._pool_id)
+
+
+# internal driver which implement client call to Stx Standalone and DC instance
 class StxClientImp(object):
     def __init__(self, stx_client=None, dc_client=None):
         super().__init__()
@@ -191,10 +225,25 @@ class StxClientImp(object):
             subcloud_additional_details(subcloud_id)
         logger.debug('subcloud name: %s, oam_floating_ip: %s' %
                      (subcloud[0].name, subcloud[0].oam_floating_ip))
-        os_client_args = config.get_stx_access_info(
-            region_name=subcloud[0].name,
-            subcloud_hostname=subcloud[0].oam_floating_ip)
-        config_client = get_stx_client(**os_client_args)
+        try:
+            os_client_args = config.get_stx_access_info(
+                region_name=subcloud[0].name,
+                subcloud_hostname=subcloud[0].oam_floating_ip)
+            logger.info(os_client_args)
+            config_client = get_stx_client(**os_client_args)
+        except EndpointException as e:
+            msg = e.format_message()
+            if CGTSCLIENT_ENDPOINT_ERROR_MSG in msg:
+                os_client_args = config.get_stx_access_info(
+                    region_name=subcloud[0].name, sub_is_https=True,
+                    subcloud_hostname=subcloud[0].oam_floating_ip)
+                logger.info(os_client_args)
+                config_client = get_stx_client(**os_client_args)
+            else:
+                raise ValueError('Stx endpoint exception: %s' % msg)
+        except Exception:
+            raise ValueError('cgtsclient get subcloud client failed')
+
         return config_client
 
     def setStxClient(self, resource_pool_id):
@@ -234,7 +283,8 @@ class StxClientImp(object):
         if systems[0].distributed_cloud_role is None or \
                 systems[0].distributed_cloud_role != 'systemcontroller':
             return [ocloudModel.StxGenericModel(
-                ResourceTypeEnum.RESOURCE_POOL, systems[0])]
+                ResourceTypeEnum.RESOURCE_POOL,
+                self._respoolconverter(systems[0]))]
 
         pools = []
         if config.get_system_controller_as_respool():
@@ -243,8 +293,9 @@ class StxClientImp(object):
         subclouds = self.getSubcloudList()
         logger.debug('subclouds numbers: %s' % len(subclouds))
         for subcloud in subclouds:
-            subcloud_stxclient = self.getSubcloudClient(subcloud.subcloud_id)
             try:
+                subcloud_stxclient = self.getSubcloudClient(
+                    subcloud.subcloud_id)
                 systems = subcloud_stxclient.isystem.list()
                 logger.debug('systems:' + str(systems[0].to_dict()))
                 pools.append(systems[0])
@@ -255,14 +306,16 @@ class StxClientImp(object):
 
         return [ocloudModel.StxGenericModel(
             ResourceTypeEnum.RESOURCE_POOL,
-            respool) for respool in pools if respool]
+                self._respoolconverter(
+                    respool)) for respool in pools if respool]
 
     def getResourcePoolDetail(self, id):
         self.setStxClient(id)
         systems = self.stxclient.isystem.list()
         logger.debug('systems:' + str(systems[0].to_dict()))
         return ocloudModel.StxGenericModel(
-            ResourceTypeEnum.RESOURCE_POOL, systems[0]) if systems else None
+            ResourceTypeEnum.RESOURCE_POOL,
+            self._respoolconverter(systems[0])) if systems else None
 
     def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]:
         hosts = self.stxclient.ihost.list()
@@ -270,6 +323,7 @@ class StxClientImp(object):
         return [ocloudModel.StxGenericModel(
             ResourceTypeEnum.PSERVER, self._hostconverter(host))
             for host in hosts if host and (host.availability == 'available'
+                                           or host.availability == 'online'
                                            or host.availability == 'degraded')]
 
     def getPserver(self, id) -> ocloudModel.StxGenericModel:
@@ -279,22 +333,80 @@ class StxClientImp(object):
             ResourceTypeEnum.PSERVER, self._hostconverter(host))
 
     def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]:
-        k8sclusters = self.stxclient.kube_cluster.list()
-        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))
-            for k8sres in k8sclusters if k8sres]
+        systems = self.stxclient.isystem.list()
+        logger.debug('system controller distributed_cloud_role:' +
+                     str(systems[0].distributed_cloud_role))
+
+        if systems[0].distributed_cloud_role is None or \
+                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))
+            return [ocloudModel.StxGenericModel(
+                ResourceTypeEnum.DMS,
+                self._k8sconverter(k8sres), self._k8shasher(k8sres))
+                for k8sres in k8sclusters if k8sres]
+
+        k8s_list = []
+        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))
+            k8s_list.append(k8sclusters[0])
+
+        subclouds = self.getSubcloudList()
+        logger.debug('subclouds numbers: %s' % len(subclouds))
+        for subcloud in subclouds:
+            try:
+                subcloud_stxclient = self.getSubcloudClient(
+                    subcloud.subcloud_id)
+                systems = subcloud_stxclient.isystem.list()
+                k8sclusters = subcloud_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))
+                k8s_list.append(k8sclusters[0])
+            except Exception as ex:
+                logger.warning('Failed get cgstclient of subcloud %s: %s' %
+                               (subcloud.name, ex))
+                continue
+
+        return [ocloudModel.StxGenericModel(ResourceTypeEnum.DMS,
+                self._k8sconverter(k8sres), self._k8shasher(k8sres))
+                for k8sres in k8s_list if k8sres]
 
     def getK8sDetail(self, name) -> ocloudModel.StxGenericModel:
+        systems = self.stxclient.isystem.list()
         if not name:
             k8sclusters = self.stxclient.kube_cluster.list()
             # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict()))
+            setattr(k8sclusters[0], 'cloud_name', systems[0].name)
             k8scluster = k8sclusters.pop()
         else:
-            k8scluster = self.stxclient.kube_cluster.get(name)
+            sname = name.split('.')
+            cloud_name = '.'.join(sname[:-1])
+            k8s_name = sname[-1]
+            if cloud_name == systems[0].name:
+                k8scluster = self.stxclient.kube_cluster.get(k8s_name)
+                setattr(k8scluster, 'cloud_name', cloud_name)
+            else:
+                subclouds = self.getSubcloudList()
+                subcloud_id = [
+                    sub.subcloud_id for sub in subclouds
+                    if sub.name == cloud_name][0]
+                subcloud_stxclient = self.getSubcloudClient(subcloud_id)
+                k8scluster = subcloud_stxclient.kube_cluster.get(k8s_name)
+                setattr(k8scluster, 'cloud_name', cloud_name)
+                # logger.debug('k8sresources[0]:' +
+                #  str(k8sclusters[0].to_dict()))
+                # logger.debug('k8sresources[0] cluster_api_endpoint: ' +
+                #  str(k8sclusters[0].cluster_api_endpoint))
 
         if not k8scluster:
             return None
@@ -368,6 +480,41 @@ class StxClientImp(object):
         return ocloudModel.StxGenericModel(
             ResourceTypeEnum.PSERVER_IF_PORT, portinfo)
 
+    def getDeviceList(self, **filters) -> List[ocloudModel.StxGenericModel]:
+        hostid = filters.get('hostid', None)
+        assert (hostid is not None), 'missing hostid to query pci device list'
+        pci_dev_list = self.stxclient.pci_device.list(hostid)
+        return [ocloudModel.StxGenericModel(
+            ResourceTypeEnum.PSERVER_PCI_DEV,
+            self._devconverter(pci_dev))
+            for pci_dev in pci_dev_list if pci_dev]
+
+    def getDevice(self, id) -> ocloudModel.StxGenericModel:
+        pciinfo = self.stxclient.pci_device.get(id)
+        return ocloudModel.StxGenericModel(
+            ResourceTypeEnum.PSERVER_PCI_DEV, self._devconverter(pciinfo))
+
+    def getAcceleratorList(self, **filters) -> \
+            List[ocloudModel.StxGenericModel]:
+        hostid = filters.get('hostid', None)
+        assert (hostid is not None), 'missing hostid to query accelerator list'
+        pci_dev_list = self.stxclient.pci_device.list(hostid)
+        acc_list = []
+        for pci_dev in pci_dev_list:
+            if pci_dev.pvendor_id in ['8086']:
+                if pci_dev.pdevice_id in ['0d5c', '0d5d']:
+                    logger.info('Accelerator vendor ID: {}, device ID: {}'.
+                                format(pci_dev.pvendor_id, pci_dev.pdevice_id))
+                    acc_list.append(ocloudModel.StxGenericModel(
+                        ResourceTypeEnum.PSERVER_ACC,
+                        self._devconverter(pci_dev)))
+        return acc_list
+
+    def getAccelerator(self, id) -> ocloudModel.StxGenericModel:
+        pciinfo = self.stxclient.pci_device.get(id)
+        return ocloudModel.StxGenericModel(
+            ResourceTypeEnum.PSERVER_ACC, self._devconverter(pciinfo))
+
     def _getIsystems(self):
         return self.stxclient.isystem.list()
 
@@ -381,6 +528,11 @@ class StxClientImp(object):
                                 'more than one system exists in the account.')
             return isystems[0]
 
+    @ staticmethod
+    def _respoolconverter(res_pool):
+        setattr(res_pool, 'name', res_pool.region_name)
+        return res_pool
+
     @ staticmethod
     def _hostconverter(host):
         setattr(host, 'name', host.hostname)
@@ -412,11 +564,17 @@ class StxClientImp(object):
         setattr(ifs, 'created_at', None)
         return ifs
 
+    @ staticmethod
+    def _devconverter(dev):
+        setattr(dev, 'name', dev.host_uuid.split('-', 1)[0] + '-'+dev.name)
+        return dev
+
     @ staticmethod
     def _k8sconverter(cluster):
-        setattr(cluster, 'name', cluster.cluster_name)
+        setattr(cluster, 'name', cluster.cloud_name +
+                '.' + cluster.cluster_name)
         setattr(cluster, 'uuid',
-                uuid.uuid3(uuid.NAMESPACE_URL, cluster.cluster_name))
+                uuid.uuid3(uuid.NAMESPACE_URL, cluster.name))
         setattr(cluster, 'updated_at', None)
         setattr(cluster, 'created_at', None)
         setattr(cluster, 'events', [])
@@ -426,5 +584,5 @@ class StxClientImp(object):
 
     @ staticmethod
     def _k8shasher(cluster):
-        return str(hash((cluster.cluster_name,
+        return str(hash((cluster.cluster_name, cluster.cloud_name,
                          cluster.cluster_api_endpoint, cluster.admin_user)))