blob: d1ee9678ae221e059972ce0d6e5574d465c3def5 [file] [log] [blame]
Matteo Scandolo48d3d2d2017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
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
A R Karthick35495c32017-05-11 14:58:32 -070017import requests
18import json
19import time
A.R Karthick57fa9372017-05-24 12:47:03 -070020import os
21import signal
A.R Karthick4c4d0492017-05-26 19:23:05 -070022from CordTestUtils import log_test as log, getstatusoutput, get_controller
A R Karthickbf1e4b02017-07-11 20:17:14 -070023from CordContainer import Container, Onos
A.R Karthick4c4d0492017-05-26 19:23:05 -070024from OnosCtrl import OnosCtrl
A.R Karthick4f583842017-06-09 17:15:47 -070025from OltConfig import OltConfig
A.R Karthick57fa9372017-05-24 12:47:03 -070026
27class VolthaService(object):
28 services = ('consul', 'kafka', 'zookeeper', 'registrator', 'fluentd')
A R Karthicke7232092017-09-07 18:01:33 -070029 standalone_services = ('envoy', 'voltha', 'ofagent', 'vcli',)
A.R Karthick57fa9372017-05-24 12:47:03 -070030 compose_file = 'docker-compose-system-test.yml'
31 service_map = {}
A R Karthick168e2342017-08-15 16:13:10 -070032 PROJECT = 'cordtester'
33 NETWORK = '{}_default'.format(PROJECT)
34 CONTAINER_MODE = False
35 REST_SERVICE = 'chameleon'
36 DOCKER_HOST_IP = '172.17.0.1'
37 PONSIM_HOST = '172.17.0.1'
A.R Karthick57fa9372017-05-24 12:47:03 -070038
A R Karthick168e2342017-08-15 16:13:10 -070039 def __init__(self, voltha_loc, controller, interface = 'eth0', olt_config = None, container_mode = False):
A.R Karthick57fa9372017-05-24 12:47:03 -070040 if not os.access(voltha_loc, os.F_OK):
41 raise Exception('Voltha location %s not found' %voltha_loc)
42 compose_file_loc = os.path.join(voltha_loc, 'compose', self.compose_file)
43 if not os.access(compose_file_loc, os.F_OK):
44 raise Exception('Voltha compose file %s not found' %compose_file_loc)
45 self.voltha_loc = voltha_loc
46 self.controller = controller
47 self.interface = interface
48 self.compose_file_loc = compose_file_loc
A R Karthick168e2342017-08-15 16:13:10 -070049 VolthaService.CONTAINER_MODE = container_mode
A.R Karthick4f583842017-06-09 17:15:47 -070050 num_onus = 1
51 if olt_config is not None:
52 port_map, _ = OltConfig(olt_config).olt_port_map()
53 if port_map['ponsim'] is True:
54 num_onus = max(1, len(port_map['ports']))
55 self.num_onus = num_onus
A.R Karthick57fa9372017-05-24 12:47:03 -070056
A R Karthick168e2342017-08-15 16:13:10 -070057 def start_services(self, *services):
58 services_fmt = ' {}' * len(services)
59 services_cmd_fmt = 'DOCKER_HOST_IP={} docker-compose -p {} -f {} up -d {}'.format(self.DOCKER_HOST_IP,
60 self.PROJECT,
61 self.compose_file_loc,
62 services_fmt)
63 start_cmd = services_cmd_fmt.format(*services)
A.R Karthick57fa9372017-05-24 12:47:03 -070064 ret = os.system(start_cmd)
65 if ret != 0:
66 raise Exception('Failed to start voltha services. Failed with code %d' %ret)
67
A R Karthick168e2342017-08-15 16:13:10 -070068 for service in services:
69 name = '{}_{}_1'.format(self.PROJECT, service)
A.R Karthick57fa9372017-05-24 12:47:03 -070070 cnt = Container(name, name)
A R Karthick168e2342017-08-15 16:13:10 -070071 ip = cnt.ip(network = self.NETWORK)
A.R Karthick57fa9372017-05-24 12:47:03 -070072 if not ip:
73 raise Exception('IP not found for container %s' %name)
74 print('IP %s for service %s' %(ip, service))
A R Karthick168e2342017-08-15 16:13:10 -070075 self.service_map[service] = dict(name = name, network = self.NETWORK, ip = ip)
A.R Karthick57fa9372017-05-24 12:47:03 -070076
A R Karthick168e2342017-08-15 16:13:10 -070077 def ponmgmt_enable(self):
78 cmds = ('echo 8 | tee /sys/class/net/ponmgmt/bridge/group_fwd_mask',
79 'brctl addif ponmgmt {} >/dev/null 2>&1'.format(self.interface),
80 )
81 for cmd in cmds:
82 try:
83 os.system(cmd)
84 except:
85 pass
86
87 def start(self):
88 self.start_services(*self.services)
89 if self.CONTAINER_MODE is True:
90 self.start_services(*self.standalone_services)
91 #enable multicast mac forwarding:
92 self.ponmgmt_enable()
A R Karthickd69d5702017-07-25 11:31:47 -070093 time.sleep(10)
A R Karthickaa6475d2017-08-15 17:24:36 -070094 chameleon_start_cmd = "cd {} && sh -c '. ./env.sh && \
95 nohup python chameleon/main.py -v --consul={}:8500 \
96 --fluentd={}:24224 --grpc-endpoint={}:50555 \
97 >/tmp/chameleon.log 2>&1 &'".format(self.voltha_loc,
98 self.get_ip('consul'),
99 self.get_ip('fluentd'),
100 self.get_ip('voltha'))
A.R Karthickc2697a12017-05-24 14:01:15 -0700101 else:
A R Karthickaa6475d2017-08-15 17:24:36 -0700102 #first start chameleon on the host as its only the reliable way for REST
A R Karthick168e2342017-08-15 16:13:10 -0700103 chameleon_start_cmd = "cd {} && sh -c '. ./env.sh && \
104 nohup python chameleon/main.py -v --consul=localhost:8500 \
105 --fluentd={}:24224 --grpc-endpoint=localhost:50555 \
106 >/tmp/chameleon.log 2>&1 &'".format(self.voltha_loc,
A R Karthickaa6475d2017-08-15 17:24:36 -0700107 self.get_ip('fluentd'))
108 if not self.service_running('python chameleon/main.py'):
109 ret = os.system(chameleon_start_cmd)
110 if ret != 0:
111 raise Exception('VOLTHA chameleon service not started. Failed with return code %d' %ret)
112 time.sleep(10)
113 else:
114 print('Chameleon voltha sevice is already running. Skipped start')
A.R Karthick57fa9372017-05-24 12:47:03 -0700115
A R Karthickaa6475d2017-08-15 17:24:36 -0700116 if self.CONTAINER_MODE is False:
A R Karthick168e2342017-08-15 16:13:10 -0700117 #now start voltha and ofagent
118 voltha_setup_cmd = "cd {} && sh -c '. ./env.sh && make rebuild-venv && make protos'".format(self.voltha_loc)
119 voltha_start_cmd = "cd {} && sh -c '. ./env.sh && \
120 nohup python voltha/main.py -v --consul=localhost:8500 --kafka={}:9092 -I {} \
121 --fluentd={}:24224 --rest-port=8880 --grpc-port=50555 \
122 >/tmp/voltha.log 2>&1 &'".format(self.voltha_loc,
123 self.service_map['kafka']['ip'],
124 self.interface,
125 self.service_map['fluentd']['ip'])
126 pki_dir = '{}/pki'.format(self.voltha_loc)
127 if not self.service_running('python voltha/main.py'):
128 voltha_pki_dir = '/voltha'
129 if os.access(pki_dir, os.F_OK):
130 pki_xfer_cmd = 'mkdir -p {} && cp -rv {}/pki {}'.format(voltha_pki_dir,
131 self.voltha_loc,
132 voltha_pki_dir)
133 os.system(pki_xfer_cmd)
134 #os.system(voltha_setup_cmd)
135 ret = os.system(voltha_start_cmd)
136 if ret != 0:
137 raise Exception('Failed to start VOLTHA. Return code %d' %ret)
138 time.sleep(10)
139 else:
140 print('VOLTHA core is already running. Skipped start')
A.R Karthick57fa9372017-05-24 12:47:03 -0700141
A R Karthick168e2342017-08-15 16:13:10 -0700142 ofagent_start_cmd = "cd {} && sh -c '. ./env.sh && \
143 nohup python ofagent/main.py -v --consul=localhost:8500 \
144 --fluentd={}:24224 --controller={}:6653 --grpc-endpoint=localhost:50555 \
145 >/tmp/ofagent.log 2>&1 &'".format(self.voltha_loc,
146 self.service_map['fluentd']['ip'],
147 self.controller)
148 if not self.service_running('python ofagent/main.py'):
149 ofagent_pki_dir = '/ofagent'
150 if os.access(pki_dir, os.F_OK):
151 pki_xfer_cmd = 'mkdir -p {} && cp -rv {}/pki {}'.format(ofagent_pki_dir,
152 self.voltha_loc,
153 ofagent_pki_dir)
154 os.system(pki_xfer_cmd)
155 ret = os.system(ofagent_start_cmd)
156 if ret != 0:
157 raise Exception('VOLTHA ofagent not started. Failed with return code %d' %ret)
158 time.sleep(10)
159 else:
160 print('VOLTHA ofagent is already running. Skipped start')
A.R Karthickc2697a12017-05-24 14:01:15 -0700161
A.R Karthick12e08c32017-05-30 17:09:26 -0700162 ponsim_start_cmd = "cd {} && sh -c '. ./env.sh && \
A.R Karthick4f583842017-06-09 17:15:47 -0700163 nohup python ponsim/main.py -o {} -v >/tmp/ponsim.log 2>&1 &'".format(self.voltha_loc, self.num_onus)
A.R Karthick12e08c32017-05-30 17:09:26 -0700164 if not self.service_running('python ponsim/main.py'):
165 ret = os.system(ponsim_start_cmd)
166 if ret != 0:
167 raise Exception('PONSIM not started. Failed with return code %d' %ret)
168 time.sleep(3)
169 else:
170 print('PONSIM already running. Skipped start')
171
A.R Karthickc2697a12017-05-24 14:01:15 -0700172 def service_running(self, pattern):
173 st, _ = getstatusoutput('pgrep -f "{}"'.format(pattern))
174 return True if st == 0 else False
A.R Karthick57fa9372017-05-24 12:47:03 -0700175
176 def kill_service(self, pattern):
177 st, output = getstatusoutput('pgrep -f "{}"'.format(pattern))
178 if st == 0 and output:
179 pids = output.strip().splitlines()
180 for pid in pids:
181 try:
182 os.kill(int(pid), signal.SIGKILL)
183 except:
184 pass
185
186 def stop(self):
A R Karthick168e2342017-08-15 16:13:10 -0700187 if self.CONTAINER_MODE is False:
188 self.kill_service('python voltha/main.py')
189 self.kill_service('python ofagent/main.py')
A R Karthick168e2342017-08-15 16:13:10 -0700190 self.kill_service('python ponsim/main.py')
A R Karthickaa6475d2017-08-15 17:24:36 -0700191 self.kill_service('python chameleon/main.py')
A R Karthick168e2342017-08-15 16:13:10 -0700192 service_stop_cmd = 'DOCKER_HOST_IP={} docker-compose -p {} -f {} down'.format(self.DOCKER_HOST_IP,
193 self.PROJECT,
194 self.compose_file_loc)
A.R Karthick57fa9372017-05-24 12:47:03 -0700195 os.system(service_stop_cmd)
A R Karthick35495c32017-05-11 14:58:32 -0700196
A R Karthick168e2342017-08-15 16:13:10 -0700197 @classmethod
198 def get_ip(cls, service):
199 if service in cls.service_map:
200 return cls.service_map[service]['ip']
201 if service == cls.REST_SERVICE:
202 return os.getenv('VOLTHA_HOST', None)
203 return None
204
205 @classmethod
206 def get_network(cls, service):
207 if service in cls.service_map:
208 return cls.service_map[service]['network']
209 return None
210
A R Karthick35495c32017-05-11 14:58:32 -0700211class VolthaCtrl(object):
A R Karthick53442712017-07-27 12:23:30 -0700212 UPLINK_VLAN_START = 333
A.R Karthick4c4d0492017-05-26 19:23:05 -0700213 UPLINK_VLAN_MAP = { 'of:0000000000000001' : '222' }
A R Karthicke7232092017-09-07 18:01:33 -0700214 REST_PORT = 8882
A R Karthick53442712017-07-27 12:23:30 -0700215 HOST = '172.17.0.1'
A R Karthickcf1a5d32017-10-05 16:04:43 -0700216 ONOS_APPS = ('org.onosproject.hostprovider', 'org.onosproject.dhcp', 'org.onosproject.dhcp-relay', 'org.ciena.cordigmp')
A R Karthick32e711a2017-08-22 16:27:22 -0700217 ADMIN_STATE = 'admin_state'
218 OPER_STATUS = 'oper_status'
219 CONNECT_STATUS = 'connect_status'
A.R Karthick4c4d0492017-05-26 19:23:05 -0700220
A R Karthick18d0fb62017-09-01 18:49:07 -0700221 def __init__(self, host = HOST, rest_port = REST_PORT, uplink_vlan_map = UPLINK_VLAN_MAP,
222 uplink_vlan_start = UPLINK_VLAN_START):
A R Karthick35495c32017-05-11 14:58:32 -0700223 self.host = host
224 self.rest_port = rest_port
A R Karthick32e711a2017-08-22 16:27:22 -0700225 self.rest_url = 'http://{}:{}/api/v1/local'.format(host, rest_port)
226 if rest_port == 8882:
227 self.rest_url = 'http://{}:{}/api/v1'.format(host, rest_port)
A R Karthicke7232092017-09-07 18:01:33 -0700228 #self.ADMIN_STATE = 'adminState'
229 #self.OPER_STATUS = 'operStatus'
230 #self.CONNECT_STATUS = 'connectStatus'
A.R Karthick4c4d0492017-05-26 19:23:05 -0700231 self.uplink_vlan_map = uplink_vlan_map
A R Karthick53442712017-07-27 12:23:30 -0700232 VolthaCtrl.UPLINK_VLAN_START = uplink_vlan_start
A.R Karthick4c4d0492017-05-26 19:23:05 -0700233 self.switches = []
234 self.switch_map = {}
235
A R Karthick18d0fb62017-09-01 18:49:07 -0700236 def config(self, fake = False, driver_configured = False):
A.R Karthick4c4d0492017-05-26 19:23:05 -0700237 devices = OnosCtrl.get_devices()
238 if not devices:
239 return self.switch_map
240 voltha_devices = filter(lambda d: not d['mfr'].startswith('Nicira'), devices)
241 self.switches = voltha_devices
242 device_config = { 'devices' : { } }
243 device_id = None
244 for device in voltha_devices:
245 device_id = device['id']
A R Karthick1555c7c2017-09-07 14:59:41 -0700246 serial = device['serial']
A.R Karthick4c4d0492017-05-26 19:23:05 -0700247 ports = OnosCtrl.get_ports_device(device_id)
248 nni_ports = filter(lambda p: p['isEnabled'] and 'annotations' in p and p['annotations']['portName'].startswith('nni'), ports)
249 uni_ports = filter(lambda p: p['isEnabled'] and 'annotations' in p and p['annotations']['portName'].startswith('uni'), ports)
250 if device_id not in self.uplink_vlan_map:
A R Karthick53442712017-07-27 12:23:30 -0700251 uplink_vlan = VolthaCtrl.UPLINK_VLAN_START
252 VolthaCtrl.UPLINK_VLAN_START += 1
A R Karthick18d0fb62017-09-01 18:49:07 -0700253 self.uplink_vlan_map[device_id] = uplink_vlan
A R Karthick53442712017-07-27 12:23:30 -0700254 log.info('Voltha device %s not in map. Using uplink vlan %d' %(device_id, uplink_vlan))
255 else:
256 uplink_vlan = self.uplink_vlan_map[device_id]
A.R Karthick4c4d0492017-05-26 19:23:05 -0700257 if not nni_ports:
258 log.info('Voltha device %s has no NNI ports' %device_id)
259 if fake is True:
260 log.info('Faking NNI port 0')
261 nni_ports = [ {'port': '0'} ]
262 else:
263 log.info('Skip configuring device %s' %device_id)
264 continue
265 if not uni_ports:
266 log.info('Voltha device %s has no UNI ports' %device_id)
267 if fake is True:
268 log.info('Faking UNI port 252')
269 uni_ports = [ {'port': '252'} ]
270 else:
271 log.info('Skip configuring device %s' %device_id)
272 continue
A.R Karthick4c4d0492017-05-26 19:23:05 -0700273 onu_ports = map(lambda uni: uni['port'], uni_ports)
A R Karthick1555c7c2017-09-07 14:59:41 -0700274 onu_names = map(lambda uni: uni['annotations']['portName'], uni_ports)
275 onu_macs = map(lambda uni: uni['annotations']['portMac'], uni_ports)
276 self.switch_map[device_id] = dict(uplink_vlan = uplink_vlan,
277 serial = serial,
278 ports = onu_ports,
279 names = onu_names,
280 macs = onu_macs)
A.R Karthick4c4d0492017-05-26 19:23:05 -0700281 device_config['devices'][device_id] = {}
282 device_config['devices'][device_id]['basic'] = dict(driver='pmc-olt')
283 device_config['devices'][device_id]['accessDevice'] = dict(uplink=nni_ports[0]['port'],
284 vlan = uplink_vlan,
A R Karthick4eb90dd2017-09-01 13:46:30 -0700285 defaultVlan=str(onu_ports[0])
A.R Karthick4c4d0492017-05-26 19:23:05 -0700286 )
A R Karthick18d0fb62017-09-01 18:49:07 -0700287 if device_id and driver_configured is False:
A.R Karthick4c4d0492017-05-26 19:23:05 -0700288 #toggle drivers/openflow base before reconfiguring the driver and olt config data
289 OnosCtrl('org.onosproject.drivers').deactivate()
290 OnosCtrl('org.onosproject.openflow-base').deactivate()
291 OnosCtrl.config(device_config)
A R Karthick6e70e142017-07-28 15:25:38 -0700292 time.sleep(10)
A.R Karthick4c4d0492017-05-26 19:23:05 -0700293 OnosCtrl('org.onosproject.drivers').activate()
294 OnosCtrl('org.onosproject.openflow-base').activate()
A R Karthick4eb90dd2017-09-01 13:46:30 -0700295 time.sleep(10)
A R Karthick6e70e142017-07-28 15:25:38 -0700296 log.info('Reactivating CORD and ONOS apps')
297 Onos.activate_cord_apps(deactivate = True)
298 Onos.activate_apps(self.ONOS_APPS, deactivate = True)
A.R Karthick4c4d0492017-05-26 19:23:05 -0700299
300 return self.switch_map
A R Karthick35495c32017-05-11 14:58:32 -0700301
302 def get_devices(self):
A R Karthick32e711a2017-08-22 16:27:22 -0700303 url = '{}/devices'.format(self.rest_url)
A R Karthick35495c32017-05-11 14:58:32 -0700304 resp = requests.get(url)
305 if resp.ok is not True or resp.status_code != 200:
306 return None
307 return resp.json()
308
A.R Karthick8b9c5f12017-05-30 17:47:08 -0700309 def enable_device(self, olt_type, olt_mac = None, address = None):
A R Karthick32e711a2017-08-22 16:27:22 -0700310 url = '{}/devices'.format(self.rest_url)
A.R Karthick8b9c5f12017-05-30 17:47:08 -0700311 if olt_mac is None and address is None:
312 log.error('Either olt mac or address needs to be specified')
A.R Karthick8a507cf2017-06-02 18:44:49 -0700313 return None, False
A.R Karthick8b9c5f12017-05-30 17:47:08 -0700314 if olt_mac is not None:
315 device_config = { 'type' : olt_type, 'mac_address' : olt_mac }
316 else:
A R Karthick31a40172017-08-14 12:06:09 -0700317 if len(address.split(':')) > 1:
318 device_config = { 'type' : olt_type, 'host_and_port' : address }
319 else:
320 device_config = { 'type' : olt_type, 'ipv4_address' : address }
A R Karthick35495c32017-05-11 14:58:32 -0700321 #pre-provision
A.R Karthick8b9c5f12017-05-30 17:47:08 -0700322 if olt_mac is not None:
323 log.info('Pre-provisioning %s with mac %s' %(olt_type, olt_mac))
324 else:
A R Karthickaa6475d2017-08-15 17:24:36 -0700325 log.info('Pre-provisioning %s with address %s' %(olt_type, address))
A R Karthick35495c32017-05-11 14:58:32 -0700326 resp = requests.post(url, data = json.dumps(device_config))
327 if resp.ok is not True or resp.status_code != 200:
A.R Karthick8a507cf2017-06-02 18:44:49 -0700328 return None, False
A R Karthick35495c32017-05-11 14:58:32 -0700329 device_id = resp.json()['id']
330 log.info('Enabling device %s' %(device_id))
331 enable_url = '{}/{}/enable'.format(url, device_id)
332 resp = requests.post(enable_url)
333 if resp.ok is not True or resp.status_code != 200:
A.R Karthick8a507cf2017-06-02 18:44:49 -0700334 return None, False
A R Karthick35495c32017-05-11 14:58:32 -0700335 #get operational status
A R Karthick090631b2017-07-25 16:05:05 -0700336 time.sleep(10)
A R Karthick35495c32017-05-11 14:58:32 -0700337 log.info('Checking operational status for device %s' %(device_id))
338 resp = requests.get('{}/{}'.format(url, device_id))
339 if resp.ok is not True or resp.status_code != 200:
A.R Karthick8a507cf2017-06-02 18:44:49 -0700340 return device_id, False
A R Karthick35495c32017-05-11 14:58:32 -0700341 device_info = resp.json()
A R Karthick32e711a2017-08-22 16:27:22 -0700342 if device_info[self.OPER_STATUS] != 'ACTIVE' or \
343 device_info[self.ADMIN_STATE] != 'ENABLED' or \
344 device_info[self.CONNECT_STATUS] != 'REACHABLE':
A.R Karthick8a507cf2017-06-02 18:44:49 -0700345 return device_id, False
A R Karthick35495c32017-05-11 14:58:32 -0700346
A.R Karthick8a507cf2017-06-02 18:44:49 -0700347 return device_id, True
348
349 def disable_device(self, device_id, delete = True):
350 log.info('Disabling device %s' %(device_id))
A R Karthick32e711a2017-08-22 16:27:22 -0700351 disable_url = '{}/devices/{}/disable'.format(self.rest_url, device_id)
A.R Karthick8a507cf2017-06-02 18:44:49 -0700352 resp = requests.post(disable_url)
353 if resp.ok is not True or resp.status_code != 200:
354 return False
355 if delete is True:
A R Karthickd69d5702017-07-25 11:31:47 -0700356 #rest for disable completion
357 time.sleep(10)
A.R Karthick8a507cf2017-06-02 18:44:49 -0700358 log.info('Deleting device %s' %(device_id))
A R Karthick32e711a2017-08-22 16:27:22 -0700359 delete_url = '{}/devices/{}/delete'.format(self.rest_url, device_id)
A.R Karthick8a507cf2017-06-02 18:44:49 -0700360 resp = requests.delete(delete_url)
361 if resp.status_code not in [204, 202, 200]:
362 return False
A R Karthick35495c32017-05-11 14:58:32 -0700363 return True
Chetan Gaonker3620a112017-05-23 06:10:15 +0000364
Thangavelu K Se6c77c72017-06-23 21:28:48 +0000365 def restart_device(self, device_id):
366 log.info('Restarting olt or onu device %s' %(device_id))
A R Karthick32e711a2017-08-22 16:27:22 -0700367 disable_url = '{}/devices/{}/restart'.format(self.rest_url, device_id)
Thangavelu K Se6c77c72017-06-23 21:28:48 +0000368 resp = requests.post(disable_url)
369 if resp.ok is not True or resp.status_code != 200:
370 return False
371 return True
372
373 def pause_device(self, device_id):
374 log.info('Restarting olt or onu device %s' %(device_id))
A R Karthick32e711a2017-08-22 16:27:22 -0700375 disable_url = '{}/devices/{}/pause'.format(self.rest_url, device_id)
Thangavelu K Se6c77c72017-06-23 21:28:48 +0000376 resp = requests.post(disable_url)
377 if resp.ok is not True or resp.status_code != 200:
378 return False
379 return True
380
Chetan Gaonker3620a112017-05-23 06:10:15 +0000381 def get_operational_status(self, device_id):
A R Karthick32e711a2017-08-22 16:27:22 -0700382 url = '{}/devices'.format(self.rest_url)
Chetan Gaonker3620a112017-05-23 06:10:15 +0000383 log.info('Checking operational status for device %s' %(device_id))
384 resp = requests.get('{}/{}'.format(url, device_id))
385 if resp.ok is not True or resp.status_code != 200:
386 return False
387 device_info = resp.json()
A R Karthick32e711a2017-08-22 16:27:22 -0700388 if device_info[self.OPER_STATUS] != 'ACTIVE' or \
389 device_info[self.ADMIN_STATE] != 'ENABLED' or \
390 device_info[self.CONNECT_STATUS] != 'REACHABLE':
Chetan Gaonker3620a112017-05-23 06:10:15 +0000391 return False
392 return True
393
394 def check_preprovision_status(self, device_id):
A R Karthick32e711a2017-08-22 16:27:22 -0700395 url = '{}/devices'.format(self.rest_url)
Chetan Gaonker3620a112017-05-23 06:10:15 +0000396 log.info('Check if device %s is in Preprovisioning state'%(device_id))
397 resp = requests.get('{}/{}'.format(url, device_id))
398 if resp.ok is not True or resp.status_code != 200:
399 return False
400 device_info = resp.json()
A R Karthick32e711a2017-08-22 16:27:22 -0700401 if device_info[self.ADMIN_STATE] == 'PREPROVISIONED':
Chetan Gaonker3620a112017-05-23 06:10:15 +0000402 return True
403 return False
A R Karthickbf1e4b02017-07-11 20:17:14 -0700404
405def get_olt_app():
406 our_path = os.path.dirname(os.path.realpath(__file__))
407 version = Onos.getVersion()
408 major = int(version.split('.')[0])
409 minor = int(version.split('.')[1])
410 olt_app_version = '1.2-SNAPSHOT'
411 if major > 1:
A R Karthick1555c7c2017-09-07 14:59:41 -0700412 olt_app_version = '3.0-SNAPSHOT'
A R Karthickbf1e4b02017-07-11 20:17:14 -0700413 elif major == 1:
A R Karthick1555c7c2017-09-07 14:59:41 -0700414 if minor >= 10:
415 olt_app_version = '3.0-SNAPSHOT'
A R Karthickbf1e4b02017-07-11 20:17:14 -0700416 elif minor <= 8:
417 olt_app_version = '1.1-SNAPSHOT'
418 olt_app_file = os.path.join(our_path, '..', 'apps/olt-app-{}.oar'.format(olt_app_version))
419 return olt_app_file
420
A R Karthick168e2342017-08-15 16:13:10 -0700421def voltha_setup(host = '172.17.0.1', ponsim_host = VolthaService.PONSIM_HOST, olt_ip = None, rest_port = VolthaCtrl.REST_PORT,
A R Karthick9dc6e922017-07-12 14:40:16 -0700422 olt_type = 'ponsim_olt', olt_mac = '00:0c:e2:31:12:00',
A R Karthickbf1e4b02017-07-11 20:17:14 -0700423 uplink_vlan_map = VolthaCtrl.UPLINK_VLAN_MAP,
A R Karthick53442712017-07-27 12:23:30 -0700424 uplink_vlan_start = VolthaCtrl.UPLINK_VLAN_START,
A R Karthick18d0fb62017-09-01 18:49:07 -0700425 config_fake = False, olt_app = None, teardown = True):
426 devices = OnosCtrl.get_devices()
427 olt_devices = filter(lambda d: not d['mfr'].startswith('Nicira') and d['driver'] == 'pmc-olt', devices)
A R Karthick53442712017-07-27 12:23:30 -0700428 voltha = VolthaCtrl(host, rest_port = rest_port,
429 uplink_vlan_map = uplink_vlan_map,
430 uplink_vlan_start = uplink_vlan_start)
A R Karthick18d0fb62017-09-01 18:49:07 -0700431 voltha_devices = voltha.get_devices()
432 if voltha_devices:
433 voltha_device_ids = filter(lambda d: d[voltha.OPER_STATUS] == 'ACTIVE' and d[voltha.ADMIN_STATE] == 'ENABLED',
434 voltha_devices['items'])
A R Karthickbf1e4b02017-07-11 20:17:14 -0700435 else:
A R Karthick18d0fb62017-09-01 18:49:07 -0700436 voltha_device_ids = []
437
438 driver_configured = len(olt_devices) > 0 and len(voltha_device_ids) > 0
439 if olt_type.startswith('ponsim'):
440 if driver_configured:
441 device_id, status = voltha_device_ids[0], True
A R Karthick31a40172017-08-14 12:06:09 -0700442 else:
A R Karthick18d0fb62017-09-01 18:49:07 -0700443 ponsim_address = '{}:50060'.format(ponsim_host)
444 log.info('Enabling ponsim olt')
445 device_id, status = voltha.enable_device(olt_type, address = ponsim_address)
446 else:
447 if driver_configured:
448 device_id, status = voltha_device_ids[0], True
449 else:
A R Karthickcafe4d82017-09-14 12:29:21 -0700450 if olt_type.startswith('maple') or olt_ip:
A R Karthick18d0fb62017-09-01 18:49:07 -0700451 if olt_ip:
452 log.info('Enabling %s' %olt_type)
453 device_id, status = voltha.enable_device(olt_type, address = olt_ip)
454 else:
A R Karthickcafe4d82017-09-14 12:29:21 -0700455 log.info('OLT IP needs to be specified for %s' %olt_type)
A R Karthick18d0fb62017-09-01 18:49:07 -0700456 else:
457 log.info('Enabling OLT instance for %s with mac %s' %(olt_type, olt_mac))
458 device_id, status = voltha.enable_device(olt_type, olt_mac)
A R Karthickbf1e4b02017-07-11 20:17:14 -0700459
460 if device_id is None or status is False:
A R Karthick9dc6e922017-07-12 14:40:16 -0700461 if device_id:
462 voltha.disable_device(device_id)
A R Karthickbf1e4b02017-07-11 20:17:14 -0700463 return None
464
465 switch_map = None
466 olt_installed = False
467 if olt_app is None:
468 olt_app = get_olt_app()
469 try:
A R Karthick090631b2017-07-25 16:05:05 -0700470 time.sleep(5)
A R Karthick18d0fb62017-09-01 18:49:07 -0700471 switch_map = voltha.config(fake = config_fake, driver_configured = driver_configured)
A R Karthickbf1e4b02017-07-11 20:17:14 -0700472 if switch_map is None:
473 voltha.disable_device(device_id)
474 return None
475 log.info('Installing OLT app %s' %olt_app)
476 OnosCtrl.install_app(olt_app)
477 olt_installed = True
478 time.sleep(5)
A R Karthick21782982017-10-02 10:49:22 -0700479 OnosCtrl.config_olt_component()
A R Karthick18d0fb62017-09-01 18:49:07 -0700480 return voltha, device_id, switch_map, driver_configured
A R Karthickbf1e4b02017-07-11 20:17:14 -0700481 except:
482 voltha.disable_device(device_id)
483 time.sleep(10)
484 if olt_installed is True:
485 log.info('Uninstalling OLT app %s' %olt_app)
486 OnosCtrl.uninstall_app(olt_app)
487
488 return None
489
490def voltha_teardown(voltha_ctrl, device_id, switch_map, olt_app = None):
A R Karthick6708f562017-09-05 12:15:31 -0700491 if voltha_ctrl:
492 voltha_ctrl.disable_device(device_id)
A R Karthickbf1e4b02017-07-11 20:17:14 -0700493 time.sleep(10)
494 if olt_app is None:
495 olt_app = get_olt_app()
A R Karthickdd064632017-07-12 13:02:17 -0700496 log.info('Uninstalling OLT app %s' %olt_app)
A R Karthickbf1e4b02017-07-11 20:17:14 -0700497 OnosCtrl.uninstall_app(olt_app)