# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import enum import functools, logging #import uuid from typing import Dict #, List #from common.orm.Database import Database #from common.orm.backend.Tools import key_to_str from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum from sqlalchemy import Column, Float, ForeignKey, String, Enum from sqlalchemy.dialects.postgresql import UUID, ARRAY from sqlalchemy.orm import relationship from context.service.database._Base import _Base from .Tools import grpc_to_enum LOGGER = logging.getLogger(__name__) class ORM_DeviceDriverEnum(enum.Enum): UNDEFINED = DeviceDriverEnum.DEVICEDRIVER_UNDEFINED OPENCONFIG = DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG TRANSPORT_API = DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API P4 = DeviceDriverEnum.DEVICEDRIVER_P4 IETF_NETWORK_TOPOLOGY = DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY ONF_TR_352 = DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352 XR = DeviceDriverEnum.DEVICEDRIVER_XR grpc_to_enum__device_driver = functools.partial( grpc_to_enum, DeviceDriverEnum, ORM_DeviceDriverEnum) class ORM_DeviceOperationalStatusEnum(enum.Enum): UNDEFINED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED grpc_to_enum__device_operational_status = functools.partial( grpc_to_enum, DeviceOperationalStatusEnum, ORM_DeviceOperationalStatusEnum) class DeviceModel(_Base): __tablename__ = 'device' device_uuid = Column(UUID(as_uuid=False), primary_key=True) device_name = Column(String(), nullable=False) device_type = Column(String(), nullable=False) #device_config_uuid = Column(UUID(as_uuid=False), ForeignKey('config.config_uuid', ondelete='CASCADE')) device_operational_status = Column(Enum(ORM_DeviceOperationalStatusEnum)) device_drivers = Column(ARRAY(Enum(ORM_DeviceDriverEnum), dimensions=1)) created_at = Column(Float) # Relationships topology_device = relationship('TopologyDeviceModel', back_populates='devices') #device_config = relationship("ConfigModel", passive_deletes=True, lazy="joined") endpoints = relationship('EndPointModel', passive_deletes=True, back_populates='device') def dump_id(self) -> Dict: return {'device_uuid': {'uuid': self.device_uuid}} def dump(self) -> Dict: return { 'device_id' : self.dump_id(), 'name' : self.device_name, 'device_type' : self.device_type, 'device_operational_status': self.device_operational_status.value, 'device_drivers' : [d.value for d in self.device_drivers], #'device_config' : {'config_rules': self.device_config.dump()}, #'device_endpoints' : [ep.dump() for ep in self.endpoints], } #def set_drivers(database : Database, db_device : DeviceModel, grpc_device_drivers): # db_device_pk = db_device.device_uuid # for driver in grpc_device_drivers: # orm_driver = grpc_to_enum__device_driver(driver) # str_device_driver_key = key_to_str([db_device_pk, orm_driver.name]) # db_device_driver = DriverModel(database, str_device_driver_key) # db_device_driver.device_fk = db_device # db_device_driver.driver = orm_driver # db_device_driver.save() # def set_kpi_sample_types(self, db_endpoint: EndPointModel, grpc_endpoint_kpi_sample_types): # db_endpoint_pk = db_endpoint.endpoint_uuid # for kpi_sample_type in grpc_endpoint_kpi_sample_types: # orm_kpi_sample_type = grpc_to_enum__kpi_sample_type(kpi_sample_type) # # str_endpoint_kpi_sample_type_key = key_to_str([db_endpoint_pk, orm_kpi_sample_type.name]) # data = {'endpoint_uuid': db_endpoint_pk, # 'kpi_sample_type': orm_kpi_sample_type.name, # 'kpi_uuid': str(uuid.uuid4())} # db_endpoint_kpi_sample_type = KpiSampleTypeModel(**data) # self.database.create(db_endpoint_kpi_sample_type) # def set_drivers(self, db_device: DeviceModel, grpc_device_drivers): # db_device_pk = db_device.device_uuid # for driver in grpc_device_drivers: # orm_driver = grpc_to_enum__device_driver(driver) # str_device_driver_key = key_to_str([db_device_pk, orm_driver.name]) # driver_config = { # # "driver_uuid": str(uuid.uuid4()), # "device_uuid": db_device_pk, # "driver": orm_driver.name # } # db_device_driver = DriverModel(**driver_config) # db_device_driver.device_fk = db_device # db_device_driver.driver = orm_driver # # self.database.create_or_update(db_device_driver) # def update_config( # self, session, db_parent_pk: str, config_name: str, # raw_config_rules: List[Tuple[ORM_ConfigActionEnum, str, str]] # ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]: # # created = False # # db_config = session.query(ConfigModel).filter_by(**{ConfigModel.main_pk_name(): db_parent_pk}).one_or_none() # if not db_config: # db_config = ConfigModel() # setattr(db_config, ConfigModel.main_pk_name(), db_parent_pk) # session.add(db_config) # session.commit() # created = True # # LOGGER.info('UPDATED-CONFIG: {}'.format(db_config.dump())) # # db_objects: List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]] = [(db_config, created)] # # for position, (action, resource_key, resource_value) in enumerate(raw_config_rules): # if action == ORM_ConfigActionEnum.SET: # result : Tuple[ConfigRuleModel, bool] = self.set_config_rule( # db_config, position, resource_key, resource_value) # db_config_rule, updated = result # db_objects.append((db_config_rule, updated)) # elif action == ORM_ConfigActionEnum.DELETE: # self.delete_config_rule(db_config, resource_key) # else: # msg = 'Unsupported action({:s}) for resource_key({:s})/resource_value({:s})' # raise AttributeError( # msg.format(str(ConfigActionEnum.Name(action)), str(resource_key), str(resource_value))) # # return db_objects # # def set_config_rule(self, db_config: ConfigModel, position: int, resource_key: str, resource_value: str, # ): # -> Tuple[ConfigRuleModel, bool]: # # from src.context.service.database.Tools import fast_hasher # str_rule_key_hash = fast_hasher(resource_key) # str_config_rule_key = key_to_str([db_config.config_uuid, str_rule_key_hash], separator=':') # pk = str(uuid.uuid5(uuid.UUID('9566448d-e950-425e-b2ae-7ead656c7e47'), str_config_rule_key)) # data = {'config_rule_uuid': pk, 'config_uuid': db_config.config_uuid, 'position': position, # 'action': ORM_ConfigActionEnum.SET, 'key': resource_key, 'value': resource_value} # to_add = ConfigRuleModel(**data) # # result, updated = self.database.create_or_update(to_add) # return result, updated # # def delete_config_rule( # self, db_config: ConfigModel, resource_key: str # ) -> None: # # from src.context.service.database.Tools import fast_hasher # str_rule_key_hash = fast_hasher(resource_key) # str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') # # db_config_rule = self.database.get_object(ConfigRuleModel, str_config_rule_key, raise_if_not_found=False) # # if db_config_rule is None: # return # db_config_rule.delete() # # def delete_all_config_rules(self, db_config: ConfigModel) -> None: # # db_config_rule_pks = db_config.references(ConfigRuleModel) # for pk, _ in db_config_rule_pks: ConfigRuleModel(self.database, pk).delete() # # """ # for position, (action, resource_key, resource_value) in enumerate(raw_config_rules): # if action == ORM_ConfigActionEnum.SET: # result: Tuple[ConfigRuleModel, bool] = set_config_rule( # database, db_config, position, resource_key, resource_value) # db_config_rule, updated = result # db_objects.append((db_config_rule, updated)) # elif action == ORM_ConfigActionEnum.DELETE: # delete_config_rule(database, db_config, resource_key) # else: # msg = 'Unsupported action({:s}) for resource_key({:s})/resource_value({:s})' # raise AttributeError( # msg.format(str(ConfigActionEnum.Name(action)), str(resource_key), str(resource_value))) # # return db_objects # """