blob: a88b4072d31a35c77baf577ee984f76324e157d2 [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
Craig Lutgenabd9c842018-11-15 23:58:27 +000046 UNI_ID = 'UNI_ID'
Girish Gowdru141ced82018-09-17 20:19:14 -070047 ONU_ID = 'ONU_ID'
48 ALLOC_ID = 'ALLOC_ID'
49 GEMPORT_ID = 'GEMPORT_ID'
Girish Gowdruab836e92018-10-25 01:17:57 -070050 FLOW_ID = 'FLOW_ID'
Girish Gowdru141ced82018-09-17 20:19:14 -070051
Craig Lutgenf7601472018-11-02 13:27:41 +000052 # Constants for passing command line arugments
53 OLT_MODEL_ARG = '--olt_model'
54
55 # The resource ranges for a given device model should be placed
56 # at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
Girish Gowdru141ced82018-09-17 20:19:14 -070057 # path on the KV store.
58 # If Resource Range parameters are to be read from the external KV store,
59 # they are expected to be stored in the following format.
60 # Note: All parameters are MANDATORY for now.
61 '''
Girish Gowdru1e77ea02018-09-24 09:10:35 -070062 {
63 "onu_id_start": 1,
64 "onu_id_end": 127,
65 "alloc_id_start": 1024,
66 "alloc_id_end": 2816,
67 "gemport_id_start": 1024,
68 "gemport_id_end": 8960,
Girish Gowdruab836e92018-10-25 01:17:57 -070069 "flow_id_start": 1,
70 "flow_id_end": 16383,
Craig Lutgenabd9c842018-11-15 23:58:27 +000071 "uni_id_start": 0,
72 "uni_id_end": 0,
Girish Gowdru1e77ea02018-09-24 09:10:35 -070073 "pon_ports": 16
74 }
75
Girish Gowdru141ced82018-09-17 20:19:14 -070076 '''
77 # constants used as keys to reference the resource range parameters from
78 # and external KV store.
Craig Lutgenabd9c842018-11-15 23:58:27 +000079 UNI_ID_START_IDX = "uni_id_start"
80 UNI_ID_END_IDX = "uni_id_end"
Craig Lutgen1dd47082018-10-23 13:12:26 -050081 ONU_ID_START_IDX = "onu_id_start"
82 ONU_ID_END_IDX = "onu_id_end"
83 ONU_ID_SHARED_IDX = "onu_id_shared"
Girish Gowdru1e77ea02018-09-24 09:10:35 -070084 ALLOC_ID_START_IDX = "alloc_id_start"
85 ALLOC_ID_END_IDX = "alloc_id_end"
Craig Lutgen1dd47082018-10-23 13:12:26 -050086 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
87 GEMPORT_ID_START_IDX = "gemport_id_start"
88 GEMPORT_ID_END_IDX = "gemport_id_end"
89 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
Girish Gowdruab836e92018-10-25 01:17:57 -070090 FLOW_ID_START_IDX = "flow_id_start"
91 FLOW_ID_END_IDX = "flow_id_end"
92 FLOW_ID_SHARED_IDX = "flow_id_shared"
Girish Gowdru1e77ea02018-09-24 09:10:35 -070093 NUM_OF_PON_PORT = "pon_ports"
Girish Gowdru141ced82018-09-17 20:19:14 -070094
95 # PON Resource range configuration on the KV store.
Craig Lutgenf7601472018-11-02 13:27:41 +000096 # Format: 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
Girish Gowdru1e77ea02018-09-24 09:10:35 -070097 # The KV store backend is initialized with a path prefix and we need to
98 # provide only the suffix.
99 PON_RESOURCE_RANGE_CONFIG_PATH = 'resource_ranges/{}'
Girish Gowdru141ced82018-09-17 20:19:14 -0700100
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700101 # resource path suffix
102 ALLOC_ID_POOL_PATH = '{}/alloc_id_pool/{}'
103 GEMPORT_ID_POOL_PATH = '{}/gemport_id_pool/{}'
104 ONU_ID_POOL_PATH = '{}/onu_id_pool/{}'
Girish Gowdruab836e92018-10-25 01:17:57 -0700105 FLOW_ID_POOL_PATH = '{}/flow_id_pool/{}'
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700106
107 # Path on the KV store for storing list of alloc IDs for a given ONU
108 # Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
109 ALLOC_ID_RESOURCE_MAP_PATH = '{}/{}/alloc_ids'
110
111 # Path on the KV store for storing list of gemport IDs for a given ONU
112 # Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
113 GEMPORT_ID_RESOURCE_MAP_PATH = '{}/{}/gemport_ids'
Girish Gowdru141ced82018-09-17 20:19:14 -0700114
Girish Gowdruab836e92018-10-25 01:17:57 -0700115 # Path on the KV store for storing list of Flow IDs for a given ONU
116 # Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
117 FLOW_ID_RESOURCE_MAP_PATH = '{}/{}/flow_ids'
118
119 # Flow Id info: Use to store more metadata associated with the flow_id
120 # Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
121 FLOW_ID_INFO_PATH = '{}/{}/flow_id_info/{}'
122
Girish Gowdru141ced82018-09-17 20:19:14 -0700123 # Constants for internal usage.
124 PON_INTF_ID = 'pon_intf_id'
125 START_IDX = 'start_idx'
126 END_IDX = 'end_idx'
127 POOL = 'pool'
128
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700129 def __init__(self, technology, extra_args, device_id,
Girish Gowdru141ced82018-09-17 20:19:14 -0700130 backend, host, port):
131 """
132 Create PONResourceManager object.
133
134 :param technology: PON technology
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700135 :param: extra_args: This string contains extra arguments passed during
136 pre-provisioning of OLT and specifies the OLT Vendor type
Girish Gowdru141ced82018-09-17 20:19:14 -0700137 :param device_id: OLT device id
138 :param backend: backend store
139 :param host: ip of backend store
140 :param port: port on which backend store listens
141 :raises exception when invalid backend store passed as an argument
142 """
143 # logger
144 self._log = structlog.get_logger()
145
146 try:
Girish Gowdru141ced82018-09-17 20:19:14 -0700147 self.technology = technology
Craig Lutgenf7601472018-11-02 13:27:41 +0000148 self.extra_args = extra_args
Girish Gowdru141ced82018-09-17 20:19:14 -0700149 self.device_id = device_id
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700150 self.backend = backend
151 self.host = host
152 self.port = port
Craig Lutgenf7601472018-11-02 13:27:41 +0000153 self.olt_model = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500154
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700155 self._kv_store = ResourceKvStore(technology, device_id, backend,
156 host, port)
Girish Gowdruab836e92018-10-25 01:17:57 -0700157 self.tech_profile = TechProfile(self)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500158
Girish Gowdru141ced82018-09-17 20:19:14 -0700159 # Below attribute, pon_resource_ranges, should be initialized
160 # by reading from KV store.
161 self.pon_resource_ranges = dict()
Craig Lutgen1dd47082018-10-23 13:12:26 -0500162 self.pon_resource_ranges[PONResourceManager.ONU_ID_SHARED_IDX] = None
163 self.pon_resource_ranges[PONResourceManager.ALLOC_ID_SHARED_IDX] = None
164 self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_SHARED_IDX] = None
Girish Gowdruab836e92018-10-25 01:17:57 -0700165 self.pon_resource_ranges[PONResourceManager.FLOW_ID_SHARED_IDX] = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500166
167 self.shared_resource_mgrs = dict()
168 self.shared_resource_mgrs[PONResourceManager.ONU_ID_SHARED_IDX] = None
169 self.shared_resource_mgrs[PONResourceManager.ALLOC_ID_SHARED_IDX] = None
170 self.shared_resource_mgrs[PONResourceManager.GEMPORT_ID_SHARED_IDX] = None
Girish Gowdruab836e92018-10-25 01:17:57 -0700171 self.shared_resource_mgrs[PONResourceManager.FLOW_ID_SHARED_IDX] = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500172
173 self.shared_idx_by_type = dict()
174 self.shared_idx_by_type[PONResourceManager.ONU_ID] = PONResourceManager.ONU_ID_SHARED_IDX
175 self.shared_idx_by_type[PONResourceManager.ALLOC_ID] = PONResourceManager.ALLOC_ID_SHARED_IDX
176 self.shared_idx_by_type[PONResourceManager.GEMPORT_ID] = PONResourceManager.GEMPORT_ID_SHARED_IDX
Girish Gowdruab836e92018-10-25 01:17:57 -0700177 self.shared_idx_by_type[PONResourceManager.FLOW_ID] = PONResourceManager.FLOW_ID_SHARED_IDX
Craig Lutgen1dd47082018-10-23 13:12:26 -0500178
Craig Lutgen65423ce2018-10-29 23:24:21 -0500179 self.intf_ids = None
Craig Lutgen1dd47082018-10-23 13:12:26 -0500180
Girish Gowdru141ced82018-09-17 20:19:14 -0700181 except Exception as e:
182 self._log.exception("exception-in-init")
183 raise Exception(e)
184
Girish Gowdru141ced82018-09-17 20:19:14 -0700185 def init_resource_ranges_from_kv_store(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700186 """
187 Initialize PON resource ranges with config fetched from kv store.
Girish Gowdru141ced82018-09-17 20:19:14 -0700188
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700189 :return boolean: True if PON resource ranges initialized else false
190 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000191 self.olt_model = self._get_olt_model()
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700192 # Try to initialize the PON Resource Ranges from KV store based on the
Craig Lutgenf7601472018-11-02 13:27:41 +0000193 # OLT model key, if available
194 if self.olt_model is None:
195 self._log.info("device-model-unavailable--not-reading-from-kv-store")
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700196 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700197
Craig Lutgenf7601472018-11-02 13:27:41 +0000198 path = self.PON_RESOURCE_RANGE_CONFIG_PATH.format(self.olt_model)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700199 try:
200 # get resource from kv store
201 result = self._kv_store.get_from_kv_store(path)
202
203 if result is None:
204 self._log.debug("resource-range-config-unavailable-on-kvstore")
205 return False
206
207 resource_range_config = result
208
209 if resource_range_config is not None:
Craig Lutgenabd9c842018-11-15 23:58:27 +0000210 # update internal ranges from kv ranges. If there are missing
211 # values in the KV profile, continue to use the defaults
212 for key,value in json.loads(resource_range_config): self.pon_resource_ranges[key] = value
213
214 # initialize optional elements that may not be in the profile
215 if self.pon_resource_ranges[PONResourceManager.UNI_ID_START_IDX] is None:
216 self.pon_resource_ranges[PONResourceManager.UNI_ID_START_IDX] = 0
217 if self.pon_resource_ranges[PONResourceManager.UNI_ID_END_IDX] is None:
218 self.pon_resource_ranges[PONResourceManager.UNI_ID_END_IDX] = 0
219
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700220 self._log.debug("Init-resource-ranges-from-kvstore-success",
221 pon_resource_ranges=self.pon_resource_ranges,
222 path=path)
223 return True
224
225 except Exception as e:
226 self._log.exception("error-initializing-resource-range-from-kv-store",
227 e=e)
228 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700229
Craig Lutgenabd9c842018-11-15 23:58:27 +0000230 def update_range_(self, start_idx, start, end_idx, end, shared_idx = None, shared_pool_id = None,
231 shared_resource_mgr = None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500232 if (start is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700233 (start_idx not in self.pon_resource_ranges or self.pon_resource_ranges[start_idx] < start):
234 self.pon_resource_ranges[start_idx] = start
Craig Lutgen1dd47082018-10-23 13:12:26 -0500235 if (end is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700236 (end_idx not in self.pon_resource_ranges or self.pon_resource_ranges[end_idx] > end):
237 self.pon_resource_ranges[end_idx] = end
Craig Lutgen1dd47082018-10-23 13:12:26 -0500238 if (shared_pool_id is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700239 (shared_idx not in self.pon_resource_ranges or self.pon_resource_ranges[shared_idx] is None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500240 self.pon_resource_ranges[shared_idx] = shared_pool_id
241 if (shared_resource_mgr is not None) and \
Girish Gowdruab836e92018-10-25 01:17:57 -0700242 (shared_idx not in self.shared_resource_mgrs or self.shared_resource_mgrs[shared_idx] is None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500243 self.shared_resource_mgrs[shared_idx] = shared_resource_mgr
244
245 def update_ranges(self,
246 onu_id_start_idx=None,
247 onu_id_end_idx=None,
248 onu_id_shared_pool_id=None,
249 onu_id_shared_resource_mgr=None,
250 alloc_id_start_idx=None,
251 alloc_id_end_idx=None,
252 alloc_id_shared_pool_id=None,
253 alloc_id_shared_resource_mgr=None,
254 gemport_id_start_idx=None,
255 gemport_id_end_idx=None,
256 gemport_id_shared_pool_id=None,
Girish Gowdruab836e92018-10-25 01:17:57 -0700257 gemport_id_shared_resource_mgr=None,
258 flow_id_start_idx=None,
259 flow_id_end_idx=None,
260 flow_id_shared_pool_id=None,
Craig Lutgenabd9c842018-11-15 23:58:27 +0000261 flow_id_shared_resource_mgr=None,
262 uni_id_start_idx=None,
263 uni_id_end_idx=None):
Craig Lutgen1dd47082018-10-23 13:12:26 -0500264
265 self.update_range_(PONResourceManager.ONU_ID_START_IDX, onu_id_start_idx,
Girish Gowdruab836e92018-10-25 01:17:57 -0700266 PONResourceManager.ONU_ID_END_IDX, onu_id_end_idx,
267 PONResourceManager.ONU_ID_SHARED_IDX, onu_id_shared_pool_id,
268 onu_id_shared_resource_mgr)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500269
270 self.update_range_(PONResourceManager.ALLOC_ID_START_IDX, alloc_id_start_idx,
Girish Gowdruab836e92018-10-25 01:17:57 -0700271 PONResourceManager.ALLOC_ID_END_IDX, alloc_id_end_idx,
272 PONResourceManager.ALLOC_ID_SHARED_IDX, alloc_id_shared_pool_id,
273 alloc_id_shared_resource_mgr)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500274
275 self.update_range_(PONResourceManager.GEMPORT_ID_START_IDX, gemport_id_start_idx,
Girish Gowdruab836e92018-10-25 01:17:57 -0700276 PONResourceManager.GEMPORT_ID_END_IDX, gemport_id_end_idx,
277 PONResourceManager.GEMPORT_ID_SHARED_IDX, gemport_id_shared_pool_id,
278 gemport_id_shared_resource_mgr)
279
280 self.update_range_(PONResourceManager.FLOW_ID_START_IDX, flow_id_start_idx,
281 PONResourceManager.FLOW_ID_END_IDX, flow_id_end_idx,
282 PONResourceManager.FLOW_ID_SHARED_IDX, flow_id_shared_pool_id,
283 flow_id_shared_resource_mgr)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500284
Craig Lutgenabd9c842018-11-15 23:58:27 +0000285 self.update_range_(PONResourceManager.UNI_ID_START_IDX, uni_id_start_idx,
286 PONResourceManager.UNI_ID_END_IDX, uni_id_end_idx)
287
Craig Lutgen1dd47082018-10-23 13:12:26 -0500288 def init_default_pon_resource_ranges(self,
289 onu_id_start_idx=1,
290 onu_id_end_idx=127,
291 onu_id_shared_pool_id=None,
Girish Gowdru141ced82018-09-17 20:19:14 -0700292 alloc_id_start_idx=1024,
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700293 alloc_id_end_idx=2816,
Craig Lutgen1dd47082018-10-23 13:12:26 -0500294 alloc_id_shared_pool_id=None,
295 gemport_id_start_idx=1024,
296 gemport_id_end_idx=8960,
297 gemport_id_shared_pool_id=None,
Girish Gowdruab836e92018-10-25 01:17:57 -0700298 flow_id_start_idx=1,
299 flow_id_end_idx=16383,
300 flow_id_shared_pool_id=None,
Craig Lutgenabd9c842018-11-15 23:58:27 +0000301 uni_id_start_idx=0,
302 uni_id_end_idx=0,
Craig Lutgen1dd47082018-10-23 13:12:26 -0500303 num_of_pon_ports=16,
304 intf_ids=None):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700305 """
306 Initialize default PON resource ranges
307
Craig Lutgen1dd47082018-10-23 13:12:26 -0500308 :param onu_id_start_idx: onu id start index
309 :param onu_id_end_idx: onu id end index
310 :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 -0700311 :param alloc_id_start_idx: alloc id start index
312 :param alloc_id_end_idx: alloc id end index
Craig Lutgen1dd47082018-10-23 13:12:26 -0500313 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
314 :param gemport_id_start_idx: gemport id start index
315 :param gemport_id_end_idx: gemport id end index
316 :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 -0700317 :param flow_id_start_idx: flow id start index
318 :param flow_id_end_idx: flow id end index
319 :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 -0700320 :param num_of_pon_ports: number of PON ports
Craig Lutgen1dd47082018-10-23 13:12:26 -0500321 :param intf_ids: interfaces serviced by this manager
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700322 """
Girish Gowdru141ced82018-09-17 20:19:14 -0700323 self._log.info("initialize-default-resource-range-values")
Craig Lutgen1dd47082018-10-23 13:12:26 -0500324
325 self.update_ranges(onu_id_start_idx, onu_id_end_idx, onu_id_shared_pool_id, None,
326 alloc_id_start_idx, alloc_id_end_idx, alloc_id_shared_pool_id, None,
Girish Gowdruab836e92018-10-25 01:17:57 -0700327 gemport_id_start_idx, gemport_id_end_idx, gemport_id_shared_pool_id, None,
Craig Lutgenabd9c842018-11-15 23:58:27 +0000328 flow_id_start_idx, flow_id_end_idx, flow_id_shared_pool_id, None,
329 uni_id_start_idx, uni_id_end_idx)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500330
331 if intf_ids is None:
332 intf_ids = range(0, num_of_pon_ports)
333
334 self.intf_ids = intf_ids
Girish Gowdru141ced82018-09-17 20:19:14 -0700335
336 def init_device_resource_pool(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700337 """
338 Initialize resource pool for all PON ports.
339 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500340
341 self._log.info("init-device-resource-pool", technology=self.technology,
Girish Gowdruab836e92018-10-25 01:17:57 -0700342 pon_resource_ranges=self.pon_resource_ranges)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500343
344 for i in self.intf_ids:
345 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ONU_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700346 if shared_pool_id is not None:
347 i = shared_pool_id
Girish Gowdru141ced82018-09-17 20:19:14 -0700348 self.init_resource_id_pool(
349 pon_intf_id=i,
350 resource_type=PONResourceManager.ONU_ID,
351 start_idx=self.pon_resource_ranges[
Craig Lutgen1dd47082018-10-23 13:12:26 -0500352 PONResourceManager.ONU_ID_START_IDX],
Girish Gowdru141ced82018-09-17 20:19:14 -0700353 end_idx=self.pon_resource_ranges[
Craig Lutgen1dd47082018-10-23 13:12:26 -0500354 PONResourceManager.ONU_ID_END_IDX])
Girish Gowdruab836e92018-10-25 01:17:57 -0700355 if shared_pool_id is not None:
356 break
Girish Gowdru141ced82018-09-17 20:19:14 -0700357
Craig Lutgen1dd47082018-10-23 13:12:26 -0500358 for i in self.intf_ids:
359 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ALLOC_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700360 if shared_pool_id is not None:
361 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500362 self.init_resource_id_pool(
363 pon_intf_id=i,
364 resource_type=PONResourceManager.ALLOC_ID,
365 start_idx=self.pon_resource_ranges[
366 PONResourceManager.ALLOC_ID_START_IDX],
367 end_idx=self.pon_resource_ranges[
368 PONResourceManager.ALLOC_ID_END_IDX])
Girish Gowdruab836e92018-10-25 01:17:57 -0700369 if shared_pool_id is not None:
370 break
Girish Gowdru141ced82018-09-17 20:19:14 -0700371
Craig Lutgen1dd47082018-10-23 13:12:26 -0500372 for i in self.intf_ids:
373 shared_pool_id = self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700374 if shared_pool_id is not None:
375 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500376 self.init_resource_id_pool(
377 pon_intf_id=i,
378 resource_type=PONResourceManager.GEMPORT_ID,
379 start_idx=self.pon_resource_ranges[
380 PONResourceManager.GEMPORT_ID_START_IDX],
381 end_idx=self.pon_resource_ranges[
382 PONResourceManager.GEMPORT_ID_END_IDX])
Girish Gowdruab836e92018-10-25 01:17:57 -0700383 if shared_pool_id is not None:
384 break
385
386 for i in self.intf_ids:
387 shared_pool_id = self.pon_resource_ranges[PONResourceManager.FLOW_ID_SHARED_IDX]
388 if shared_pool_id is not None:
389 i = shared_pool_id
390 self.init_resource_id_pool(
391 pon_intf_id=i,
392 resource_type=PONResourceManager.FLOW_ID,
393 start_idx=self.pon_resource_ranges[
394 PONResourceManager.FLOW_ID_START_IDX],
395 end_idx=self.pon_resource_ranges[
396 PONResourceManager.FLOW_ID_END_IDX])
397 if shared_pool_id is not None:
398 break
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700399
Girish Gowdru141ced82018-09-17 20:19:14 -0700400 def clear_device_resource_pool(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700401 """
402 Clear resource pool of all PON ports.
403 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500404 for i in self.intf_ids:
405 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ONU_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700406 if shared_pool_id is not None:
407 i = shared_pool_id
Girish Gowdru141ced82018-09-17 20:19:14 -0700408 self.clear_resource_id_pool(
409 pon_intf_id=i,
410 resource_type=PONResourceManager.ONU_ID,
411 )
Girish Gowdruab836e92018-10-25 01:17:57 -0700412 if shared_pool_id is not None:
413 break
Girish Gowdru141ced82018-09-17 20:19:14 -0700414
Craig Lutgen1dd47082018-10-23 13:12:26 -0500415 for i in self.intf_ids:
416 shared_pool_id = self.pon_resource_ranges[PONResourceManager.ALLOC_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700417 if shared_pool_id is not None:
418 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500419 self.clear_resource_id_pool(
420 pon_intf_id=i,
421 resource_type=PONResourceManager.ALLOC_ID,
422 )
Girish Gowdruab836e92018-10-25 01:17:57 -0700423 if shared_pool_id is not None:
424 break
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700425
Craig Lutgen1dd47082018-10-23 13:12:26 -0500426 for i in self.intf_ids:
427 shared_pool_id = self.pon_resource_ranges[PONResourceManager.GEMPORT_ID_SHARED_IDX]
Girish Gowdruab836e92018-10-25 01:17:57 -0700428 if shared_pool_id is not None:
429 i = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500430 self.clear_resource_id_pool(
431 pon_intf_id=i,
432 resource_type=PONResourceManager.GEMPORT_ID,
433 )
Girish Gowdruab836e92018-10-25 01:17:57 -0700434 if shared_pool_id is not None:
435 break
436
437 for i in self.intf_ids:
438 shared_pool_id = self.pon_resource_ranges[PONResourceManager.FLOW_ID_SHARED_IDX]
439 if shared_pool_id is not None:
440 i = shared_pool_id
441 self.clear_resource_id_pool(
442 pon_intf_id=i,
443 resource_type=PONResourceManager.FLOW_ID,
444 )
445 if shared_pool_id is not None:
446 break
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700447
Girish Gowdru141ced82018-09-17 20:19:14 -0700448 def init_resource_id_pool(self, pon_intf_id, resource_type, start_idx,
449 end_idx):
450 """
451 Initialize Resource ID pool for a given Resource Type on a given PON Port
452
453 :param pon_intf_id: OLT PON interface id
454 :param resource_type: String to identify type of resource
455 :param start_idx: start index for onu id pool
456 :param end_idx: end index for onu id pool
457 :return boolean: True if resource id pool initialized else false
458 """
459 status = False
Craig Lutgen1dd47082018-10-23 13:12:26 -0500460
461 # delegate to the master instance if sharing enabled across instances
462 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
463 if shared_resource_mgr is not None and shared_resource_mgr is not self:
464 return shared_resource_mgr.init_resource_id_pool(pon_intf_id, resource_type,
Girish Gowdruab836e92018-10-25 01:17:57 -0700465 start_idx, end_idx)
Craig Lutgen1dd47082018-10-23 13:12:26 -0500466
Girish Gowdru141ced82018-09-17 20:19:14 -0700467 path = self._get_path(pon_intf_id, resource_type)
468 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700469 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700470
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700471 try:
472 # In case of adapter reboot and reconciliation resource in kv store
473 # checked for its presence if not kv store update happens
474 resource = self._get_resource(path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700475
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700476 if resource is not None:
477 self._log.info("Resource-already-present-in-store", path=path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700478 status = True
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700479 else:
480 resource = self._format_resource(pon_intf_id, start_idx,
481 end_idx)
482 self._log.info("Resource-initialized", path=path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700483
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700484 # Add resource as json in kv store.
485 result = self._kv_store.update_to_kv_store(path, resource)
486 if result is True:
487 status = True
488
489 except Exception as e:
490 self._log.exception("error-initializing-resource-pool", e=e)
491
492 return status
493
Craig Lutgenabd9c842018-11-15 23:58:27 +0000494 def assert_resource_limits(self, id, resource_type):
495 """
496 Assert the specified id value is in the limit bounds of he requested resource type.
497
498 :param id: The value to assert is in limits
499 :param resource_type: String to identify type of resource
500 """
501 start_idx = PONResourceManager.ONU_ID_START_IDX if resource_type == PONResourceManager.ONU_ID \
502 else PONResourceManager.ALLOC_ID_START_IDX if resource_type == PONResourceManager.ALLOC_ID \
503 else PONResourceManager.GEMPORT_ID_START_IDX if resource_type == PONResourceManager.GEMPORT_ID \
504 else PONResourceManager.FLOW_ID_START_IDX if resource_type == PONResourceManager.FLOW_ID \
505 else PONResourceManager.UNI_ID_START_IDX if resource_type == PONResourceManager.UNI_ID \
506 else None
507 end_idx = PONResourceManager.ONU_ID_END_IDX if resource_type == PONResourceManager.ONU_ID \
508 else PONResourceManager.ALLOC_ID_END_IDX if resource_type == PONResourceManager.ALLOC_ID \
509 else PONResourceManager.GEMPORT_ID_END_IDX if resource_type == PONResourceManager.GEMPORT_ID \
510 else PONResourceManager.FLOW_ID_END_IDX if resource_type == PONResourceManager.FLOW_ID \
511 else PONResourceManager.UNI_ID_END_IDX if resource_type == PONResourceManager.UNI_ID \
512 else None
513 assert id >= self.pon_resource_ranges[start_idx] and id <= self.pon_resource_ranges[end_idx]
514
Girish Gowdru141ced82018-09-17 20:19:14 -0700515 def get_resource_id(self, pon_intf_id, resource_type, num_of_id=1):
516 """
Girish Gowdruab836e92018-10-25 01:17:57 -0700517 Create alloc/gemport/onu/flow id for given OLT PON interface.
Girish Gowdru141ced82018-09-17 20:19:14 -0700518
519 :param pon_intf_id: OLT PON interface id
520 :param resource_type: String to identify type of resource
521 :param num_of_id: required number of ids
522 :return list/int/None: list, int or None if resource type is
523 alloc_id/gemport_id, onu_id or invalid type
524 respectively
525 """
526 result = None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700527
Girish Gowdruab836e92018-10-25 01:17:57 -0700528 if num_of_id < 1:
529 self._log.error("invalid-num-of-resources-requested")
530 return result
531
Craig Lutgen1dd47082018-10-23 13:12:26 -0500532 # delegate to the master instance if sharing enabled across instances
533 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
534 if shared_resource_mgr is not None and shared_resource_mgr is not self:
Craig Lutgen66dbf622018-11-18 12:24:54 -0600535 return shared_resource_mgr.get_resource_id(pon_intf_id, resource_type, num_of_id)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700536
Girish Gowdru141ced82018-09-17 20:19:14 -0700537 path = self._get_path(pon_intf_id, resource_type)
538 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700539 return result
Girish Gowdru141ced82018-09-17 20:19:14 -0700540
Girish Gowdru141ced82018-09-17 20:19:14 -0700541 try:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700542 resource = self._get_resource(path)
Girish Gowdruab836e92018-10-25 01:17:57 -0700543 if resource is not None and \
544 (resource_type == PONResourceManager.ONU_ID or
545 resource_type == PONResourceManager.FLOW_ID):
Girish Gowdru141ced82018-09-17 20:19:14 -0700546 result = self._generate_next_id(resource)
547 elif resource is not None and (
548 resource_type == PONResourceManager.GEMPORT_ID or
549 resource_type == PONResourceManager.ALLOC_ID):
Girish Gowdruab836e92018-10-25 01:17:57 -0700550 if num_of_id == 1:
551 result = self._generate_next_id(resource)
552 else:
553 result = list()
554 while num_of_id > 0:
555 result.append(self._generate_next_id(resource))
556 num_of_id -= 1
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700557 else:
558 raise Exception("get-resource-failed")
Girish Gowdru141ced82018-09-17 20:19:14 -0700559
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700560 self._log.debug("Get-" + resource_type + "-success", result=result,
561 path=path)
Girish Gowdru141ced82018-09-17 20:19:14 -0700562 # Update resource in kv store
563 self._update_resource(path, resource)
564
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700565 except Exception as e:
Girish Gowdru141ced82018-09-17 20:19:14 -0700566 self._log.exception("Get-" + resource_type + "-id-failed",
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700567 path=path, e=e)
568 return result
Girish Gowdru141ced82018-09-17 20:19:14 -0700569
Girish Gowdru141ced82018-09-17 20:19:14 -0700570 def free_resource_id(self, pon_intf_id, resource_type, release_content):
571 """
Girish Gowdruab836e92018-10-25 01:17:57 -0700572 Release alloc/gemport/onu/flow id for given OLT PON interface.
Girish Gowdru141ced82018-09-17 20:19:14 -0700573
574 :param pon_intf_id: OLT PON interface id
575 :param resource_type: String to identify type of resource
576 :param release_content: required number of ids
577 :return boolean: True if all IDs in given release_content released
578 else False
579 """
580 status = False
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700581
Craig Lutgen1dd47082018-10-23 13:12:26 -0500582 # delegate to the master instance if sharing enabled across instances
583 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
584 if shared_resource_mgr is not None and shared_resource_mgr is not self:
585 return shared_resource_mgr.free_resource_id(pon_intf_id, resource_type)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700586
Girish Gowdru141ced82018-09-17 20:19:14 -0700587 path = self._get_path(pon_intf_id, resource_type)
588 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700589 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700590
Girish Gowdru141ced82018-09-17 20:19:14 -0700591 try:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700592 resource = self._get_resource(path)
Girish Gowdruab836e92018-10-25 01:17:57 -0700593 if resource is not None and (
594 resource_type == PONResourceManager.ONU_ID or
595 resource_type == PONResourceManager.FLOW_ID):
Girish Gowdru141ced82018-09-17 20:19:14 -0700596 self._release_id(resource, release_content)
597 elif resource is not None and (
598 resource_type == PONResourceManager.ALLOC_ID or
599 resource_type == PONResourceManager.GEMPORT_ID):
600 for content in release_content:
601 self._release_id(resource, content)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700602 else:
603 raise Exception("get-resource-failed")
604
Girish Gowdru141ced82018-09-17 20:19:14 -0700605 self._log.debug("Free-" + resource_type + "-success", path=path)
606
607 # Update resource in kv store
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700608 status = self._update_resource(path, resource)
Girish Gowdru141ced82018-09-17 20:19:14 -0700609
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700610 except Exception as e:
611 self._log.exception("Free-" + resource_type + "-failed",
612 path=path, e=e)
613 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700614
Girish Gowdru141ced82018-09-17 20:19:14 -0700615 def clear_resource_id_pool(self, pon_intf_id, resource_type):
616 """
617 Clear Resource Pool for a given Resource Type on a given PON Port.
618
619 :return boolean: True if removed else False
620 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500621
622 # delegate to the master instance if sharing enabled across instances
623 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
624 if shared_resource_mgr is not None and shared_resource_mgr is not self:
625 return shared_resource_mgr.clear_resource_id_pool(pon_intf_id, resource_type)
626
Girish Gowdru141ced82018-09-17 20:19:14 -0700627 path = self._get_path(pon_intf_id, resource_type)
628 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700629 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700630
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700631 try:
632 result = self._kv_store.remove_from_kv_store(path)
633 if result is True:
634 self._log.debug("Resource-pool-cleared",
635 device_id=self.device_id,
636 path=path)
637 return True
638 except Exception as e:
639 self._log.exception("error-clearing-resource-pool", e=e)
640
Girish Gowdru141ced82018-09-17 20:19:14 -0700641 self._log.error("Clear-resource-pool-failed", device_id=self.device_id,
642 path=path)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700643 return False
644
645 def init_resource_map(self, pon_intf_onu_id):
646 """
647 Initialize resource map
648
649 :param pon_intf_onu_id: reference of PON interface id and onu id
650 """
651 # initialize pon_intf_onu_id tuple to alloc_ids map
652 alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
653 self.device_id, str(pon_intf_onu_id)
654 )
655 alloc_ids = list()
656 self._kv_store.update_to_kv_store(
657 alloc_id_path, json.dumps(alloc_ids)
658 )
659
660 # initialize pon_intf_onu_id tuple to gemport_ids map
661 gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
662 self.device_id, str(pon_intf_onu_id)
663 )
664 gemport_ids = list()
665 self._kv_store.update_to_kv_store(
666 gemport_id_path, json.dumps(gemport_ids)
667 )
668
669 def remove_resource_map(self, pon_intf_onu_id):
670 """
671 Remove resource map
672
673 :param pon_intf_onu_id: reference of PON interface id and onu id
674 """
675 # remove pon_intf_onu_id tuple to alloc_ids map
676 alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
677 self.device_id, str(pon_intf_onu_id)
678 )
679 self._kv_store.remove_from_kv_store(alloc_id_path)
680
681 # remove pon_intf_onu_id tuple to gemport_ids map
682 gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
683 self.device_id, str(pon_intf_onu_id)
684 )
685 self._kv_store.remove_from_kv_store(gemport_id_path)
686
687 def get_current_alloc_ids_for_onu(self, pon_intf_onu_id):
688 """
689 Get currently configured alloc ids for given pon_intf_onu_id
690
691 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700692
693 :return list: List of alloc_ids if available, else None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700694 """
695 path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
696 self.device_id,
697 str(pon_intf_onu_id))
698 value = self._kv_store.get_from_kv_store(path)
699 if value is not None:
700 alloc_id_list = json.loads(value)
701 if len(alloc_id_list) > 0:
702 return alloc_id_list
703
704 return None
705
706 def get_current_gemport_ids_for_onu(self, pon_intf_onu_id):
707 """
708 Get currently configured gemport ids for given pon_intf_onu_id
709
710 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700711
712 :return list: List of gemport IDs if available, else None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700713 """
714
715 path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
716 self.device_id,
717 str(pon_intf_onu_id))
718 value = self._kv_store.get_from_kv_store(path)
719 if value is not None:
720 gemport_id_list = json.loads(value)
721 if len(gemport_id_list) > 0:
722 return gemport_id_list
723
724 return None
725
Girish Gowdruab836e92018-10-25 01:17:57 -0700726 def get_current_flow_ids_for_onu(self, pon_intf_onu_id):
727 """
728 Get currently configured flow ids for given pon_intf_onu_id
729
730 :param pon_intf_onu_id: reference of PON interface id and onu id
731
732 :return list: List of Flow IDs if available, else None
733 """
734
735 path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
736 self.device_id,
737 str(pon_intf_onu_id))
738 value = self._kv_store.get_from_kv_store(path)
739 if value is not None:
740 flow_id_list = json.loads(value)
741 assert(isinstance(flow_id_list, list))
742 if len(flow_id_list) > 0:
743 return flow_id_list
744
745 return None
746
747 def get_flow_id_info(self, pon_intf_onu_id, flow_id):
748 """
749 Get flow_id details configured for the ONU.
750
751 :param pon_intf_onu_id: reference of PON interface id and onu id
752 :param flow_id: Flow Id reference
753
754 :return blob: Flow data blob if available, else None
755 """
756
757 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
758 self.device_id,
759 str(pon_intf_onu_id),
760 flow_id)
761 value = self._kv_store.get_from_kv_store(path)
762 if value is not None:
763 return ast.literal_eval(value)
764
765 return None
766
767 def remove_flow_id_info(self, pon_intf_onu_id, flow_id):
768 """
769 Get flow_id details configured for the ONU.
770
771 :param pon_intf_onu_id: reference of PON interface id and onu id
772 :param flow_id: Flow Id reference
773
774 """
775
776 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
777 self.device_id,
778 str(pon_intf_onu_id),
779 flow_id)
780 self._kv_store.remove_from_kv_store(path)
781
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700782 def update_alloc_ids_for_onu(self, pon_intf_onu_id, alloc_ids):
783 """
784 Update currently configured alloc ids for given pon_intf_onu_id
785
786 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700787 :param alloc_ids: list of alloc ids
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700788 """
789 path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
790 self.device_id, str(pon_intf_onu_id)
791 )
792 self._kv_store.update_to_kv_store(
793 path, json.dumps(alloc_ids)
794 )
795
796 def update_gemport_ids_for_onu(self, pon_intf_onu_id, gemport_ids):
797 """
798 Update currently configured gemport ids for given pon_intf_onu_id
799
800 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700801 :param gemport_ids: list of gem port ids
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700802 """
803 path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
804 self.device_id, str(pon_intf_onu_id)
805 )
806 self._kv_store.update_to_kv_store(
807 path, json.dumps(gemport_ids)
808 )
809
Girish Gowdruab836e92018-10-25 01:17:57 -0700810 def update_flow_id_for_onu(self, pon_intf_onu_id, flow_id, add=True):
811 """
812 Update the flow_id list of the ONU (add or remove flow_id from the list)
813
814 :param pon_intf_onu_id: reference of PON interface id and onu id
815 :param flow_id: flow ID
816 :param add: Boolean flag to indicate whether the flow_id should be
817 added or removed from the list. Defaults to adding the flow.
818 """
819 path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
820 self.device_id, str(pon_intf_onu_id)
821 )
822 current_flow_ids = self.get_current_flow_ids_for_onu(pon_intf_onu_id)
823 if not isinstance(current_flow_ids, list):
824 # When the first flow_id is being added, the current_flow_ids is None
825 current_flow_ids = list()
826
827 if add:
828 if flow_id not in current_flow_ids:
829 current_flow_ids.append(flow_id)
830 else:
831 if flow_id in current_flow_ids:
832 current_flow_ids.remove(flow_id)
833
834 self._kv_store.update_to_kv_store(path, current_flow_ids)
835
836 def update_flow_id_info_for_onu(self, pon_intf_onu_id, flow_id, flow_data):
837 """
838 Update any metadata associated with the flow_id. The flow_data could be json
839 or any of other data structure. The resource manager doesnt care
840
841 :param pon_intf_onu_id: reference of PON interface id and onu id
842 :param flow_id: Flow ID
843 :param flow_data: Flow data blob
844 """
845 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
846 self.device_id, str(pon_intf_onu_id), flow_id
847 )
848
849 if not self._kv_store.update_to_kv_store(path, flow_data):
850 self._log.error("flow-info-update-failed", path=path, flow_id=flow_id)
851
Craig Lutgenf7601472018-11-02 13:27:41 +0000852 def _get_olt_model(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700853 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000854 Get olt model variant
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700855
Craig Lutgenf7601472018-11-02 13:27:41 +0000856 :return: type of olt model
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700857 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000858 olt_model = None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700859 if self.extra_args and len(self.extra_args) > 0:
860 parser = OltVendorArgumentParser(add_help=False)
Craig Lutgenf7601472018-11-02 13:27:41 +0000861 parser.add_argument(PONResourceManager.OLT_MODEL_ARG, '-m', action='store', default='default')
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700862 try:
863 args = parser.parse_args(shlex.split(self.extra_args))
864 self._log.debug('parsing-extra-arguments', args=args)
Craig Lutgenf7601472018-11-02 13:27:41 +0000865 olt_model = args.olt_model
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700866 except ArgumentError as e:
867 self._log.exception('invalid-arguments: {}', e=e)
868 except Exception as e:
869 self._log.exception('option-parsing-error: {}', e=e)
870
Craig Lutgenf7601472018-11-02 13:27:41 +0000871 self._log.debug('olt-model', olt_model=olt_model)
872 return olt_model
Girish Gowdru141ced82018-09-17 20:19:14 -0700873
874 def _generate_next_id(self, resource):
875 """
876 Generate unique id having OFFSET as start index.
877
878 :param resource: resource used to generate ID
879 :return int: generated id
880 """
881 pos = resource[PONResourceManager.POOL].find('0b0')
882 resource[PONResourceManager.POOL].set(1, pos)
883 return pos[0] + resource[PONResourceManager.START_IDX]
884
885 def _release_id(self, resource, unique_id):
886 """
887 Release unique id having OFFSET as start index.
888
889 :param resource: resource used to release ID
890 :param unique_id: id need to be released
891 """
892 pos = ((int(unique_id)) - resource[PONResourceManager.START_IDX])
893 resource[PONResourceManager.POOL].set(0, pos)
894
895 def _get_path(self, pon_intf_id, resource_type):
896 """
897 Get path for given resource type.
898
899 :param pon_intf_id: OLT PON interface id
900 :param resource_type: String to identify type of resource
901 :return: path for given resource type
902 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500903
904 shared_pool_id = self.pon_resource_ranges[self.shared_idx_by_type[resource_type]]
Girish Gowdruab836e92018-10-25 01:17:57 -0700905 if shared_pool_id is not None:
906 pon_intf_id = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500907
Girish Gowdru141ced82018-09-17 20:19:14 -0700908 path = None
909 if resource_type == PONResourceManager.ONU_ID:
910 path = self._get_onu_id_resource_path(pon_intf_id)
911 elif resource_type == PONResourceManager.ALLOC_ID:
912 path = self._get_alloc_id_resource_path(pon_intf_id)
913 elif resource_type == PONResourceManager.GEMPORT_ID:
914 path = self._get_gemport_id_resource_path(pon_intf_id)
Girish Gowdruab836e92018-10-25 01:17:57 -0700915 elif resource_type == PONResourceManager.FLOW_ID:
916 path = self._get_flow_id_resource_path(pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700917 else:
918 self._log.error("invalid-resource-pool-identifier")
919 return path
920
Girish Gowdruab836e92018-10-25 01:17:57 -0700921 def _get_flow_id_resource_path(self, pon_intf_id):
922 """
923 Get flow id resource path.
924
925 :param pon_intf_id: OLT PON interface id
926 :return: flow id resource path
927 """
928 return PONResourceManager.FLOW_ID_POOL_PATH.format(
929 self.device_id, pon_intf_id)
930
Girish Gowdru141ced82018-09-17 20:19:14 -0700931 def _get_alloc_id_resource_path(self, pon_intf_id):
932 """
933 Get alloc id resource path.
934
935 :param pon_intf_id: OLT PON interface id
936 :return: alloc id resource path
937 """
938 return PONResourceManager.ALLOC_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700939 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700940
941 def _get_gemport_id_resource_path(self, pon_intf_id):
942 """
943 Get gemport id resource path.
944
945 :param pon_intf_id: OLT PON interface id
946 :return: gemport id resource path
947 """
948 return PONResourceManager.GEMPORT_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700949 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700950
951 def _get_onu_id_resource_path(self, pon_intf_id):
952 """
953 Get onu id resource path.
954
955 :param pon_intf_id: OLT PON interface id
956 :return: onu id resource path
957 """
958 return PONResourceManager.ONU_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700959 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700960
Girish Gowdru141ced82018-09-17 20:19:14 -0700961 def _update_resource(self, path, resource):
962 """
963 Update resource in resource kv store.
964
965 :param path: path to update resource
966 :param resource: resource need to be updated
967 :return boolean: True if resource updated in kv store else False
968 """
969 resource[PONResourceManager.POOL] = \
970 resource[PONResourceManager.POOL].bin
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700971 result = self._kv_store.update_to_kv_store(path, json.dumps(resource))
972 if result is True:
973 return True
974 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700975
Girish Gowdru141ced82018-09-17 20:19:14 -0700976 def _get_resource(self, path):
977 """
978 Get resource from kv store.
979
980 :param path: path to get resource
981 :return: resource if resource present in kv store else None
982 """
983 # get resource from kv store
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700984 result = self._kv_store.get_from_kv_store(path)
985 if result is None:
986 return result
987 self._log.info("dumping resource", result=result)
988 resource = result
Girish Gowdru141ced82018-09-17 20:19:14 -0700989
990 if resource is not None:
991 # decode resource fetched from backend store to dictionary
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700992 resource = json.loads(resource)
Girish Gowdru141ced82018-09-17 20:19:14 -0700993
994 # resource pool in backend store stored as binary string whereas to
995 # access the pool to generate/release IDs it need to be converted
996 # as BitArray
997 resource[PONResourceManager.POOL] = \
998 BitArray('0b' + resource[PONResourceManager.POOL])
999
Girish Gowdru1e77ea02018-09-24 09:10:35 -07001000 return resource
Girish Gowdru141ced82018-09-17 20:19:14 -07001001
1002 def _format_resource(self, pon_intf_id, start_idx, end_idx):
1003 """
1004 Format resource as json.
1005
1006 :param pon_intf_id: OLT PON interface id
1007 :param start_idx: start index for id pool
1008 :param end_idx: end index for id pool
1009 :return dictionary: resource formatted as dictionary
1010 """
1011 # Format resource as json to be stored in backend store
1012 resource = dict()
1013 resource[PONResourceManager.PON_INTF_ID] = pon_intf_id
1014 resource[PONResourceManager.START_IDX] = start_idx
1015 resource[PONResourceManager.END_IDX] = end_idx
1016
1017 # resource pool stored in backend store as binary string
1018 resource[PONResourceManager.POOL] = BitArray(end_idx).bin
1019
1020 return json.dumps(resource)