Update DeploymentManagerInfo attributes 62/12962/3
authorZhang Rong(Jon) <rong.zhang@windriver.com>
Thu, 13 Jun 2024 15:37:57 +0000 (23:37 +0800)
committerZhang Rong(Jon) <rong.zhang@windriver.com>
Thu, 20 Jun 2024 04:01:36 +0000 (12:01 +0800)
The April train release introduced a new spec to expand three attributes
of the DeploymentManager.

This commit implements these changes, adding the new attributes to the
DeploymentManager.

Test Plan:
1.Verified that the deployment manager list includes the new attributes
by default.
2.Verified that fetching a specific deployment manager responds as
expected.

Issue-ID: INF-468

Change-Id: I372f01fca970243d4b6421121b469786d5480e61
Signed-off-by: Zhang Rong(Jon) <rong.zhang@windriver.com>
o2app/entrypoints/redis_eventconsumer.py
o2ims/adapter/clients/fault_client.py
o2ims/adapter/clients/ocloud_client.py
o2ims/adapter/clients/ocloud_sa_client.py
o2ims/domain/alarm_obj.py
o2ims/domain/ocloud.py
o2ims/service/command/notify_handler.py
o2ims/views/ocloud_dto.py

index db39daa..8098d04 100644 (file)
@@ -23,7 +23,8 @@ from o2common.config import config
 from o2common.helper import o2logging
 from o2dms.domain import commands
 from o2ims.domain import commands as imscmd
 from o2common.helper import o2logging
 from o2dms.domain import commands
 from o2ims.domain import commands as imscmd
-from o2ims.domain.subscription_obj import Message2SMO, RegistrationMessage
+from o2ims.domain.subscription_obj import Message2SMO, RegistrationMessage, \
+    NotificationEventEnum
 from o2ims.domain.alarm_obj import AlarmEvent2SMO
 
 logger = o2logging.get_logger(__name__)
 from o2ims.domain.alarm_obj import AlarmEvent2SMO
 
 logger = o2logging.get_logger(__name__)
@@ -125,9 +126,17 @@ def handle_changed(m, bus):
         datastr = m['data']
         data = json.loads(datastr)
         logger.info('OcloudChanged with cmd:{}'.format(data))
         datastr = m['data']
         data = json.loads(datastr)
         logger.info('OcloudChanged with cmd:{}'.format(data))
-        cmd = imscmd.Register2SMO(data=RegistrationMessage(
-            id=data['id'], eventtype=data['notificationEventType'],
-            updatetime=data['updatetime']))
+        if data['notificationEventType'] == NotificationEventEnum.CREATE:
+            cmd = imscmd.Register2SMO(data=RegistrationMessage(
+                id=data['id'], eventtype=data['notificationEventType'],
+                updatetime=data['updatetime']))
+        elif data['notificationEventType'] == NotificationEventEnum.MODIFY:
+            ref = apibase + inventory_api_version
+            cmd = imscmd.PubMessage2SMO(data=Message2SMO(
+                id=data['id'], ref=ref,
+                eventtype=data['notificationEventType'],
+                updatetime=data['updatetime']),
+                type='OCloud')
         bus.handle(cmd)
     elif channel == 'AlarmEventChanged':
         datastr = m['data']
         bus.handle(cmd)
     elif channel == 'AlarmEventChanged':
         datastr = m['data']
@@ -145,7 +154,7 @@ def handle_changed(m, bus):
         data = json.loads(datastr)
         logger.info('AlarmEventPurged with cmd:{}'.format(data))
         cmd = imscmd.PurgeAlarmEvent(data=AlarmEvent2SMO(
         data = json.loads(datastr)
         logger.info('AlarmEventPurged with cmd:{}'.format(data))
         cmd = imscmd.PurgeAlarmEvent(data=AlarmEvent2SMO(
-            id=data['id'], eventtype=data['notificationEventType'],
+            id=data['id'], ref="", eventtype=data['notificationEventType'],
             updatetime=data['updatetime']))
         bus.handle(cmd)
     else:
             updatetime=data['updatetime']))
         bus.handle(cmd)
     else:
index 74abe57..616a4ca 100644 (file)
@@ -263,7 +263,7 @@ class StxFaultClientImp(object):
                         self._suppression_converter(event)))
         return suppression_list
 
                         self._suppression_converter(event)))
         return suppression_list
 
-    @ staticmethod
+    @staticmethod
     def _alarmconverter(alarm):
         selected_keys = [
             'alarm_id', 'alarm_state', 'entity_type_id', 'entity_instance_id',
     def _alarmconverter(alarm):
         selected_keys = [
             'alarm_id', 'alarm_state', 'entity_type_id', 'entity_instance_id',
@@ -285,7 +285,7 @@ class StxFaultClientImp(object):
                 uuid.NAMESPACE_URL, alarm.probable_cause)))
         return alarm
 
                 uuid.NAMESPACE_URL, alarm.probable_cause)))
         return alarm
 
-    @ staticmethod
+    @staticmethod
     def _eventconverter(event, clear=False):
         selected_keys = [
             'event_log_id', 'state', 'entity_type_id',
     def _eventconverter(event, clear=False):
         selected_keys = [
             'event_log_id', 'state', 'entity_type_id',
@@ -308,7 +308,7 @@ class StxFaultClientImp(object):
                 uuid.NAMESPACE_URL, event.probable_cause)))
         return event
 
                 uuid.NAMESPACE_URL, event.probable_cause)))
         return event
 
-    @ staticmethod
+    @staticmethod
     def _suppression_converter(event, clear=False):
         selected_keys = [
             'alarm_id', 'description', 'suppression_status',
     def _suppression_converter(event, clear=False):
         selected_keys = [
             'alarm_id', 'description', 'suppression_status',
@@ -329,7 +329,7 @@ class StxFaultClientImp(object):
         setattr(event, 'timestamp', None)
         return event
 
         setattr(event, 'timestamp', None)
         return event
 
-    @ staticmethod
+    @staticmethod
     def _alarmeventhasher(event, state=''):
         # The event model and the alarm model have different parameter name
         # of the state. alarm model is alarm_state, event model is state.
     def _alarmeventhasher(event, state=''):
         # The event model and the alarm model have different parameter name
         # of the state. alarm model is alarm_state, event model is state.
index 5a7b3fb..f601bbc 100644 (file)
@@ -591,12 +591,12 @@ class StxClientImp(object):
                                 'more than one system exists in the account.')
             return isystems[0]
 
                                 'more than one system exists in the account.')
             return isystems[0]
 
-    @ staticmethod
+    @staticmethod
     def _respoolconverter(res_pool):
         setattr(res_pool, 'name', res_pool.region_name)
         return res_pool
 
     def _respoolconverter(res_pool):
         setattr(res_pool, 'name', res_pool.region_name)
         return res_pool
 
-    @ staticmethod
+    @staticmethod
     def _hostconverter(host):
         selected_keys = [
             "hostname", "personality", "id", "mgmt_ip", "mgmt_mac",
     def _hostconverter(host):
         selected_keys = [
             "hostname", "personality", "id", "mgmt_ip", "mgmt_mac",
@@ -612,7 +612,7 @@ class StxClientImp(object):
         setattr(host, 'name', host.hostname)
         return host
 
         setattr(host, 'name', host.hostname)
         return host
 
-    @ staticmethod
+    @staticmethod
     def _labelconverter(label):
         selected_keys = [
             "uuid", "label_key", "label_value", "host_uuid"
     def _labelconverter(label):
         selected_keys = [
             "uuid", "label_key", "label_value", "host_uuid"
@@ -628,7 +628,7 @@ class StxClientImp(object):
         setattr(label, 'created_at', None)
         return label
 
         setattr(label, 'created_at', None)
         return label
 
-    @ staticmethod
+    @staticmethod
     def _cpuconverter(cpu):
         selected_keys = [
             "cpu", "core", "thread", "allocated_function", "numa_node",
     def _cpuconverter(cpu):
         selected_keys = [
             "cpu", "core", "thread", "allocated_function", "numa_node",
@@ -642,7 +642,7 @@ class StxClientImp(object):
             '-', 1)[0] + '-cpu-'+str(cpu.cpu))
         return cpu
 
             '-', 1)[0] + '-cpu-'+str(cpu.cpu))
         return cpu
 
-    @ staticmethod
+    @staticmethod
     def _memconverter(mem):
         selected_keys = [
             "memtotal_mib", "memavail_mib", "vm_hugepages_use_1G",
     def _memconverter(mem):
         selected_keys = [
             "memtotal_mib", "memavail_mib", "vm_hugepages_use_1G",
@@ -660,7 +660,7 @@ class StxClientImp(object):
                 '-mem-node-'+str(mem.numa_node))
         return mem
 
                 '-mem-node-'+str(mem.numa_node))
         return mem
 
-    @ staticmethod
+    @staticmethod
     def _ethconverter(eth):
         selected_keys = [
             "name", "namedisplay", "dev_id", "pdevice", "capabilities",
     def _ethconverter(eth):
         selected_keys = [
             "name", "namedisplay", "dev_id", "pdevice", "capabilities",
@@ -678,7 +678,7 @@ class StxClientImp(object):
         setattr(eth, 'created_at', None)
         return eth
 
         setattr(eth, 'created_at', None)
         return eth
 
-    @ staticmethod
+    @staticmethod
     def _ifconverter(ifs):
         selected_keys = [
             "ifname", "iftype", "imac", "vlan_id", "imtu",
     def _ifconverter(ifs):
         selected_keys = [
             "ifname", "iftype", "imac", "vlan_id", "imtu",
@@ -694,7 +694,7 @@ class StxClientImp(object):
         setattr(ifs, 'created_at', None)
         return ifs
 
         setattr(ifs, 'created_at', None)
         return ifs
 
-    @ staticmethod
+    @staticmethod
     def _devconverter(dev):
         selected_keys = [
             "name", "pdevice", "pciaddr", "pvendor_id", "pvendor",
     def _devconverter(dev):
         selected_keys = [
             "name", "pdevice", "pciaddr", "pvendor_id", "pvendor",
@@ -708,7 +708,7 @@ class StxClientImp(object):
         setattr(dev, 'name', dev.host_uuid.split('-', 1)[0] + '-'+dev.name)
         return dev
 
         setattr(dev, 'name', dev.host_uuid.split('-', 1)[0] + '-'+dev.name)
         return dev
 
-    @ staticmethod
+    @staticmethod
     def _k8sconverter(cluster):
         setattr(cluster, 'name', cluster.cloud_name +
                 '.' + cluster.cluster_name)
     def _k8sconverter(cluster):
         setattr(cluster, 'name', cluster.cloud_name +
                 '.' + cluster.cluster_name)
@@ -721,7 +721,7 @@ class StxClientImp(object):
                      cluster.name + '/' + str(cluster.uuid))
         return cluster
 
                      cluster.name + '/' + str(cluster.uuid))
         return cluster
 
-    @ staticmethod
+    @staticmethod
     def _k8shasher(cluster):
         return str(hash((cluster.cluster_name, cluster.cloud_name,
                          cluster.cluster_api_endpoint, cluster.admin_user,
     def _k8shasher(cluster):
         return str(hash((cluster.cluster_name, cluster.cloud_name,
                          cluster.cluster_api_endpoint, cluster.admin_user,
index 81ba817..aacb6be 100644 (file)
@@ -270,38 +270,38 @@ class StxSaClientImp(object):
                                 'more than one system exists in the account.')
             return isystems[0]
 
                                 'more than one system exists in the account.')
             return isystems[0]
 
-    @ staticmethod
+    @staticmethod
     def _hostconverter(host):
         setattr(host, 'name', host.hostname)
         return host
 
     def _hostconverter(host):
         setattr(host, 'name', host.hostname)
         return host
 
-    @ staticmethod
+    @staticmethod
     def _cpuconverter(cpu):
         setattr(cpu, 'name', cpu.ihost_uuid.split(
             '-', 1)[0] + '-cpu-'+str(cpu.cpu))
         return cpu
 
     def _cpuconverter(cpu):
         setattr(cpu, 'name', cpu.ihost_uuid.split(
             '-', 1)[0] + '-cpu-'+str(cpu.cpu))
         return cpu
 
-    @ staticmethod
+    @staticmethod
     def _memconverter(mem):
         setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] +
                 '-mem-node-'+str(mem.numa_node))
         return mem
 
     def _memconverter(mem):
         setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] +
                 '-mem-node-'+str(mem.numa_node))
         return mem
 
-    @ staticmethod
+    @staticmethod
     def _ethconverter(eth):
         setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name)
         setattr(eth, 'updated_at', None)
         setattr(eth, 'created_at', None)
         return eth
 
     def _ethconverter(eth):
         setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name)
         setattr(eth, 'updated_at', None)
         setattr(eth, 'created_at', None)
         return eth
 
-    @ staticmethod
+    @staticmethod
     def _ifconverter(ifs):
         setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname)
         setattr(ifs, 'updated_at', None)
         setattr(ifs, 'created_at', None)
         return ifs
 
     def _ifconverter(ifs):
         setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname)
         setattr(ifs, 'updated_at', None)
         setattr(ifs, 'created_at', None)
         return ifs
 
-    @ staticmethod
+    @staticmethod
     def _k8sconverter(cluster):
         setattr(cluster, 'name', cluster.cluster_name)
         setattr(cluster, 'uuid',
     def _k8sconverter(cluster):
         setattr(cluster, 'name', cluster.cluster_name)
         setattr(cluster, 'uuid',
@@ -313,7 +313,7 @@ class StxSaClientImp(object):
                      cluster.name + '/' + str(cluster.uuid))
         return cluster
 
                      cluster.name + '/' + str(cluster.uuid))
         return cluster
 
-    @ staticmethod
+    @staticmethod
     def _k8shasher(cluster):
         return str(hash((cluster.cluster_name,
                          cluster.cluster_api_endpoint, cluster.admin_user)))
     def _k8shasher(cluster):
         return str(hash((cluster.cluster_name,
                          cluster.cluster_api_endpoint, cluster.admin_user)))
index 800c6d7..c0f9f17 100644 (file)
@@ -178,9 +178,10 @@ class AlarmNotificationEventEnum(str, Enum):
 
 class AlarmEvent2SMO(Serializer):
     def __init__(self, eventtype: AlarmNotificationEventEnum,
 
 class AlarmEvent2SMO(Serializer):
     def __init__(self, eventtype: AlarmNotificationEventEnum,
-                 id: str, updatetime: str) -> None:
+                 id: str, ref: str, updatetime: str) -> None:
         self.notificationEventType = eventtype
         self.id = id
         self.notificationEventType = eventtype
         self.id = id
+        self.objectRef = ref
         self.updatetime = updatetime
 
 
         self.updatetime = updatetime
 
 
index ce46e96..23e9122 100644 (file)
@@ -66,6 +66,8 @@ class DeploymentManager(InfrastructureInventoryObject, AgRoot, Serializer):
 
         if 'capabilities' in d and d['capabilities'] != '':
             d['capabilities'] = json.loads(d['capabilities'])
 
         if 'capabilities' in d and d['capabilities'] != '':
             d['capabilities'] = json.loads(d['capabilities'])
+        if 'capacity' in d and d['capacity'] != '':
+            d['capacity'] = json.loads(d['capacity'])
         return d
 
     def get_notification_dict(self):
         return d
 
     def get_notification_dict(self):
index 88a0e90..6fd0bb2 100644 (file)
@@ -48,6 +48,8 @@ def notify_change_to_smo(
         _notify_dms(uow, notifications, cmd.data)
     elif msg_type == 'Resource':
         _notify_resource(uow, notifications, cmd.data)
         _notify_dms(uow, notifications, cmd.data)
     elif msg_type == 'Resource':
         _notify_resource(uow, notifications, cmd.data)
+    elif msg_type == 'OCloud':
+        _notify_ocloud(uow, notifications, cmd.data)
 
 
 def __get_object_type_and_value(sub_filter):
 
 
 def __get_object_type_and_value(sub_filter):
@@ -61,7 +63,6 @@ def __get_object_type_and_value(sub_filter):
 
 
 def handle_filter(filter: str, f_type: str):
 
 
 def handle_filter(filter: str, f_type: str):
-    print(filter)
     if not filter:
         return
 
     if not filter:
         return
 
@@ -189,6 +190,35 @@ def _notify_dms(uow, notifications, data):
                         .format(sub_data['subscriptionId'], data.id))
 
 
                         .format(sub_data['subscriptionId'], data.id))
 
 
+def _notify_ocloud(uow, notifications, data):
+    with uow:
+        ocloud = uow.oclouds.get(data.id)
+        if ocloud is None:
+            logger.warning(
+                'oCloud {} does not exists.'.format(data.id))
+            return
+
+        ocloud_dict = ocloud.get_notification_dict()
+
+        subs = uow.subscriptions.list()
+        for sub in subs:
+            sub_data = sub.serialize()
+            logger.debug('Subscription: {}'.format(sub_data['subscriptionId']))
+            filters = handle_filter(
+                sub_data['filter'], 'CloudInfo')
+            logger.debug(f'filters: {filters}, sub_data: {sub_data}')
+
+            if not filters or filters[0] == 0 or check_filters(
+                    filters, sub_data, uow.oclouds,
+                    ocloud.Ocloud,
+                    ocloud.Ocloud.oCloudId, data.id):
+                callback_smo(notifications, sub, data, ocloud_dict)
+                continue
+
+            logger.info('Subscription {} filter hit, skip Cloud {}.'
+                        .format(sub_data['subscriptionId'], data.id))
+
+
 def _notify_resource(uow, notifications, data):
     with uow:
         resource = uow.resources.get(data.id)
 def _notify_resource(uow, notifications, data):
     with uow:
         resource = uow.resources.get(data.id)
index f283ca0..7d1b8f6 100644 (file)
@@ -89,11 +89,11 @@ class OcloudDTO:
             # 'smoRegistrationService': fields.String
             'extensions': fields.String(
                 example='',
             # 'smoRegistrationService': fields.String
             'extensions': fields.String(
                 example='',
-                description='These are unspecified (not standardized) ' +\
-                'properties (keys) which are tailored by the vendor ' +\
+                description='These are unspecified (not standardized) ' +
+                'properties (keys) which are tailored by the vendor ' +
                 'to extend the information provided about the O-Cloud.'),
         },
                 'to extend the information provided about the O-Cloud.'),
         },
-        mask='{oCloudId,globalCloudId,globalcloudId,name,description,' +\
+        mask='{oCloudId,globalCloudId,globalcloudId,name,description,' +
         'serviceUri}'
     )
 
         'serviceUri}'
     )
 
@@ -264,9 +264,9 @@ class ResourcePoolDTO:
             # 'resources': fields.String,
             'extensions': fields.String(
                 example='',
             # 'resources': fields.String,
             'extensions': fields.String(
                 example='',
-                description='List of metadata key-value pairs ' +\
-                'used to associate meaningful metadata to ' +\
-                'the related resource pool.')
+                description=('List of metadata key-value pairs '
+                             'used to associate meaningful metadata to '
+                             'the related resource pool.'))
         },
         mask='{resourcePoolId,oCloudId,globalLocationId,name,description}'
     )
         },
         mask='{resourcePoolId,oCloudId,globalLocationId,name,description}'
     )
@@ -367,6 +367,14 @@ class DeploymentManagerDTO:
                 'the Deployment Manager'),
         })
 
                 'the Deployment Manager'),
         })
 
+    capacity = api_ims_inventory_v1.model(
+        "DeploymentManagerCapacity", {
+            'OS': fields.String(
+                example='low_latency',
+                description='Show the OS capacity of ' +
+                'the Deployment Manager'),
+        })
+
     deployment_manager_list = api_ims_inventory_v1.model(
         "DeploymentManagerListDto",
         {
     deployment_manager_list = api_ims_inventory_v1.model(
         "DeploymentManagerListDto",
         {
@@ -389,11 +397,12 @@ class DeploymentManagerDTO:
                 example='https://128.224.115.51:6443',
                 description='The fully qualified URI to a Deployment ' +
                 'Management server for O2dms.'),
                 example='https://128.224.115.51:6443',
                 description='The fully qualified URI to a Deployment ' +
                 'Management server for O2dms.'),
+            # Comment for the future implementation
             # 'deploymentManagementServiceEndpoint': fields.String(
             # attribute='serviceUri'),
             # 'deploymentManagementServiceEndpoint': fields.String(
             # attribute='serviceUri'),
-            'supportedLocations': fields.String,
+            'supportedLocations': fields.String,
             'capabilities': fields.Nested(capabilities, True, True),
             'capabilities': fields.Nested(capabilities, True, True),
-            # 'capacity': fields.String,
+            'capacity': fields.Nested(capacity, True, True),
             'profileSupportList': fields.List(
                 fields.String,
                 example=['native_k8sapi'],
             'profileSupportList': fields.List(
                 fields.String,
                 example=['native_k8sapi'],
@@ -405,8 +414,8 @@ class DeploymentManagerDTO:
                 'associate meaningful metadata to the related Deployment ' +
                 'Manager'),
         },
                 'associate meaningful metadata to the related Deployment ' +
                 'Manager'),
         },
-        mask='{deploymentManagerId,name,description,oCloudId,serviceUri,' + \
-        'profileSupportList}'
+        mask='{deploymentManagerId,name,description,oCloudId,serviceUri,' +
+        'supportedLocations,capabilities,capacity,profileSupportList}'
     )
 
     profile = api_ims_inventory_v1.model("DeploymentManagerGetDtoProfile", {
     )
 
     profile = api_ims_inventory_v1.model("DeploymentManagerGetDtoProfile", {
@@ -480,12 +489,13 @@ class DeploymentManagerDTO:
                 'Management server for O2dms.'),
             # 'deploymentManagementServiceEndpoint': fields.String(
             # attribute='serviceUri'),
                 'Management server for O2dms.'),
             # 'deploymentManagementServiceEndpoint': fields.String(
             # attribute='serviceUri'),
-            'supportedLocations': fields.String,
+            'supportedLocations': fields.String,
             'capabilities': fields.Nested(capabilities, True, True),
             'capabilities': fields.Nested(capabilities, True, True),
-            # 'capacity': fields.String,
+            'capacity': fields.Nested(capacity, True, True),
             'extensions': fields.Nested(extensions, True, True)
         },
             'extensions': fields.Nested(extensions, True, True)
         },
-        mask='{deploymentManagerId,name,description,oCloudId,serviceUri,' +\
+        mask='{deploymentManagerId,name,description,oCloudId,serviceUri,' +
+        'supportedLocations,capabilities,capacity,' +
         'extensions{profileName,profileData}}'
     )
 
         'extensions{profileName,profileData}}'
     )