Example #1
0
    def __init__(self, adapter, device_id):
        self.log = structlog.get_logger(device_id=device_id)
        self.log.debug('function-entry')
        self.adapter = adapter
        self.adapter_agent = adapter.adapter_agent
        self.parent_adapter = None
        self.parent_id = None
        self.device_id = device_id
        self.incoming_messages = DeferredQueue()
        self.event_messages = DeferredQueue()
        self.proxy_address = None
        self.tx_id = 0
        self._enabled = False
        self.alarms = None
        self.pm_metrics = None
        self._omcc_version = OMCCVersion.Unknown
        self._total_tcont_count = 0  # From ANI-G ME
        self._qos_flexibility = 0  # From ONT2_G ME

        self._onu_indication = None
        self._unis = dict()  # Port # -> UniPort

        self._pon = None
        # TODO: probably shouldnt be hardcoded, determine from olt maybe?
        self._pon_port_number = 100
        self.logical_device_id = None

        self._heartbeat = HeartBeat.create(self, device_id)

        # Set up OpenOMCI environment
        self._onu_omci_device = None
        self._dev_info_loaded = False
        self._deferred = None

        self._in_sync_subscription = None
        self._connectivity_subscription = None
        self._capabilities_subscription = None

        self.mac_bridge_service_profile_entity_id = 0x201
        self.gal_enet_profile_entity_id = 0x1

        self._tp_service_specific_task = dict()
        self._tech_profile_download_done = dict()

        # Initialize KV store client
        self.args = registry('main').get_args()
        if self.args.backend == 'etcd':
            host, port = self.args.etcd.split(':', 1)
            self.kv_client = EtcdStore(
                host, port, TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX)
        elif self.args.backend == 'consul':
            host, port = self.args.consul.split(':', 1)
            self.kv_client = ConsulStore(
                host, port, TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX)
        else:
            self.log.error('Invalid-backend')
            raise Exception("Invalid-backend-for-kv-store")

        # Handle received ONU event messages
        reactor.callLater(0, self.handle_onu_events)
Example #2
0
    def __init__(self, device_id, host_and_port, extra_args, device_info):
        self.log = structlog.get_logger(id=device_id, ip=host_and_port)
        self.device_id = device_id
        self.host_and_port = host_and_port
        self.extra_args = extra_args
        self.device_info = device_info
        self.args = registry('main').get_args()

        # KV store's IP Address and PORT
        # host, port = '127.0.0.1', 8500
        if self.args.backend == 'etcd':
            host, port = self.args.etcd.split(':', 1)
            self.kv_store = EtcdStore(
                host, port,
                AdtranOltResourceMgr.BASE_PATH_KV_STORE.format(device_id))
        elif self.args.backend == 'consul':
            host, port = self.args.consul.split(':', 1)
            self.kv_store = ConsulStore(
                host, port,
                AdtranOltResourceMgr.BASE_PATH_KV_STORE.format(device_id))
        else:
            self.log.error('Invalid-backend')
            raise Exception("Invalid-backend-for-kv-store")

        self.resource_mgr = AdtranPONResourceManager(
            self.device_info.technology, self.extra_args, self.device_id,
            self.args.backend, host, port)
        # Flag to indicate whether information fetched from device should
        # be used to initialize PON Resource Ranges
        self.use_device_info = False

        self.initialize_device_resource_range_and_pool()
Example #3
0
    def __init__(self, technology, device_id, backend, host, port):
        """
        Create ResourceKvStore object.

        Based on backend ('consul' and 'etcd' use the host and port
        to create the respective object.

        :param technology: PON technology
        :param device_id: OLT device id
        :param backend: Type of backend storage (etcd or consul)
        :param host: host ip info for backend storage
        :param port: port for the backend storage
        :raises exception when invalid backend store passed as an argument
        """
        # logger
        self._log = structlog.get_logger()

        path = PATH_PREFIX.format(technology)
        try:
            if backend == 'consul':
                self._kv_store = ConsulStore(host, port, path)
            elif backend == 'etcd':
                self._kv_store = EtcdStore(host, port, path)
            else:
                self._log.error('Invalid-backend')
                raise Exception("Invalid-backend-for-kv-store")
        except Exception as e:
            self._log.exception("exception-in-init")
            raise Exception(e)
Example #4
0
 def __init__(self, backend, host, port):
     """
     based on backend ('consul' and 'etcd' use the host and port
     to create of the respective object
     :param backend: Type of backend storage (etcd or consul)
     :param host: host ip info for backend storage
     :param port: port for the backend storage
     """
     try:
         if backend == 'consul':
             self.kv_store = ConsulStore(host, port, PATH_PREFIX)
         elif backend == 'etcd':
             self.kv_store = EtcdStore(host, port, PATH_PREFIX)
         else:
             log.error('Invalid-backend')
             raise Exception("Invalid-backend-for-kv-store")
     except Exception as e:
         log.exception("exception-in-init", e=e)
Example #5
0
    def __init__(self, adapter, device_id):
        kwargs = dict()
        super(AdtranOnuHandler, self).__init__(**kwargs)
        self.adapter = adapter
        self.adapter_agent = adapter.adapter_agent
        self.device_id = device_id
        self.log = structlog.get_logger(device_id=device_id)
        self.logical_device_id = None
        self.proxy_address = None
        self._enabled = False
        self.pm_metrics = None
        self.alarms = None

        self._openomci = OMCI(self, adapter.omci_agent)
        self._in_sync_subscription = None

        self._pon_port_number = 1

        self._unis = dict()         # Port # -> UniPort
        self._pon = PonPort.create(self, self._pon_port_number)
        self._heartbeat = HeartBeat.create(self, device_id)
        self._deferred = None

        # Flow entries
        self._flows = dict()

        # OMCI resources               # TODO: Some of these could be dynamically chosen
        self.vlan_tcis_1 = 0x900
        self.mac_bridge_service_profile_entity_id = self.vlan_tcis_1
        self.gal_enet_profile_entity_id = 0

        # Technology profile related values
        self.incoming_messages = DeferredQueue()
        self.event_messages = DeferredQueue()
        self._tp_service_specific_task = dict()
        self._tech_profile_download_done = dict()

        # Initialize KV store client
        self.args = registry('main').get_args()
        if self.args.backend == 'etcd':
            host, port = self.args.etcd.split(':', 1)
            self.kv_client = EtcdStore(host, port,
                                       TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX)
        elif self.args.backend == 'consul':
            host, port = self.args.consul.split(':', 1)
            self.kv_client = ConsulStore(host, port,
                                         TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX)
        else:
            self.log.error('Invalid-backend')
            raise Exception("Invalid-backend-for-kv-store")

        # Handle received ONU event messages
        reactor.callLater(0, self.handle_onu_events)
Example #6
0
    def __init__(self, resource_mgr):
        try:
            self.args = registry('main').get_args()
            self.resource_mgr = resource_mgr

            if self.args.backend == 'etcd':
                # KV store's IP Address and PORT
                host, port = self.args.etcd.split(':', 1)
                self._kv_store = EtcdStore(
                    host, port, TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX)
            elif self.args.backend == 'consul':
                # KV store's IP Address and PORT
                host, port = self.args.consul.split(':', 1)
                self._kv_store = ConsulStore(
                    host, port, TechProfile.KV_STORE_TECH_PROFILE_PATH_PREFIX)

            # self.tech_profile_instance_store = dict()
        except Exception as e:
            log.exception("exception-in-init")
            raise Exception(e)
Example #7
0
    def __init__(self, device_id, host_and_port, extra_args, device_info):
        self.log = structlog.get_logger(id=device_id, ip=host_and_port)
        self.device_id = device_id
        self.host_and_port = host_and_port
        self.extra_args = extra_args
        self.device_info = device_info
        self.args = registry('main').get_args()

        # KV store's IP Address and PORT
        if self.args.backend == 'etcd':
            host, port = self.args.etcd.split(':', 1)
            self.kv_store = EtcdStore(
                host, port,
                OpenOltResourceMgr.BASE_PATH_KV_STORE.format(device_id))
        elif self.args.backend == 'consul':
            host, port = self.args.consul.split(':', 1)
            self.kv_store = ConsulStore(
                host, port,
                OpenOltResourceMgr.BASE_PATH_KV_STORE.format(device_id))
        else:
            self.log.error('Invalid-backend')
            raise Exception("Invalid-backend-for-kv-store")

        ranges = dict()
        resource_mgrs_by_tech = dict()
        self.resource_mgrs = dict()

        # If a legacy driver returns protobuf without any ranges,s synthesize one from
        # the legacy global per-device informaiton. This, in theory, is temporary until
        # the legacy drivers are upgrade to support pool ranges.
        if len(self.device_info.ranges) == 0:
            arange = self.device_info.ranges.add()
            arange.technology = self.device_info.technology
            arange.intf_ids.extend(range(0, device_info.pon_ports))

            pool = arange.pools.add()
            pool.type = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.ONU_ID
            pool.start = self.device_info.onu_id_start
            pool.end = self.device_info.onu_id_end
            pool.sharing = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.DEDICATED_PER_INTF

            pool = arange.pools.add()
            pool.type = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.ALLOC_ID
            pool.start = self.device_info.alloc_id_start
            pool.end = self.device_info.alloc_id_end
            pool.sharing = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.SHARED_BY_ALL_INTF_ALL_TECH

            pool = arange.pools.add()
            pool.type = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.GEMPORT_ID
            pool.start = self.device_info.gemport_id_start
            pool.end = self.device_info.gemport_id_end
            pool.sharing = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.SHARED_BY_ALL_INTF_ALL_TECH

            pool = arange.pools.add()
            pool.type = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.FLOW_ID
            pool.start = self.device_info.flow_id_start
            pool.end = self.device_info.flow_id_end
            pool.sharing = openolt_pb2.DeviceInfo.DeviceResourceRanges.Pool.SHARED_BY_ALL_INTF_ALL_TECH

        # Create a separate Resource Manager instance for each range. This assumes that
        # each technology is represented by only a single range
        global_resource_mgr = None
        for arange in self.device_info.ranges:
            technology = arange.technology
            self.log.info("device-info", technology=technology)
            ranges[technology] = arange
            extra_args = self.extra_args + ' ' + PONResourceManager.OLT_MODEL_ARG + ' {}'.format(
                self.device_info.model)
            resource_mgr = PONResourceManager(technology, extra_args,
                                              self.device_id,
                                              self.args.backend, host, port)
            resource_mgrs_by_tech[technology] = resource_mgr
            if global_resource_mgr is None:
                global_resource_mgr = resource_mgr
            for intf_id in arange.intf_ids:
                self.resource_mgrs[intf_id] = resource_mgrs_by_tech[technology]
            self.initialize_device_resource_range_and_pool(
                resource_mgr, global_resource_mgr, arange)

        # After we have initialized resource ranges, initialize the
        # resource pools accordingly.
        for technology, resource_mgr in resource_mgrs_by_tech.iteritems():
            resource_mgr.init_device_resource_pool()
Example #8
0
class Asfvolt16KvStore(object):

    def __init__(self, backend, host, port):
        """
        based on backend ('consul' and 'etcd' use the host and port
        to create of the respective object
        :param backend: Type of backend storage (etcd or consul)
        :param host: host ip info for backend storage
        :param port: port for the backend storage
        """
        try:
            if backend == 'consul':
                self.kv_store = ConsulStore(host, port, PATH_PREFIX)
            elif backend == 'etcd':
                self.kv_store = EtcdStore(host, port, PATH_PREFIX)
            else:
                log.error('Invalid-backend')
                raise Exception("Invalid-backend-for-kv-store")
        except Exception as e:
            log.exception("exception-in-init", e=e)

    # Used for incremental flow, as we are getting remove flow cookies,
    # So instead of evaluating, we are just getting the mapping info
    # from kv store
    def get_flows_to_remove_info(self, device_id, flows):
        # store flows to be removed
        flows_to_remove_list = []
        id = device_id.encode('ascii', 'ignore')

        try:
            # Preparing cookie info list from received remove flow
            for flow in flows:
                cookie_info = self.kv_store[id + '/' + str(flow.cookie)]
                if cookie_info:
                    log.debug("cookie-info-exist", cookie=flow.cookie,
                              cookie_info=cookie_info)
                    flows_to_remove_list.append(json.loads(cookie_info))
                else:
                    log.debug("cookie-info-does-not-exist", cookie=flow.cookie)

        except Exception as e:
            log.exception("evaulating-flows-to-remove-info", e=e)

        return flows_to_remove_list

    # Used for bulk flow update, as we are getting bulk flow cookies,
    # So we evalute based on the curent flows present in kv store
    def get_flows_to_remove(self, device_id, flows):
        # store the flows present in the db
        current_flows_list = []

        # store flows to be removed
        flows_to_remove_list = []
        id = device_id.encode('ascii', 'ignore')

        # Get all the flows already present in the consul
        try:
            # Get all the flows already present in the consul
            # Preparing cookie list from flows present in the KV store
            kv_store_flows = self.kv_store._kv_get(PATH_PREFIX + '/' + id,
                                                   recurse=True)
            if kv_store_flows is None:
                return flows_to_remove_list

            for kv_store_flow in kv_store_flows:
                value = kv_store_flow['Value']
                current_flows_list.append(json.loads(value))

            # Preparing cookie list from bulk flow received
            bulk_update_flow_cookie_list = [flow.cookie for flow in flows]

            # Evaluating the flows need to be removed
            # current_flows not present in bulk_flow
            for current_flow in current_flows_list:
                cookie = current_flow.keys()[0]
                if long(cookie) not in bulk_update_flow_cookie_list:
                    flows_to_remove_list.append(current_flow[cookie])

        except Exception as e:
            log.exception("evaulating-flows-to-remove", e=e)

        return flows_to_remove_list

    def get_flows_to_add(self, device_id, flows):
        # store the flows present in the db
        current_flows_list = []
        id = device_id.encode('ascii', 'ignore')

        try:
            # Get all the flows already present in the consul
            # Preparing cookie set from flows present in the KV store
            kv_store_flows = self.kv_store._kv_get(PATH_PREFIX + '/' + id,
                                                   recurse=True)
            if kv_store_flows is not None:
                for kv_store_flow in kv_store_flows:
                    value = kv_store_flow['Value']
                    current_flows_list.append(json.loads(value))

            current_flow_cookie_set = set(long(current_flow.keys()[0])
                                          for current_flow in current_flows_list)
            # Preparing cookie set from bulk flow received
            bulk_update_flow_cookie_set = set(flow.cookie for flow in flows)

            # Evaluating the list of flows newly to be added
            flow_to_add_set = bulk_update_flow_cookie_set.difference \
                                             (current_flow_cookie_set)
            flows_to_add_list = list(flow_to_add_set)

        except Exception as e:
            log.exception("evaluating-flows-to-add", e=e)

        return flows_to_add_list

    def add_to_kv_store(self, device_id, new_flow_mapping_list):
        # store the flows present in the db
        current_flows_list = []
        id = device_id.encode('ascii', 'ignore')

        try:
            log.debug("incremental-flows-to-be-added-to-kv-store",
                      flows=new_flow_mapping_list)
            # Key is the cookie id, extracted from the key stored in new_flow_mapping_list
            for flow in new_flow_mapping_list:
                self.kv_store[id + '/' + str(flow.keys()[0])] = json.dumps(flow)

        except Exception as e:
            log.exception("incremental-flow-add-to-kv-store", e=e)

    def remove_from_kv_store(self, device_id, flows_to_remove):
        id = device_id.encode('ascii', 'ignore')

        try:
            log.debug("incremental-flows-to-be-removed-from-kv-store",
                      flows=flows_to_remove)
            # remove the flows based on cookie id from kv store
            for cookie in flows_to_remove:
                del self.kv_store[id + '/' + str(cookie)]

        except Exception as e:
            log.exception("incremental-flow-remove-from-kv-store", e=e)

    def update_kv_store(self, device_id, new_flow_mapping_list, flows):
        # store the flows present in the db
        current_flows_list = []
        id = device_id.encode('ascii', 'ignore')

        try:
            # Get all the flows already present in the consul
            # Preparing cookie set from flows present in the KV store
            kv_store_flows = self.kv_store._kv_get(PATH_PREFIX + '/' + id,
                                                   recurse=True)
            if kv_store_flows is not None:
                for kv_store_flow in kv_store_flows:
                    value = kv_store_flow['Value']
                    current_flows_list.append(json.loads(value))

            current_flow_cookie_set = set(long(current_flow.keys()[0])
                                          for current_flow in current_flows_list)

            # Preparing cookie set from flows added newly
            new_flow_added_cookie_set = set(new_flow.keys()[0]
                                            for new_flow in new_flow_mapping_list)

            # Preparing cookie set from bulk flow received
            bulk_update_flow_cookie_set = set(flow.cookie for flow in flows)

            # Evaluating flows to be removed, remove from KV store
            remove_flows_list = list(current_flow_cookie_set.difference \
                                              (bulk_update_flow_cookie_set))
            log.debug("bulk-flows-to-be-removed-from-kv-store",
                      flows=remove_flows_list)

            for cookie in remove_flows_list:
                del self.kv_store[id + '/' + str(cookie)]

            # Evaluating flows need to be added newly to KV, add to KV
            new_flows_list = list(new_flow_added_cookie_set.difference \
                                            (current_flow_cookie_set))
            log.debug("bulk-flows-to-be-added-to-kv-store", flows=new_flows_list)

            for new_flow in new_flows_list:
                for fl in new_flow_mapping_list:
                    if fl.keys()[0] == new_flow:
                        self.kv_store[id + '/' + str(new_flow)] = json.dumps(fl)

        except Exception as e:
            log.exception("bulk-flow-update-kv-store", e=e)


    def clear_kv_store(self, device_id):
        id = device_id.encode('ascii', 'ignore')
        try:
            # Recurse flow is not working as cache is not getting cleared
            # So extracting all flows using GET and deleting each flow
            #kv_store_clear_flows = self.kv_store._kv_delete(PATH_PREFIX + '/' \
            #                                                + id, recurse=True)

            # Get all the flows present in the consul
            kv_store_flows = self.kv_store._kv_get(PATH_PREFIX + '/' + id,
                                                   recurse=True)
            if kv_store_flows is not None:
                for kv_store_flow in kv_store_flows:
                    # Extracting cookie id from the kv store flow details
                    # and deleting each flows
                    flow = json.loads(kv_store_flow['Value'])
                    cookie = flow.keys()[0]
                    del self.kv_store[id + '/' + str(cookie)]
                log.debug("kv-store-flows-cleared-successfully")
            else:
                log.debug("no-flows-found-in-kv-store")
                return

        except Exception as e:
            log.exception("clear-kv-store", e=e)

    def is_reference_found_for_key_value(self, device_id, key, value):
        id = device_id.encode('ascii', 'ignore')
        try:
            # Get all the flows present in the consul
            kv_store_flows = self.kv_store._kv_get(PATH_PREFIX + '/' + id,
                                                   recurse=True)
            if kv_store_flows is not None:
                for kv_store_flow in kv_store_flows:
                    flow = json.loads(kv_store_flow['Value'])
                    cookie = flow.keys()[0]
                    flow_data = flow[cookie]
                    if key in flow_data.keys():
                        # Check if have reference for the Key in the flow
                        # with the given value
                        if flow_data[key] == value:
                            return True
        except Exception as e:
            log.exception("excepting-finding-refernece-for-kv", e=e)

        return False