blob: 9e249fb3d0a3f7c7fa12b76bcbd593fde8ee7c45 [file] [log] [blame]
Girish Gowdru141ced82018-09-17 20:19:14 -07001#
2# Copyright 2018 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17"""
18Resource Manager will be unique for each OLT device.
19
20It exposes APIs to create/free alloc_ids/onu_ids/gemport_ids. Resource Manager
21uses a KV store in backend to ensure resiliency of the data.
22"""
23import json
Girish Gowdruab836e92018-10-25 01:17:57 -070024import ast
Girish Gowdru141ced82018-09-17 20:19:14 -070025import structlog
26from bitstring import BitArray
Girish Gowdru1e77ea02018-09-24 09:10:35 -070027import shlex
28from argparse import ArgumentParser, ArgumentError
Girish Gowdru141ced82018-09-17 20:19:14 -070029
Girish Gowdru1e77ea02018-09-24 09:10:35 -070030from common.pon_resource_manager.resource_kv_store import ResourceKvStore
Girish Gowdruab836e92018-10-25 01:17:57 -070031from common.tech_profile.tech_profile import TechProfile
Girish Gowdru1e77ea02018-09-24 09:10:35 -070032
33
34# Used to parse extra arguments to OpenOlt adapter from the NBI
35class OltVendorArgumentParser(ArgumentParser):
36 # Must override the exit command to prevent it from
37 # calling sys.exit(). Return exception instead.
38 def exit(self, status=0, message=None):
39 raise Exception(message)
Girish Gowdru141ced82018-09-17 20:19:14 -070040
41
42class PONResourceManager(object):
43 """Implements APIs to initialize/allocate/release alloc/gemport/onu IDs."""
44
45 # Constants to identify resource pool
46 ONU_ID = 'ONU_ID'
47 ALLOC_ID = 'ALLOC_ID'
48 GEMPORT_ID = 'GEMPORT_ID'
Girish Gowdruab836e92018-10-25 01:17:57 -070049 FLOW_ID = 'FLOW_ID'
Girish Gowdru141ced82018-09-17 20:19:14 -070050
Craig Lutgenf7601472018-11-02 13:27:41 +000051 # Constants for passing command line arugments
52 OLT_MODEL_ARG = '--olt_model'
53
54 # The resource ranges for a given device model should be placed
55 # at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
Girish Gowdru141ced82018-09-17 20:19:14 -070056 # path on the KV store.
57 # If Resource Range parameters are to be read from the external KV store,
58 # they are expected to be stored in the following format.
59 # Note: All parameters are MANDATORY for now.
60 '''
Girish Gowdru1e77ea02018-09-24 09:10:35 -070061 {
62 "onu_id_start": 1,
63 "onu_id_end": 127,
64 "alloc_id_start": 1024,
65 "alloc_id_end": 2816,
66 "gemport_id_start": 1024,
67 "gemport_id_end": 8960,
Girish Gowdruab836e92018-10-25 01:17:57 -070068 "flow_id_start": 1,
69 "flow_id_end": 16383,
Girish Gowdru1e77ea02018-09-24 09:10:35 -070070 "pon_ports": 16
71 }
72
Girish Gowdru141ced82018-09-17 20:19:14 -070073 '''
74 # constants used as keys to reference the resource range parameters from
75 # and external KV store.
Craig Lutgen1dd47082018-10-23 13:12:26 -050076 ONU_ID_START_IDX = "onu_id_start"
77 ONU_ID_END_IDX = "onu_id_end"
78 ONU_ID_SHARED_IDX = "onu_id_shared"
Girish Gowdru1e77ea02018-09-24 09:10:35 -070079 ALLOC_ID_START_IDX = "alloc_id_start"
80 ALLOC_ID_END_IDX = "alloc_id_end"
Craig Lutgen1dd47082018-10-23 13:12:26 -050081 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
82 GEMPORT_ID_START_IDX = "gemport_id_start"
83 GEMPORT_ID_END_IDX = "gemport_id_end"
84 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
Girish Gowdruab836e92018-10-25 01:17:57 -070085 FLOW_ID_START_IDX = "flow_id_start"
86 FLOW_ID_END_IDX = "flow_id_end"
87 FLOW_ID_SHARED_IDX = "flow_id_shared"
Girish Gowdru1e77ea02018-09-24 09:10:35 -070088 NUM_OF_PON_PORT = "pon_ports"
Girish Gowdru141ced82018-09-17 20:19:14 -070089
90 # PON Resource range configuration on the KV store.
Craig Lutgenf7601472018-11-02 13:27:41 +000091 # Format: 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
Girish Gowdru1e77ea02018-09-24 09:10:35 -070092 # The KV store backend is initialized with a path prefix and we need to
93 # provide only the suffix.
94 PON_RESOURCE_RANGE_CONFIG_PATH = 'resource_ranges/{}'
Girish Gowdru141ced82018-09-17 20:19:14 -070095
Girish Gowdru1e77ea02018-09-24 09:10:35 -070096 # resource path suffix
97 ALLOC_ID_POOL_PATH = '{}/alloc_id_pool/{}'
98 GEMPORT_ID_POOL_PATH = '{}/gemport_id_pool/{}'
99 ONU_ID_POOL_PATH = '{}/onu_id_pool/{}'
Girish Gowdruab836e92018-10-25 01:17:57 -0700100 FLOW_ID_POOL_PATH = '{}/flow_id_pool/{}'
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700101
102 # Path on the KV store for storing list of alloc IDs for a given ONU
103 # Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
104 ALLOC_ID_RESOURCE_MAP_PATH = '{}/{}/alloc_ids'
105
106 # Path on the KV store for storing list of gemport IDs for a given ONU
107 # Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
108 GEMPORT_ID_RESOURCE_MAP_PATH = '{}/{}/gemport_ids'
Girish Gowdru141ced82018-09-17 20:19:14 -0700109
Girish Gowdruab836e92018-10-25 01:17:57 -0700110 # Path on the KV store for storing list of Flow IDs for a given ONU
111 # Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
112 FLOW_ID_RESOURCE_MAP_PATH = '{}/{}/flow_ids'
113
114 # Flow Id info: Use to store more metadata associated with the flow_id
115 # Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
116 FLOW_ID_INFO_PATH = '{}/{}/flow_id_info/{}'
117
Girish Gowdru141ced82018-09-17 20:19:14 -0700118 # Constants for internal usage.
119 PON_INTF_ID = 'pon_intf_id'
120 START_IDX = 'start_idx'
121 END_IDX = 'end_idx'
122 POOL = 'pool'
123
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700124 def __init__(self, technology, extra_args, device_id,
Girish Gowdru141ced82018-09-17 20:19:14 -0700125 backend, host, port):
126 """
127 Create PONResourceManager object.
128
129 :param technology: PON technology
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700130 :param: extra_args: This string contains extra arguments passed during
131 pre-provisioning of OLT and specifies the OLT Vendor type
Girish Gowdru141ced82018-09-17 20:19:14 -0700132 :param device_id: OLT device id
133 :param backend: backend store
134 :param host: ip of backend store
135 :param port: port on which backend store listens
136 :raises exception when invalid backend store passed as an argument
137 """
138 # logger
139 self._log = structlog.get_logger()
140
141 try:
Girish Gowdru141ced82018-09-17 20:19:14 -0700142 self.technology = technology
Craig Lutgenf7601472018-11-02 13:27:41 +0000143 self.extra_args = extra_args
Girish Gowdru141ced82018-09-17 20:19:14 -0700144 self.device_id = device_id
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700145 self.backend = backend
146 self.host = host
147 self.port = port
Craig Lutgenf7601472018-11-02 13:27:41 +0000148 self.olt_model = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500149
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700150 self._kv_store = ResourceKvStore(technology, device_id, backend,
151 host, port)
Girish Gowdruab836e92018-10-25 01:17:57 -0700152 self.tech_profile = TechProfile(self)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500153
Girish Gowdru141ced82018-09-17 20:19:14 -0700154 # Below attribute, pon_resource_ranges, should be initialized
155 # by reading from KV store.
156 self.pon_resource_ranges = dict()
Craig Lutgen1dd47082018-10-23 13:12:26 -0500157 self.pon_resource_ranges[PONResourceManager.ONU_ID_SHARED_IDX] = None
158 self.pon_resource_ranges[PONResourceManager.ALLOC_ID_SHARED_IDX] = None
159 self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_SHARED_IDX] = None
Girish Gowdruab836e92018-10-25 01:17:57 -0700160 self.pon_resource_ranges[PONResourceManager.FLOW_ID_SHARED_IDX] = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500161
162 self.shared_resource_mgrs = dict()
163 self.shared_resource_mgrs[PONResourceManager.ONU_ID_SHARED_IDX] = None
164 self.shared_resource_mgrs[PONResourceManager.ALLOC_ID_SHARED_IDX] = None
165 self.shared_resource_mgrs[PONResourceManager.GEMPORT_ID_SHARED_IDX] = None
Girish Gowdruab836e92018-10-25 01:17:57 -0700166 self.shared_resource_mgrs[PONResourceManager.FLOW_ID_SHARED_IDX] = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500167
168 self.shared_idx_by_type = dict()
169 self.shared_idx_by_type[PONResourceManager.ONU_ID] = PONResourceManager.ONU_ID_SHARED_IDX
170 self.shared_idx_by_type[PONResourceManager.ALLOC_ID] = PONResourceManager.ALLOC_ID_SHARED_IDX
171 self.shared_idx_by_type[PONResourceManager.GEMPORT_ID] = PONResourceManager.GEMPORT_ID_SHARED_IDX
Girish Gowdruab836e92018-10-25 01:17:57 -0700172 self.shared_idx_by_type[PONResourceManager.FLOW_ID] = PONResourceManager.FLOW_ID_SHARED_IDX
Craig Lutgen1dd47082018-10-23 13:12:26 -0500173
Craig Lutgen65423ce2018-10-29 23:24:21 -0500174 self.intf_ids = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500175
Girish Gowdru141ced82018-09-17 20:19:14 -0700176 except Exception as e:
177 self._log.exception("exception-in-init")
178 raise Exception(e)
179
Girish Gowdru141ced82018-09-17 20:19:14 -0700180 def init_resource_ranges_from_kv_store(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700181 """
182 Initialize PON resource ranges with config fetched from kv store.
Girish Gowdru141ced82018-09-17 20:19:14 -0700183
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700184 :return boolean: True if PON resource ranges initialized else false
185 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000186 self.olt_model = self._get_olt_model()
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700187 # Try to initialize the PON Resource Ranges from KV store based on the
Craig Lutgenf7601472018-11-02 13:27:41 +0000188 # OLT model key, if available
189 if self.olt_model is None:
190 self._log.info("device-model-unavailable--not-reading-from-kv-store")
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700191 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700192
Craig Lutgenf7601472018-11-02 13:27:41 +0000193 path = self.PON_RESOURCE_RANGE_CONFIG_PATH.format(self.olt_model)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700194 try:
195 # get resource from kv store
196 result = self._kv_store.get_from_kv_store(path)
197
198 if result is None:
199 self._log.debug("resource-range-config-unavailable-on-kvstore")
200 return False
201
202 resource_range_config = result
203
204 if resource_range_config is not None:
205 self.pon_resource_ranges = json.loads(resource_range_config)
206 self._log.debug("Init-resource-ranges-from-kvstore-success",
207 pon_resource_ranges=self.pon_resource_ranges,
208 path=path)
209 return True
210
211 except Exception as e:
212 self._log.exception("error-initializing-resource-range-from-kv-store",
213 e=e)
214 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700215
Craig Lutgen1dd47082018-10-23 13:12:26 -0500216 def update_range_(self, start_idx, start, end_idx, end, shared_idx, shared_pool_id, shared_resource_mgr):
217 if (start is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700218 (start_idx not in self.pon_resource_ranges or self.pon_resource_ranges[start_idx] < start):
219 self.pon_resource_ranges[start_idx] = start
Craig Lutgen1dd47082018-10-23 13:12:26 -0500220 if (end is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700221 (end_idx not in self.pon_resource_ranges or self.pon_resource_ranges[end_idx] > end):
222 self.pon_resource_ranges[end_idx] = end
Craig Lutgen1dd47082018-10-23 13:12:26 -0500223 if (shared_pool_id is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700224 (shared_idx not in self.pon_resource_ranges or self.pon_resource_ranges[shared_idx] is None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500225 self.pon_resource_ranges[shared_idx] = shared_pool_id
226 if (shared_resource_mgr is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700227 (shared_idx not in self.shared_resource_mgrs or self.shared_resource_mgrs[shared_idx] is None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500228 self.shared_resource_mgrs[shared_idx] = shared_resource_mgr
229
230 def update_ranges(self,
231 onu_id_start_idx=None,
232 onu_id_end_idx=None,
233 onu_id_shared_pool_id=None,
234 onu_id_shared_resource_mgr=None,
235 alloc_id_start_idx=None,
236 alloc_id_end_idx=None,
237 alloc_id_shared_pool_id=None,
238 alloc_id_shared_resource_mgr=None,
239 gemport_id_start_idx=None,
240 gemport_id_end_idx=None,
241 gemport_id_shared_pool_id=None,
Girish Gowdruab836e92018-10-25 01:17:57 -0700242 gemport_id_shared_resource_mgr=None,
243 flow_id_start_idx=None,
244 flow_id_end_idx=None,
245 flow_id_shared_pool_id=None,
246 flow_id_shared_resource_mgr=None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500247
248 self.update_range_(PONResourceManager.ONU_ID_START_IDX, onu_id_start_idx,
Girish Gowdruab836e92018-10-25 01:17:57 -0700249 PONResourceManager.ONU_ID_END_IDX, onu_id_end_idx,
250 PONResourceManager.ONU_ID_SHARED_IDX, onu_id_shared_pool_id,
251 onu_id_shared_resource_mgr)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500252
253 self.update_range_(PONResourceManager.ALLOC_ID_START_IDX, alloc_id_start_idx,
Girish Gowdruab836e92018-10-25 01:17:57 -0700254 PONResourceManager.ALLOC_ID_END_IDX, alloc_id_end_idx,
255 PONResourceManager.ALLOC_ID_SHARED_IDX, alloc_id_shared_pool_id,
256 alloc_id_shared_resource_mgr)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500257
258 self.update_range_(PONResourceManager.GEMPORT_ID_START_IDX, gemport_id_start_idx,
Girish Gowdruab836e92018-10-25 01:17:57 -0700259 PONResourceManager.GEMPORT_ID_END_IDX, gemport_id_end_idx,
260 PONResourceManager.GEMPORT_ID_SHARED_IDX, gemport_id_shared_pool_id,
261 gemport_id_shared_resource_mgr)
262
263 self.update_range_(PONResourceManager.FLOW_ID_START_IDX, flow_id_start_idx,
264 PONResourceManager.FLOW_ID_END_IDX, flow_id_end_idx,
265 PONResourceManager.FLOW_ID_SHARED_IDX, flow_id_shared_pool_id,
266 flow_id_shared_resource_mgr)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500267
268 def init_default_pon_resource_ranges(self,
269 onu_id_start_idx=1,
270 onu_id_end_idx=127,
271 onu_id_shared_pool_id=None,
Girish Gowdru141ced82018-09-17 20:19:14 -0700272 alloc_id_start_idx=1024,
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700273 alloc_id_end_idx=2816,
Craig Lutgen1dd47082018-10-23 13:12:26 -0500274 alloc_id_shared_pool_id=None,
275 gemport_id_start_idx=1024,
276 gemport_id_end_idx=8960,
277 gemport_id_shared_pool_id=None,
Girish Gowdruab836e92018-10-25 01:17:57 -0700278 flow_id_start_idx=1,
279 flow_id_end_idx=16383,
280 flow_id_shared_pool_id=None,
Craig Lutgen1dd47082018-10-23 13:12:26 -0500281 num_of_pon_ports=16,
282 intf_ids=None):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700283 """
284 Initialize default PON resource ranges
285
Craig Lutgen1dd47082018-10-23 13:12:26 -0500286 :param onu_id_start_idx: onu id start index
287 :param onu_id_end_idx: onu id end index
288 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700289 :param alloc_id_start_idx: alloc id start index
290 :param alloc_id_end_idx: alloc id end index
Craig Lutgen1dd47082018-10-23 13:12:26 -0500291 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
292 :param gemport_id_start_idx: gemport id start index
293 :param gemport_id_end_idx: gemport id end index
294 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
Girish Gowdruab836e92018-10-25 01:17:57 -0700295 :param flow_id_start_idx: flow id start index
296 :param flow_id_end_idx: flow id end index
297 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700298 :param num_of_pon_ports: number of PON ports
Craig Lutgen1dd47082018-10-23 13:12:26 -0500299 :param intf_ids: interfaces serviced by this manager
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700300 """
Girish Gowdru141ced82018-09-17 20:19:14 -0700301 self._log.info("initialize-default-resource-range-values")
Craig Lutgen1dd47082018-10-23 13:12:26 -0500302
303 self.update_ranges(onu_id_start_idx, onu_id_end_idx, onu_id_shared_pool_id, None,
304 alloc_id_start_idx, alloc_id_end_idx, alloc_id_shared_pool_id, None,
Girish Gowdruab836e92018-10-25 01:17:57 -0700305 gemport_id_start_idx, gemport_id_end_idx, gemport_id_shared_pool_id, None,
306 flow_id_start_idx, flow_id_end_idx, flow_id_shared_pool_id, None)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500307
308 if intf_ids is None:
309 intf_ids = range(0, num_of_pon_ports)
310
311 self.intf_ids = intf_ids
Girish Gowdru141ced82018-09-17 20:19:14 -0700312
313 def init_device_resource_pool(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700314 """
315 Initialize resource pool for all PON ports.
316 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500317
318 self._log.info("init-device-resource-pool", technology=self.technology,
Girish Gowdruab836e92018-10-25 01:17:57 -0700319 pon_resource_ranges=self.pon_resource_ranges)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500320
321 for i in self.intf_ids:
322 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ONU_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700323 if shared_pool_id is not None:
324 i = shared_pool_id
Girish Gowdru141ced82018-09-17 20:19:14 -0700325 self.init_resource_id_pool(
326 pon_intf_id=i,
327 resource_type=PONResourceManager.ONU_ID,
328 start_idx=self.pon_resource_ranges[
Craig Lutgen1dd47082018-10-23 13:12:26 -0500329 PONResourceManager.ONU_ID_START_IDX],
Girish Gowdru141ced82018-09-17 20:19:14 -0700330 end_idx=self.pon_resource_ranges[
Craig Lutgen1dd47082018-10-23 13:12:26 -0500331 PONResourceManager.ONU_ID_END_IDX])
Girish Gowdruab836e92018-10-25 01:17:57 -0700332 if shared_pool_id is not None:
333 break
Girish Gowdru141ced82018-09-17 20:19:14 -0700334
Craig Lutgen1dd47082018-10-23 13:12:26 -0500335 for i in self.intf_ids:
336 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ALLOC_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700337 if shared_pool_id is not None:
338 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500339 self.init_resource_id_pool(
340 pon_intf_id=i,
341 resource_type=PONResourceManager.ALLOC_ID,
342 start_idx=self.pon_resource_ranges[
343 PONResourceManager.ALLOC_ID_START_IDX],
344 end_idx=self.pon_resource_ranges[
345 PONResourceManager.ALLOC_ID_END_IDX])
Girish Gowdruab836e92018-10-25 01:17:57 -0700346 if shared_pool_id is not None:
347 break
Girish Gowdru141ced82018-09-17 20:19:14 -0700348
Craig Lutgen1dd47082018-10-23 13:12:26 -0500349 for i in self.intf_ids:
350 shared_pool_id = self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700351 if shared_pool_id is not None:
352 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500353 self.init_resource_id_pool(
354 pon_intf_id=i,
355 resource_type=PONResourceManager.GEMPORT_ID,
356 start_idx=self.pon_resource_ranges[
357 PONResourceManager.GEMPORT_ID_START_IDX],
358 end_idx=self.pon_resource_ranges[
359 PONResourceManager.GEMPORT_ID_END_IDX])
Girish Gowdruab836e92018-10-25 01:17:57 -0700360 if shared_pool_id is not None:
361 break
362
363 for i in self.intf_ids:
364 shared_pool_id = self.pon_resource_ranges[PONResourceManager.FLOW_ID_SHARED_IDX]
365 if shared_pool_id is not None:
366 i = shared_pool_id
367 self.init_resource_id_pool(
368 pon_intf_id=i,
369 resource_type=PONResourceManager.FLOW_ID,
370 start_idx=self.pon_resource_ranges[
371 PONResourceManager.FLOW_ID_START_IDX],
372 end_idx=self.pon_resource_ranges[
373 PONResourceManager.FLOW_ID_END_IDX])
374 if shared_pool_id is not None:
375 break
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700376
Girish Gowdru141ced82018-09-17 20:19:14 -0700377 def clear_device_resource_pool(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700378 """
379 Clear resource pool of all PON ports.
380 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500381 for i in self.intf_ids:
382 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ONU_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700383 if shared_pool_id is not None:
384 i = shared_pool_id
Girish Gowdru141ced82018-09-17 20:19:14 -0700385 self.clear_resource_id_pool(
386 pon_intf_id=i,
387 resource_type=PONResourceManager.ONU_ID,
388 )
Girish Gowdruab836e92018-10-25 01:17:57 -0700389 if shared_pool_id is not None:
390 break
Girish Gowdru141ced82018-09-17 20:19:14 -0700391
Craig Lutgen1dd47082018-10-23 13:12:26 -0500392 for i in self.intf_ids:
393 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ALLOC_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700394 if shared_pool_id is not None:
395 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500396 self.clear_resource_id_pool(
397 pon_intf_id=i,
398 resource_type=PONResourceManager.ALLOC_ID,
399 )
Girish Gowdruab836e92018-10-25 01:17:57 -0700400 if shared_pool_id is not None:
401 break
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700402
Craig Lutgen1dd47082018-10-23 13:12:26 -0500403 for i in self.intf_ids:
404 shared_pool_id = self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700405 if shared_pool_id is not None:
406 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500407 self.clear_resource_id_pool(
408 pon_intf_id=i,
409 resource_type=PONResourceManager.GEMPORT_ID,
410 )
Girish Gowdruab836e92018-10-25 01:17:57 -0700411 if shared_pool_id is not None:
412 break
413
414 for i in self.intf_ids:
415 shared_pool_id = self.pon_resource_ranges[PONResourceManager.FLOW_ID_SHARED_IDX]
416 if shared_pool_id is not None:
417 i = shared_pool_id
418 self.clear_resource_id_pool(
419 pon_intf_id=i,
420 resource_type=PONResourceManager.FLOW_ID,
421 )
422 if shared_pool_id is not None:
423 break
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700424
Girish Gowdru141ced82018-09-17 20:19:14 -0700425 def init_resource_id_pool(self, pon_intf_id, resource_type, start_idx,
426 end_idx):
427 """
428 Initialize Resource ID pool for a given Resource Type on a given PON Port
429
430 :param pon_intf_id: OLT PON interface id
431 :param resource_type: String to identify type of resource
432 :param start_idx: start index for onu id pool
433 :param end_idx: end index for onu id pool
434 :return boolean: True if resource id pool initialized else false
435 """
436 status = False
Craig Lutgen1dd47082018-10-23 13:12:26 -0500437
438 # delegate to the master instance if sharing enabled across instances
439 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
440 if shared_resource_mgr is not None and shared_resource_mgr is not self:
441 return shared_resource_mgr.init_resource_id_pool(pon_intf_id, resource_type,
Girish Gowdruab836e92018-10-25 01:17:57 -0700442 start_idx, end_idx)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500443
Girish Gowdru141ced82018-09-17 20:19:14 -0700444 path = self._get_path(pon_intf_id, resource_type)
445 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700446 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700447
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700448 try:
449 # In case of adapter reboot and reconciliation resource in kv store
450 # checked for its presence if not kv store update happens
451 resource = self._get_resource(path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700452
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700453 if resource is not None:
454 self._log.info("Resource-already-present-in-store", path=path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700455 status = True
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700456 else:
457 resource = self._format_resource(pon_intf_id, start_idx,
458 end_idx)
459 self._log.info("Resource-initialized", path=path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700460
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700461 # Add resource as json in kv store.
462 result = self._kv_store.update_to_kv_store(path, resource)
463 if result is True:
464 status = True
465
466 except Exception as e:
467 self._log.exception("error-initializing-resource-pool", e=e)
468
469 return status
470
Girish Gowdru141ced82018-09-17 20:19:14 -0700471 def get_resource_id(self, pon_intf_id, resource_type, num_of_id=1):
472 """
Girish Gowdruab836e92018-10-25 01:17:57 -0700473 Create alloc/gemport/onu/flow id for given OLT PON interface.
Girish Gowdru141ced82018-09-17 20:19:14 -0700474
475 :param pon_intf_id: OLT PON interface id
476 :param resource_type: String to identify type of resource
477 :param num_of_id: required number of ids
478 :return list/int/None: list, int or None if resource type is
479 alloc_id/gemport_id, onu_id or invalid type
480 respectively
481 """
482 result = None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700483
Girish Gowdruab836e92018-10-25 01:17:57 -0700484 if num_of_id < 1:
485 self._log.error("invalid-num-of-resources-requested")
486 return result
487
Craig Lutgen1dd47082018-10-23 13:12:26 -0500488 # delegate to the master instance if sharing enabled across instances
489 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
490 if shared_resource_mgr is not None and shared_resource_mgr is not self:
Craig Lutgen66dbf622018-11-18 12:24:54 -0600491 return shared_resource_mgr.get_resource_id(pon_intf_id, resource_type, num_of_id)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700492
Girish Gowdru141ced82018-09-17 20:19:14 -0700493 path = self._get_path(pon_intf_id, resource_type)
494 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700495 return result
Girish Gowdru141ced82018-09-17 20:19:14 -0700496
Girish Gowdru141ced82018-09-17 20:19:14 -0700497 try:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700498 resource = self._get_resource(path)
Girish Gowdruab836e92018-10-25 01:17:57 -0700499 if resource is not None and \
500 (resource_type == PONResourceManager.ONU_ID or
501 resource_type == PONResourceManager.FLOW_ID):
Girish Gowdru141ced82018-09-17 20:19:14 -0700502 result = self._generate_next_id(resource)
503 elif resource is not None and (
504 resource_type == PONResourceManager.GEMPORT_ID or
505 resource_type == PONResourceManager.ALLOC_ID):
Girish Gowdruab836e92018-10-25 01:17:57 -0700506 if num_of_id == 1:
507 result = self._generate_next_id(resource)
508 else:
509 result = list()
510 while num_of_id > 0:
511 result.append(self._generate_next_id(resource))
512 num_of_id -= 1
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700513 else:
514 raise Exception("get-resource-failed")
Girish Gowdru141ced82018-09-17 20:19:14 -0700515
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700516 self._log.debug("Get-" + resource_type + "-success", result=result,
517 path=path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700518 # Update resource in kv store
519 self._update_resource(path, resource)
520
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700521 except Exception as e:
Girish Gowdru141ced82018-09-17 20:19:14 -0700522 self._log.exception("Get-" + resource_type + "-id-failed",
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700523 path=path, e=e)
524 return result
Girish Gowdru141ced82018-09-17 20:19:14 -0700525
Girish Gowdru141ced82018-09-17 20:19:14 -0700526 def free_resource_id(self, pon_intf_id, resource_type, release_content):
527 """
Girish Gowdruab836e92018-10-25 01:17:57 -0700528 Release alloc/gemport/onu/flow id for given OLT PON interface.
Girish Gowdru141ced82018-09-17 20:19:14 -0700529
530 :param pon_intf_id: OLT PON interface id
531 :param resource_type: String to identify type of resource
532 :param release_content: required number of ids
533 :return boolean: True if all IDs in given release_content released
534 else False
535 """
536 status = False
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700537
Craig Lutgen1dd47082018-10-23 13:12:26 -0500538 # delegate to the master instance if sharing enabled across instances
539 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
540 if shared_resource_mgr is not None and shared_resource_mgr is not self:
541 return shared_resource_mgr.free_resource_id(pon_intf_id, resource_type)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700542
Girish Gowdru141ced82018-09-17 20:19:14 -0700543 path = self._get_path(pon_intf_id, resource_type)
544 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700545 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700546
Girish Gowdru141ced82018-09-17 20:19:14 -0700547 try:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700548 resource = self._get_resource(path)
Girish Gowdruab836e92018-10-25 01:17:57 -0700549 if resource is not None and (
550 resource_type == PONResourceManager.ONU_ID or
551 resource_type == PONResourceManager.FLOW_ID):
Girish Gowdru141ced82018-09-17 20:19:14 -0700552 self._release_id(resource, release_content)
553 elif resource is not None and (
554 resource_type == PONResourceManager.ALLOC_ID or
555 resource_type == PONResourceManager.GEMPORT_ID):
556 for content in release_content:
557 self._release_id(resource, content)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700558 else:
559 raise Exception("get-resource-failed")
560
Girish Gowdru141ced82018-09-17 20:19:14 -0700561 self._log.debug("Free-" + resource_type + "-success", path=path)
562
563 # Update resource in kv store
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700564 status = self._update_resource(path, resource)
Girish Gowdru141ced82018-09-17 20:19:14 -0700565
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700566 except Exception as e:
567 self._log.exception("Free-" + resource_type + "-failed",
568 path=path, e=e)
569 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700570
Girish Gowdru141ced82018-09-17 20:19:14 -0700571 def clear_resource_id_pool(self, pon_intf_id, resource_type):
572 """
573 Clear Resource Pool for a given Resource Type on a given PON Port.
574
575 :return boolean: True if removed else False
576 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500577
578 # delegate to the master instance if sharing enabled across instances
579 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
580 if shared_resource_mgr is not None and shared_resource_mgr is not self:
581 return shared_resource_mgr.clear_resource_id_pool(pon_intf_id, resource_type)
582
Girish Gowdru141ced82018-09-17 20:19:14 -0700583 path = self._get_path(pon_intf_id, resource_type)
584 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700585 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700586
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700587 try:
588 result = self._kv_store.remove_from_kv_store(path)
589 if result is True:
590 self._log.debug("Resource-pool-cleared",
591 device_id=self.device_id,
592 path=path)
593 return True
594 except Exception as e:
595 self._log.exception("error-clearing-resource-pool", e=e)
596
Girish Gowdru141ced82018-09-17 20:19:14 -0700597 self._log.error("Clear-resource-pool-failed", device_id=self.device_id,
598 path=path)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700599 return False
600
601 def init_resource_map(self, pon_intf_onu_id):
602 """
603 Initialize resource map
604
605 :param pon_intf_onu_id: reference of PON interface id and onu id
606 """
607 # initialize pon_intf_onu_id tuple to alloc_ids map
608 alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
609 self.device_id, str(pon_intf_onu_id)
610 )
611 alloc_ids = list()
612 self._kv_store.update_to_kv_store(
613 alloc_id_path, json.dumps(alloc_ids)
614 )
615
616 # initialize pon_intf_onu_id tuple to gemport_ids map
617 gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
618 self.device_id, str(pon_intf_onu_id)
619 )
620 gemport_ids = list()
621 self._kv_store.update_to_kv_store(
622 gemport_id_path, json.dumps(gemport_ids)
623 )
624
625 def remove_resource_map(self, pon_intf_onu_id):
626 """
627 Remove resource map
628
629 :param pon_intf_onu_id: reference of PON interface id and onu id
630 """
631 # remove pon_intf_onu_id tuple to alloc_ids map
632 alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
633 self.device_id, str(pon_intf_onu_id)
634 )
635 self._kv_store.remove_from_kv_store(alloc_id_path)
636
637 # remove pon_intf_onu_id tuple to gemport_ids map
638 gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
639 self.device_id, str(pon_intf_onu_id)
640 )
641 self._kv_store.remove_from_kv_store(gemport_id_path)
642
643 def get_current_alloc_ids_for_onu(self, pon_intf_onu_id):
644 """
645 Get currently configured alloc ids for given pon_intf_onu_id
646
647 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700648
649 :return list: List of alloc_ids if available, else None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700650 """
651 path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
652 self.device_id,
653 str(pon_intf_onu_id))
654 value = self._kv_store.get_from_kv_store(path)
655 if value is not None:
656 alloc_id_list = json.loads(value)
657 if len(alloc_id_list) > 0:
658 return alloc_id_list
659
660 return None
661
662 def get_current_gemport_ids_for_onu(self, pon_intf_onu_id):
663 """
664 Get currently configured gemport ids for given pon_intf_onu_id
665
666 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700667
668 :return list: List of gemport IDs if available, else None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700669 """
670
671 path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
672 self.device_id,
673 str(pon_intf_onu_id))
674 value = self._kv_store.get_from_kv_store(path)
675 if value is not None:
676 gemport_id_list = json.loads(value)
677 if len(gemport_id_list) > 0:
678 return gemport_id_list
679
680 return None
681
Girish Gowdruab836e92018-10-25 01:17:57 -0700682 def get_current_flow_ids_for_onu(self, pon_intf_onu_id):
683 """
684 Get currently configured flow ids for given pon_intf_onu_id
685
686 :param pon_intf_onu_id: reference of PON interface id and onu id
687
688 :return list: List of Flow IDs if available, else None
689 """
690
691 path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
692 self.device_id,
693 str(pon_intf_onu_id))
694 value = self._kv_store.get_from_kv_store(path)
695 if value is not None:
696 flow_id_list = json.loads(value)
697 assert(isinstance(flow_id_list, list))
698 if len(flow_id_list) > 0:
699 return flow_id_list
700
701 return None
702
703 def get_flow_id_info(self, pon_intf_onu_id, flow_id):
704 """
705 Get flow_id details configured for the ONU.
706
707 :param pon_intf_onu_id: reference of PON interface id and onu id
708 :param flow_id: Flow Id reference
709
710 :return blob: Flow data blob if available, else None
711 """
712
713 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
714 self.device_id,
715 str(pon_intf_onu_id),
716 flow_id)
717 value = self._kv_store.get_from_kv_store(path)
718 if value is not None:
719 return ast.literal_eval(value)
720
721 return None
722
723 def remove_flow_id_info(self, pon_intf_onu_id, flow_id):
724 """
725 Get flow_id details configured for the ONU.
726
727 :param pon_intf_onu_id: reference of PON interface id and onu id
728 :param flow_id: Flow Id reference
729
730 """
731
732 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
733 self.device_id,
734 str(pon_intf_onu_id),
735 flow_id)
736 self._kv_store.remove_from_kv_store(path)
737
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700738 def update_alloc_ids_for_onu(self, pon_intf_onu_id, alloc_ids):
739 """
740 Update currently configured alloc ids for given pon_intf_onu_id
741
742 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700743 :param alloc_ids: list of alloc ids
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700744 """
745 path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
746 self.device_id, str(pon_intf_onu_id)
747 )
748 self._kv_store.update_to_kv_store(
749 path, json.dumps(alloc_ids)
750 )
751
752 def update_gemport_ids_for_onu(self, pon_intf_onu_id, gemport_ids):
753 """
754 Update currently configured gemport ids for given pon_intf_onu_id
755
756 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700757 :param gemport_ids: list of gem port ids
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700758 """
759 path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
760 self.device_id, str(pon_intf_onu_id)
761 )
762 self._kv_store.update_to_kv_store(
763 path, json.dumps(gemport_ids)
764 )
765
Girish Gowdruab836e92018-10-25 01:17:57 -0700766 def update_flow_id_for_onu(self, pon_intf_onu_id, flow_id, add=True):
767 """
768 Update the flow_id list of the ONU (add or remove flow_id from the list)
769
770 :param pon_intf_onu_id: reference of PON interface id and onu id
771 :param flow_id: flow ID
772 :param add: Boolean flag to indicate whether the flow_id should be
773 added or removed from the list. Defaults to adding the flow.
774 """
775 path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
776 self.device_id, str(pon_intf_onu_id)
777 )
778 current_flow_ids = self.get_current_flow_ids_for_onu(pon_intf_onu_id)
779 if not isinstance(current_flow_ids, list):
780 # When the first flow_id is being added, the current_flow_ids is None
781 current_flow_ids = list()
782
783 if add:
784 if flow_id not in current_flow_ids:
785 current_flow_ids.append(flow_id)
786 else:
787 if flow_id in current_flow_ids:
788 current_flow_ids.remove(flow_id)
789
790 self._kv_store.update_to_kv_store(path, current_flow_ids)
791
792 def update_flow_id_info_for_onu(self, pon_intf_onu_id, flow_id, flow_data):
793 """
794 Update any metadata associated with the flow_id. The flow_data could be json
795 or any of other data structure. The resource manager doesnt care
796
797 :param pon_intf_onu_id: reference of PON interface id and onu id
798 :param flow_id: Flow ID
799 :param flow_data: Flow data blob
800 """
801 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
802 self.device_id, str(pon_intf_onu_id), flow_id
803 )
804
805 if not self._kv_store.update_to_kv_store(path, flow_data):
806 self._log.error("flow-info-update-failed", path=path, flow_id=flow_id)
807
Craig Lutgenf7601472018-11-02 13:27:41 +0000808 def _get_olt_model(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700809 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000810 Get olt model variant
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700811
Craig Lutgenf7601472018-11-02 13:27:41 +0000812 :return: type of olt model
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700813 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000814 olt_model = None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700815 if self.extra_args and len(self.extra_args) > 0:
816 parser = OltVendorArgumentParser(add_help=False)
Craig Lutgenf7601472018-11-02 13:27:41 +0000817 parser.add_argument(PONResourceManager.OLT_MODEL_ARG, '-m', action='store', default='default')
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700818 try:
819 args = parser.parse_args(shlex.split(self.extra_args))
820 self._log.debug('parsing-extra-arguments', args=args)
Craig Lutgenf7601472018-11-02 13:27:41 +0000821 olt_model = args.olt_model
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700822 except ArgumentError as e:
823 self._log.exception('invalid-arguments: {}', e=e)
824 except Exception as e:
825 self._log.exception('option-parsing-error: {}', e=e)
826
Craig Lutgenf7601472018-11-02 13:27:41 +0000827 self._log.debug('olt-model', olt_model=olt_model)
828 return olt_model
Girish Gowdru141ced82018-09-17 20:19:14 -0700829
830 def _generate_next_id(self, resource):
831 """
832 Generate unique id having OFFSET as start index.
833
834 :param resource: resource used to generate ID
835 :return int: generated id
836 """
837 pos = resource[PONResourceManager.POOL].find('0b0')
838 resource[PONResourceManager.POOL].set(1, pos)
839 return pos[0] + resource[PONResourceManager.START_IDX]
840
841 def _release_id(self, resource, unique_id):
842 """
843 Release unique id having OFFSET as start index.
844
845 :param resource: resource used to release ID
846 :param unique_id: id need to be released
847 """
848 pos = ((int(unique_id)) - resource[PONResourceManager.START_IDX])
849 resource[PONResourceManager.POOL].set(0, pos)
850
851 def _get_path(self, pon_intf_id, resource_type):
852 """
853 Get path for given resource type.
854
855 :param pon_intf_id: OLT PON interface id
856 :param resource_type: String to identify type of resource
857 :return: path for given resource type
858 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500859
860 shared_pool_id = self.pon_resource_ranges[self.shared_idx_by_type[resource_type]]
Girish Gowdruab836e92018-10-25 01:17:57 -0700861 if shared_pool_id is not None:
862 pon_intf_id = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500863
Girish Gowdru141ced82018-09-17 20:19:14 -0700864 path = None
865 if resource_type == PONResourceManager.ONU_ID:
866 path = self._get_onu_id_resource_path(pon_intf_id)
867 elif resource_type == PONResourceManager.ALLOC_ID:
868 path = self._get_alloc_id_resource_path(pon_intf_id)
869 elif resource_type == PONResourceManager.GEMPORT_ID:
870 path = self._get_gemport_id_resource_path(pon_intf_id)
Girish Gowdruab836e92018-10-25 01:17:57 -0700871 elif resource_type == PONResourceManager.FLOW_ID:
872 path = self._get_flow_id_resource_path(pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700873 else:
874 self._log.error("invalid-resource-pool-identifier")
875 return path
876
Girish Gowdruab836e92018-10-25 01:17:57 -0700877 def _get_flow_id_resource_path(self, pon_intf_id):
878 """
879 Get flow id resource path.
880
881 :param pon_intf_id: OLT PON interface id
882 :return: flow id resource path
883 """
884 return PONResourceManager.FLOW_ID_POOL_PATH.format(
885 self.device_id, pon_intf_id)
886
Girish Gowdru141ced82018-09-17 20:19:14 -0700887 def _get_alloc_id_resource_path(self, pon_intf_id):
888 """
889 Get alloc id resource path.
890
891 :param pon_intf_id: OLT PON interface id
892 :return: alloc id resource path
893 """
894 return PONResourceManager.ALLOC_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700895 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700896
897 def _get_gemport_id_resource_path(self, pon_intf_id):
898 """
899 Get gemport id resource path.
900
901 :param pon_intf_id: OLT PON interface id
902 :return: gemport id resource path
903 """
904 return PONResourceManager.GEMPORT_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700905 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700906
907 def _get_onu_id_resource_path(self, pon_intf_id):
908 """
909 Get onu id resource path.
910
911 :param pon_intf_id: OLT PON interface id
912 :return: onu id resource path
913 """
914 return PONResourceManager.ONU_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700915 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700916
Girish Gowdru141ced82018-09-17 20:19:14 -0700917 def _update_resource(self, path, resource):
918 """
919 Update resource in resource kv store.
920
921 :param path: path to update resource
922 :param resource: resource need to be updated
923 :return boolean: True if resource updated in kv store else False
924 """
925 resource[PONResourceManager.POOL] = \
926 resource[PONResourceManager.POOL].bin
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700927 result = self._kv_store.update_to_kv_store(path, json.dumps(resource))
928 if result is True:
929 return True
930 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700931
Girish Gowdru141ced82018-09-17 20:19:14 -0700932 def _get_resource(self, path):
933 """
934 Get resource from kv store.
935
936 :param path: path to get resource
937 :return: resource if resource present in kv store else None
938 """
939 # get resource from kv store
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700940 result = self._kv_store.get_from_kv_store(path)
941 if result is None:
942 return result
943 self._log.info("dumping resource", result=result)
944 resource = result
Girish Gowdru141ced82018-09-17 20:19:14 -0700945
946 if resource is not None:
947 # decode resource fetched from backend store to dictionary
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700948 resource = json.loads(resource)
Girish Gowdru141ced82018-09-17 20:19:14 -0700949
950 # resource pool in backend store stored as binary string whereas to
951 # access the pool to generate/release IDs it need to be converted
952 # as BitArray
953 resource[PONResourceManager.POOL] = \
954 BitArray('0b' + resource[PONResourceManager.POOL])
955
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700956 return resource
Girish Gowdru141ced82018-09-17 20:19:14 -0700957
958 def _format_resource(self, pon_intf_id, start_idx, end_idx):
959 """
960 Format resource as json.
961
962 :param pon_intf_id: OLT PON interface id
963 :param start_idx: start index for id pool
964 :param end_idx: end index for id pool
965 :return dictionary: resource formatted as dictionary
966 """
967 # Format resource as json to be stored in backend store
968 resource = dict()
969 resource[PONResourceManager.PON_INTF_ID] = pon_intf_id
970 resource[PONResourceManager.START_IDX] = start_idx
971 resource[PONResourceManager.END_IDX] = end_idx
972
973 # resource pool stored in backend store as binary string
974 resource[PONResourceManager.POOL] = BitArray(end_idx).bin
975
976 return json.dumps(resource)