blob: bdb45ee831a394d1e29f65d6efe1d80fadae91d1 [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 Gowdrub761bc12018-11-29 02:22:18 -0800581 known_resource_types = [PONResourceManager.ONU_ID,
582 PONResourceManager.ALLOC_ID,
583 PONResourceManager.GEMPORT_ID,
584 PONResourceManager.FLOW_ID]
585 if resource_type not in known_resource_types:
586 self._log.error("unknown-resource-type",
587 resource_type=resource_type)
588 return status
589 if release_content is None:
590 self._log.debug("nothing-to-release")
591 return status
Craig Lutgen1dd47082018-10-23 13:12:26 -0500592 # delegate to the master instance if sharing enabled across instances
593 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
594 if shared_resource_mgr is not None and shared_resource_mgr is not self:
595 return shared_resource_mgr.free_resource_id(pon_intf_id, resource_type)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700596
Girish Gowdru141ced82018-09-17 20:19:14 -0700597 path = self._get_path(pon_intf_id, resource_type)
598 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700599 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700600
Girish Gowdru141ced82018-09-17 20:19:14 -0700601 try:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700602 resource = self._get_resource(path)
Girish Gowdrub761bc12018-11-29 02:22:18 -0800603 if resource is None:
604 raise Exception("get-resource-failed")
605 if isinstance(release_content, list):
Girish Gowdru141ced82018-09-17 20:19:14 -0700606 for content in release_content:
607 self._release_id(resource, content)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700608 else:
Girish Gowdrub761bc12018-11-29 02:22:18 -0800609 self._release_id(resource, release_content)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700610
Girish Gowdru141ced82018-09-17 20:19:14 -0700611 self._log.debug("Free-" + resource_type + "-success", path=path)
612
613 # Update resource in kv store
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700614 status = self._update_resource(path, resource)
Girish Gowdru141ced82018-09-17 20:19:14 -0700615
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700616 except Exception as e:
617 self._log.exception("Free-" + resource_type + "-failed",
618 path=path, e=e)
619 return status
Girish Gowdru141ced82018-09-17 20:19:14 -0700620
Girish Gowdru141ced82018-09-17 20:19:14 -0700621 def clear_resource_id_pool(self, pon_intf_id, resource_type):
622 """
623 Clear Resource Pool for a given Resource Type on a given PON Port.
624
625 :return boolean: True if removed else False
626 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500627
628 # delegate to the master instance if sharing enabled across instances
629 shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
630 if shared_resource_mgr is not None and shared_resource_mgr is not self:
631 return shared_resource_mgr.clear_resource_id_pool(pon_intf_id, resource_type)
632
Girish Gowdru141ced82018-09-17 20:19:14 -0700633 path = self._get_path(pon_intf_id, resource_type)
634 if path is None:
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700635 return False
Girish Gowdru141ced82018-09-17 20:19:14 -0700636
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700637 try:
638 result = self._kv_store.remove_from_kv_store(path)
639 if result is True:
640 self._log.debug("Resource-pool-cleared",
641 device_id=self.device_id,
642 path=path)
643 return True
644 except Exception as e:
645 self._log.exception("error-clearing-resource-pool", e=e)
646
Girish Gowdru141ced82018-09-17 20:19:14 -0700647 self._log.error("Clear-resource-pool-failed", device_id=self.device_id,
648 path=path)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700649 return False
650
651 def init_resource_map(self, pon_intf_onu_id):
652 """
653 Initialize resource map
654
655 :param pon_intf_onu_id: reference of PON interface id and onu id
656 """
657 # initialize pon_intf_onu_id tuple to alloc_ids map
658 alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
659 self.device_id, str(pon_intf_onu_id)
660 )
661 alloc_ids = list()
662 self._kv_store.update_to_kv_store(
663 alloc_id_path, json.dumps(alloc_ids)
664 )
665
666 # initialize pon_intf_onu_id tuple to gemport_ids map
667 gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
668 self.device_id, str(pon_intf_onu_id)
669 )
670 gemport_ids = list()
671 self._kv_store.update_to_kv_store(
672 gemport_id_path, json.dumps(gemport_ids)
673 )
674
675 def remove_resource_map(self, pon_intf_onu_id):
676 """
677 Remove resource map
678
679 :param pon_intf_onu_id: reference of PON interface id and onu id
680 """
681 # remove pon_intf_onu_id tuple to alloc_ids map
Girish Gowdrub761bc12018-11-29 02:22:18 -0800682 try:
683 alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
684 self.device_id, str(pon_intf_onu_id)
685 )
686 self._kv_store.remove_from_kv_store(alloc_id_path)
687 except Exception as e:
688 self._log.error("error-removing-alloc-id", e=e)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700689
Girish Gowdrub761bc12018-11-29 02:22:18 -0800690 try:
691 # remove pon_intf_onu_id tuple to gemport_ids map
692 gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
693 self.device_id, str(pon_intf_onu_id)
694 )
695 self._kv_store.remove_from_kv_store(gemport_id_path)
696 except Exception as e:
697 self._log.error("error-removing-gem-ports", e=e)
698
699 flow_id_path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
700 self.device_id, str(pon_intf_onu_id))
701 flow_ids = self._kv_store.get_from_kv_store(flow_id_path)
702
703 if flow_ids and isinstance(flow_ids, list):
704 for flow_id in flow_ids:
705 try:
706 flow_id_info_path = PONResourceManager.FLOW_ID_INFO_PATH.format(
707 self.device_id, str(pon_intf_onu_id), flow_id)
708 self._kv_store.remove_from_kv_store(flow_id_info_path)
709 except Exception as e:
710 self._log.error("error-removing-flow-info", flow_id=flow_id, e=e)
711 continue
712 try:
713 self._kv_store.remove_from_kv_store(flow_id_path)
714 except Exception as e:
715 self._log.error("error-removing-flow-ids", e=e)
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700716
717 def get_current_alloc_ids_for_onu(self, pon_intf_onu_id):
718 """
719 Get currently configured alloc ids for given pon_intf_onu_id
720
721 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700722
723 :return list: List of alloc_ids if available, else None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700724 """
725 path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
726 self.device_id,
727 str(pon_intf_onu_id))
728 value = self._kv_store.get_from_kv_store(path)
729 if value is not None:
730 alloc_id_list = json.loads(value)
731 if len(alloc_id_list) > 0:
732 return alloc_id_list
733
734 return None
735
736 def get_current_gemport_ids_for_onu(self, pon_intf_onu_id):
737 """
738 Get currently configured gemport ids for given pon_intf_onu_id
739
740 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700741
742 :return list: List of gemport IDs if available, else None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700743 """
744
745 path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
746 self.device_id,
747 str(pon_intf_onu_id))
748 value = self._kv_store.get_from_kv_store(path)
749 if value is not None:
750 gemport_id_list = json.loads(value)
751 if len(gemport_id_list) > 0:
752 return gemport_id_list
753
754 return None
755
Girish Gowdruab836e92018-10-25 01:17:57 -0700756 def get_current_flow_ids_for_onu(self, pon_intf_onu_id):
757 """
758 Get currently configured flow ids for given pon_intf_onu_id
759
760 :param pon_intf_onu_id: reference of PON interface id and onu id
761
762 :return list: List of Flow IDs if available, else None
763 """
764
765 path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
766 self.device_id,
767 str(pon_intf_onu_id))
768 value = self._kv_store.get_from_kv_store(path)
769 if value is not None:
770 flow_id_list = json.loads(value)
771 assert(isinstance(flow_id_list, list))
772 if len(flow_id_list) > 0:
773 return flow_id_list
774
775 return None
776
777 def get_flow_id_info(self, pon_intf_onu_id, flow_id):
778 """
779 Get flow_id details configured for the ONU.
780
781 :param pon_intf_onu_id: reference of PON interface id and onu id
782 :param flow_id: Flow Id reference
783
784 :return blob: Flow data blob if available, else None
785 """
786
787 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
788 self.device_id,
789 str(pon_intf_onu_id),
790 flow_id)
791 value = self._kv_store.get_from_kv_store(path)
792 if value is not None:
793 return ast.literal_eval(value)
794
795 return None
796
797 def remove_flow_id_info(self, pon_intf_onu_id, flow_id):
798 """
799 Get flow_id details configured for the ONU.
800
801 :param pon_intf_onu_id: reference of PON interface id and onu id
802 :param flow_id: Flow Id reference
803
804 """
805
806 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
807 self.device_id,
808 str(pon_intf_onu_id),
809 flow_id)
810 self._kv_store.remove_from_kv_store(path)
811
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700812 def update_alloc_ids_for_onu(self, pon_intf_onu_id, alloc_ids):
813 """
814 Update currently configured alloc ids for given pon_intf_onu_id
815
816 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700817 :param alloc_ids: list of alloc ids
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700818 """
819 path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
820 self.device_id, str(pon_intf_onu_id)
821 )
822 self._kv_store.update_to_kv_store(
823 path, json.dumps(alloc_ids)
824 )
825
826 def update_gemport_ids_for_onu(self, pon_intf_onu_id, gemport_ids):
827 """
828 Update currently configured gemport ids for given pon_intf_onu_id
829
830 :param pon_intf_onu_id: reference of PON interface id and onu id
Girish Gowdruab836e92018-10-25 01:17:57 -0700831 :param gemport_ids: list of gem port ids
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700832 """
833 path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
834 self.device_id, str(pon_intf_onu_id)
835 )
836 self._kv_store.update_to_kv_store(
837 path, json.dumps(gemport_ids)
838 )
839
Girish Gowdruab836e92018-10-25 01:17:57 -0700840 def update_flow_id_for_onu(self, pon_intf_onu_id, flow_id, add=True):
841 """
842 Update the flow_id list of the ONU (add or remove flow_id from the list)
843
844 :param pon_intf_onu_id: reference of PON interface id and onu id
845 :param flow_id: flow ID
846 :param add: Boolean flag to indicate whether the flow_id should be
847 added or removed from the list. Defaults to adding the flow.
848 """
849 path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
850 self.device_id, str(pon_intf_onu_id)
851 )
852 current_flow_ids = self.get_current_flow_ids_for_onu(pon_intf_onu_id)
853 if not isinstance(current_flow_ids, list):
854 # When the first flow_id is being added, the current_flow_ids is None
855 current_flow_ids = list()
856
857 if add:
858 if flow_id not in current_flow_ids:
859 current_flow_ids.append(flow_id)
860 else:
861 if flow_id in current_flow_ids:
862 current_flow_ids.remove(flow_id)
863
864 self._kv_store.update_to_kv_store(path, current_flow_ids)
865
866 def update_flow_id_info_for_onu(self, pon_intf_onu_id, flow_id, flow_data):
867 """
868 Update any metadata associated with the flow_id. The flow_data could be json
869 or any of other data structure. The resource manager doesnt care
870
871 :param pon_intf_onu_id: reference of PON interface id and onu id
872 :param flow_id: Flow ID
873 :param flow_data: Flow data blob
874 """
875 path = PONResourceManager.FLOW_ID_INFO_PATH.format(
876 self.device_id, str(pon_intf_onu_id), flow_id
877 )
878
879 if not self._kv_store.update_to_kv_store(path, flow_data):
880 self._log.error("flow-info-update-failed", path=path, flow_id=flow_id)
881
Craig Lutgenf7601472018-11-02 13:27:41 +0000882 def _get_olt_model(self):
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700883 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000884 Get olt model variant
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700885
Craig Lutgenf7601472018-11-02 13:27:41 +0000886 :return: type of olt model
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700887 """
Craig Lutgenf7601472018-11-02 13:27:41 +0000888 olt_model = None
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700889 if self.extra_args and len(self.extra_args) > 0:
890 parser = OltVendorArgumentParser(add_help=False)
Craig Lutgenf7601472018-11-02 13:27:41 +0000891 parser.add_argument(PONResourceManager.OLT_MODEL_ARG, '-m', action='store', default='default')
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700892 try:
893 args = parser.parse_args(shlex.split(self.extra_args))
894 self._log.debug('parsing-extra-arguments', args=args)
Craig Lutgenf7601472018-11-02 13:27:41 +0000895 olt_model = args.olt_model
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700896 except ArgumentError as e:
897 self._log.exception('invalid-arguments: {}', e=e)
898 except Exception as e:
899 self._log.exception('option-parsing-error: {}', e=e)
900
Craig Lutgenf7601472018-11-02 13:27:41 +0000901 self._log.debug('olt-model', olt_model=olt_model)
902 return olt_model
Girish Gowdru141ced82018-09-17 20:19:14 -0700903
904 def _generate_next_id(self, resource):
905 """
906 Generate unique id having OFFSET as start index.
907
908 :param resource: resource used to generate ID
909 :return int: generated id
910 """
911 pos = resource[PONResourceManager.POOL].find('0b0')
912 resource[PONResourceManager.POOL].set(1, pos)
913 return pos[0] + resource[PONResourceManager.START_IDX]
914
915 def _release_id(self, resource, unique_id):
916 """
917 Release unique id having OFFSET as start index.
918
919 :param resource: resource used to release ID
920 :param unique_id: id need to be released
921 """
922 pos = ((int(unique_id)) - resource[PONResourceManager.START_IDX])
923 resource[PONResourceManager.POOL].set(0, pos)
924
925 def _get_path(self, pon_intf_id, resource_type):
926 """
927 Get path for given resource type.
928
929 :param pon_intf_id: OLT PON interface id
930 :param resource_type: String to identify type of resource
931 :return: path for given resource type
932 """
Craig Lutgen1dd47082018-10-23 13:12:26 -0500933
934 shared_pool_id = self.pon_resource_ranges[self.shared_idx_by_type[resource_type]]
Girish Gowdruab836e92018-10-25 01:17:57 -0700935 if shared_pool_id is not None:
936 pon_intf_id = shared_pool_id
Craig Lutgen1dd47082018-10-23 13:12:26 -0500937
Girish Gowdru141ced82018-09-17 20:19:14 -0700938 path = None
939 if resource_type == PONResourceManager.ONU_ID:
940 path = self._get_onu_id_resource_path(pon_intf_id)
941 elif resource_type == PONResourceManager.ALLOC_ID:
942 path = self._get_alloc_id_resource_path(pon_intf_id)
943 elif resource_type == PONResourceManager.GEMPORT_ID:
944 path = self._get_gemport_id_resource_path(pon_intf_id)
Girish Gowdruab836e92018-10-25 01:17:57 -0700945 elif resource_type == PONResourceManager.FLOW_ID:
946 path = self._get_flow_id_resource_path(pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700947 else:
948 self._log.error("invalid-resource-pool-identifier")
949 return path
950
Girish Gowdruab836e92018-10-25 01:17:57 -0700951 def _get_flow_id_resource_path(self, pon_intf_id):
952 """
953 Get flow id resource path.
954
955 :param pon_intf_id: OLT PON interface id
956 :return: flow id resource path
957 """
958 return PONResourceManager.FLOW_ID_POOL_PATH.format(
959 self.device_id, pon_intf_id)
960
Girish Gowdru141ced82018-09-17 20:19:14 -0700961 def _get_alloc_id_resource_path(self, pon_intf_id):
962 """
963 Get alloc id resource path.
964
965 :param pon_intf_id: OLT PON interface id
966 :return: alloc id resource path
967 """
968 return PONResourceManager.ALLOC_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700969 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700970
971 def _get_gemport_id_resource_path(self, pon_intf_id):
972 """
973 Get gemport id resource path.
974
975 :param pon_intf_id: OLT PON interface id
976 :return: gemport id resource path
977 """
978 return PONResourceManager.GEMPORT_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700979 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700980
981 def _get_onu_id_resource_path(self, pon_intf_id):
982 """
983 Get onu id resource path.
984
985 :param pon_intf_id: OLT PON interface id
986 :return: onu id resource path
987 """
988 return PONResourceManager.ONU_ID_POOL_PATH.format(
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700989 self.device_id, pon_intf_id)
Girish Gowdru141ced82018-09-17 20:19:14 -0700990
Girish Gowdru141ced82018-09-17 20:19:14 -0700991 def _update_resource(self, path, resource):
992 """
993 Update resource in resource kv store.
994
995 :param path: path to update resource
996 :param resource: resource need to be updated
997 :return boolean: True if resource updated in kv store else False
998 """
999 resource[PONResourceManager.POOL] = \
1000 resource[PONResourceManager.POOL].bin
Girish Gowdru1e77ea02018-09-24 09:10:35 -07001001 result = self._kv_store.update_to_kv_store(path, json.dumps(resource))
1002 if result is True:
1003 return True
1004 return False
Girish Gowdru141ced82018-09-17 20:19:14 -07001005
Girish Gowdru141ced82018-09-17 20:19:14 -07001006 def _get_resource(self, path):
1007 """
1008 Get resource from kv store.
1009
1010 :param path: path to get resource
1011 :return: resource if resource present in kv store else None
1012 """
1013 # get resource from kv store
Girish Gowdru1e77ea02018-09-24 09:10:35 -07001014 result = self._kv_store.get_from_kv_store(path)
1015 if result is None:
1016 return result
1017 self._log.info("dumping resource", result=result)
1018 resource = result
Girish Gowdru141ced82018-09-17 20:19:14 -07001019
1020 if resource is not None:
1021 # decode resource fetched from backend store to dictionary
Girish Gowdru1e77ea02018-09-24 09:10:35 -07001022 resource = json.loads(resource)
Girish Gowdru141ced82018-09-17 20:19:14 -07001023
1024 # resource pool in backend store stored as binary string whereas to
1025 # access the pool to generate/release IDs it need to be converted
1026 # as BitArray
1027 resource[PONResourceManager.POOL] = \
1028 BitArray('0b' + resource[PONResourceManager.POOL])
1029
Girish Gowdru1e77ea02018-09-24 09:10:35 -07001030 return resource
Girish Gowdru141ced82018-09-17 20:19:14 -07001031
1032 def _format_resource(self, pon_intf_id, start_idx, end_idx):
1033 """
1034 Format resource as json.
1035
1036 :param pon_intf_id: OLT PON interface id
1037 :param start_idx: start index for id pool
1038 :param end_idx: end index for id pool
1039 :return dictionary: resource formatted as dictionary
1040 """
1041 # Format resource as json to be stored in backend store
1042 resource = dict()
1043 resource[PONResourceManager.PON_INTF_ID] = pon_intf_id
1044 resource[PONResourceManager.START_IDX] = start_idx
1045 resource[PONResourceManager.END_IDX] = end_idx
1046
1047 # resource pool stored in backend store as binary string
1048 resource[PONResourceManager.POOL] = BitArray(end_idx).bin
1049
1050 return json.dumps(resource)