[CORD-3017] Working around ONOS driver issue
Change-Id: I8ac1735927409aaaffe3a7654925261314faa149
diff --git a/xos/synchronizer/models/volt.xproto b/xos/synchronizer/models/volt.xproto
index d7e8b70..16c3955 100644
--- a/xos/synchronizer/models/volt.xproto
+++ b/xos/synchronizer/models/volt.xproto
@@ -29,7 +29,7 @@
option description="Represents a physical OLT device";
required manytoone volt_service->VOLTService:volt_devices = 1 [db_index = True, null = False, blank = False];
- required string name = 2 [help_text = "name of device", max_length = 254, null = False, db_index = False, blank = False, unique = True];
+ optional string name = 2 [help_text = "name of device", max_length = 254, null = True, db_index = False, blank = True, unique = True];
required string device_type = 3 [help_text = "Device Type", default = "asfvolt16_olt", max_length = 254, null = False, db_index = False, blank = False, tosca_key=True];
required string host = 4 [help_text = "Host", max_length = 254, null = False, db_index = False, blank = False, tosca_key=True];
required int32 port = 5 [help_text = "Fabric port", null = False, db_index = False, blank = False, tosca_key=True];
diff --git a/xos/synchronizer/steps/sync_olt_device.py b/xos/synchronizer/steps/sync_olt_device.py
index 4a42ec1..cb2d4c6 100644
--- a/xos/synchronizer/steps/sync_olt_device.py
+++ b/xos/synchronizer/steps/sync_olt_device.py
@@ -46,128 +46,165 @@
o.dp_id = "of:%s" % (Helpers.datapath_id_to_hex(ld["datapath_id"])) # Convert to hex
return o
- raise Exception("Can't find a logical device for device id: %s" % o.device_id)
+ raise Exception("Can't find a logical_device for OLT device id: %s" % o.device_id)
+ def pre_provision_olt_device(self, model):
+ log.info("Pre-provisioning OLT device in VOLTHA", object=str(model), **model.tologdict())
- def sync_record(self, o):
- log.info("Synching device", object=str(o), **o.tologdict())
+ voltha = Helpers.get_voltha_info(model.volt_service)
- voltha = Helpers.get_voltha_info(o.volt_service)
- onos_voltha = Helpers.get_onos_voltha_info(o.volt_service)
+ data = {
+ "type": model.device_type,
+ "host_and_port": "%s:%s" % (model.host, model.port)
+ }
+
+ if model.device_type == 'simulated_olt':
+ # Simulated devices won't accept host and port. This is to enable tests in voltha without having a real olt or ponsim
+ data.pop('host_and_port')
+ data['mac_address'] = "00:0c:e2:31:40:00"
+
+ log.info("Pushing OLT to Voltha", data=data)
+
+ request = requests.post("%s:%d/api/v1/devices" % (voltha['url'], voltha['port']), json=data)
+
+ if request.status_code != 200:
+ raise Exception("Failed to add OLT device: %s" % request.text)
+
+ log.info("Add device response", text=request.text)
+
+ res = request.json()
+
+ log.info("Add device json res", res=res)
+
+ if not res['id']:
+ raise Exception(
+ 'VOLTHA Device Id is empty. This probably means that the OLT device is already provisioned in VOLTHA')
+ else:
+ model.device_id = res['id'];
+
+ return model
+
+ def activate_olt(self, model):
+
+ voltha = Helpers.get_voltha_info(model.volt_service)
+
+ # Enable device
+ request = requests.post("%s:%d/api/v1/devices/%s/enable" % (voltha['url'], voltha['port'], model.device_id))
+
+ if request.status_code != 200:
+ raise Exception("Failed to enable OLT device: %s" % request.text)
+
+ # Read state
+ request = requests.get("%s:%d/api/v1/devices/%s" % (voltha['url'], voltha['port'], model.device_id)).json()
+ while request['oper_status'] == "ACTIVATING":
+ log.info("Waiting for OLT device %s (%s) to activate" % (model.name, model.device_id))
+ sleep(5)
+ request = requests.get("%s:%d/api/v1/devices/%s" % (voltha['url'], voltha['port'], model.device_id)).json()
+
+ model.admin_state = request['admin_state']
+ model.oper_status = request['oper_status']
+
+ # Find the of_id of the device
+ model = self.get_ids_from_logical_device(model)
+ model.save()
+
+ return model
+
+ def configure_onos(self, model):
+
+ onos_voltha = Helpers.get_onos_voltha_info(model.volt_service)
onos_voltha_basic_auth = HTTPBasicAuth(onos_voltha['user'], onos_voltha['pass'])
- # If the device has feedback_state is already present in voltha
- if not o.device_id and not o.admin_state and not o.oper_status and not o.of_id:
- log.info("Pushing device to VOLTHA", object=str(o), **o.tologdict())
-
- data = {
- "type": o.device_type,
- "host_and_port": "%s:%s" % (o.host, o.port)
- }
-
- if o.device_type == 'simulated_olt':
- # Simulated devices will not accept host and port. This is for test only
- data.pop('host_and_port')
- data['mac_address'] = "00:0c:e2:31:40:00"
-
- log.info("Pushing OLT to Voltha", data=data)
-
- request = requests.post("%s:%d/api/v1/devices" % (voltha['url'], voltha['port']), json=data)
-
- if request.status_code != 200:
- raise Exception("Failed to add device: %s" % request.text)
-
- log.info("Add device response", text=request.text)
-
- res = request.json()
-
- log.info("Add device json res", res=res)
-
- if not res['id']:
- raise Exception('VOLTHA Device Id is empty, this probably means that the device is already provisioned in VOLTHA')
- else:
- o.device_id = res['id'];
-
- # Enable device
- request = requests.post("%s:%d/api/v1/devices/%s/enable" % (voltha['url'], voltha['port'], o.device_id))
-
- if request.status_code != 200:
- raise Exception("Failed to enable device: %s" % request.text)
-
- # Read state
- request = requests.get("%s:%d/api/v1/devices/%s" % (voltha['url'], voltha['port'], o.device_id)).json()
- while request['oper_status'] == "ACTIVATING":
- log.info("Waiting for device %s (%s) to activate" % (o.name, o.device_id))
- sleep(5)
- request = requests.get("%s:%d/api/v1/devices/%s" % (voltha['url'], voltha['port'], o.device_id)).json()
-
- o.admin_state = request['admin_state']
- o.oper_status = request['oper_status']
-
- # Find the of_id of the device
- o = self.get_ids_from_logical_device(o)
- o.save()
- else:
- log.info("Device already exists in VOLTHA", object=str(o), **o.tologdict())
-
-
- # Do we need to move this synchronization in a PON_PORT specific step?
# For now, we assume that each OLT has only one port
- vlan = o.ports.all()[0].s_tag
+ vlan = model.ports.all()[0].s_tag
# Add device info to onos-voltha
data = {
"devices": {
- o.dp_id: {
+ model.dp_id: {
"basic": {
- "driver": o.driver
+ "driver": model.driver
},
"accessDevice": {
- "uplink": o.uplink,
+ "uplink": model.uplink,
"vlan": vlan
}
}
}
}
- request = requests.post("%s:%d/onos/v1/network/configuration/" % (onos_voltha['url'], onos_voltha['port']), data=json.dumps(data), auth=onos_voltha_basic_auth)
+ url = "%s:%d/onos/v1/network/configuration/" % (onos_voltha['url'], onos_voltha['port'])
+ request = requests.post(url, json=data, auth=onos_voltha_basic_auth)
if request.status_code != 200:
log.error(request.text)
- raise Exception("Failed to add device %s into ONOS" % o.name)
+ raise Exception("Failed to add OLT device %s into ONOS" % model.name)
else:
try:
print request.json()
except Exception:
print request.text
+ return model
+
+ def hack_to_get_onos_to_load_the_proper_driver(self, model):
+ # Remove the device from ONOS
+ log.info("Updating ONOS driver")
+ onos_voltha = Helpers.get_onos_voltha_info(model.volt_service)
+ onos_voltha_basic_auth = HTTPBasicAuth(onos_voltha['user'], onos_voltha['pass'])
+ request = requests.delete("%s:%d/onos/v1/network/configuration/devices/%s" % (
+ onos_voltha['url'], onos_voltha['port'], model.of_id), auth=onos_voltha_basic_auth)
+
+ if request.status_code != 204:
+ log.error("Failed to remove OLT device from ONOS: %s - %s" % (model.name, model.of_id),
+ rest_response=request.text,
+ rest_status_code=request.status_code)
+ raise Exception("Failed to remove OLT device from ONOS")
+
+ def sync_record(self, model):
+ log.info("Synching device", object=str(model), **model.tologdict())
+
+ # If the device has feedback_state is already present in voltha
+ if not model.device_id and not model.admin_state and not model.oper_status and not model.of_id:
+ log.info("Pushing OLT device to VOLTHA", object=str(model), **model.tologdict())
+ model = self.pre_provision_olt_device(model)
+ self.activate_olt(model)
+ else:
+ log.info("OLT device already exists in VOLTHA", object=str(model), **model.tologdict())
+
+ self.configure_onos(model)
+
+ # FIXME this is need to solve a bug in ONOS
+ self.hack_to_get_onos_to_load_the_proper_driver(model)
+ # FIXME END
def delete_record(self, o):
- log.info("Deleting device", object=str(o), **o.tologdict())
+ log.info("Deleting OLT device", object=str(o), **o.tologdict())
voltha = Helpers.get_voltha_info(o.volt_service)
onos_voltha = Helpers.get_onos_voltha_info(o.volt_service)
onos_voltha_basic_auth = HTTPBasicAuth(onos_voltha['user'], onos_voltha['pass'])
if not o.device_id:
- log.error("Device %s has no device_id" % o.name)
+ log.error("OLTDevice %s has no device_id" % o.name)
else:
- # Remove the device from ONOS
- request = requests.delete("%s:%d/onos/v1/network/configuration/devices/%s" % (onos_voltha['url'], onos_voltha['port'], o.of_id), auth=onos_voltha_basic_auth)
-
- if request.status_code != 200:
- log.error("Failed to remove device from ONOS: %s - %s" % (o.name, o.of_id), rest_responese=request.text, rest_status_code=request.status_code)
- raise Exception("Failed to remove device in ONOS")
-
- # Disable the device
+ # Disable the OLT device
request = requests.post("%s:%d/api/v1/devices/%s/disable" % (voltha['url'], voltha['port'], o.device_id))
if request.status_code != 200:
- log.error("Failed to disable device in VOLTHA: %s - %s" % (o.name, o.device_id), rest_responese=request.text, rest_status_code=request.status_code)
- raise Exception("Failed to disable device in VOLTHA")
+ log.error("Failed to disable OLT device in VOLTHA: %s - %s" % (o.name, o.device_id), rest_response=request.text, rest_status_code=request.status_code)
+ raise Exception("Failed to disable OLT device in VOLTHA")
- # Delete the device
+ # Delete the OLT device
request = requests.delete("%s:%d/api/v1/devices/%s/delete" % (voltha['url'], voltha['port'], o.device_id))
if request.status_code != 200:
- log.error("Failed to delete device in VOLTHA: %s - %s" % (o.name, o.device_id), rest_responese=request.text, rest_status_code=request.status_code)
- raise Exception("Failed to delete device in VOLTHA")
+ log.error("Failed to delete OLT device from VOLTHA: %s - %s" % (o.name, o.device_id), rest_response=request.text, rest_status_code=request.status_code)
+ raise Exception("Failed to delete OLT device from VOLTHA")
+
+ # Remove the device from ONOS
+ request = requests.delete("%s:%d/onos/v1/network/configuration/devices/%s" % (
+ onos_voltha['url'], onos_voltha['port'], o.of_id), auth=onos_voltha_basic_auth)
+
+ if request.status_code != 204:
+ log.error("Failed to remove OLT device from ONOS: %s - %s" % (o.name, o.of_id), rest_response=request.text, rest_status_code=request.status_code)
+ raise Exception("Failed to remove OLT device from ONOS")
diff --git a/xos/synchronizer/steps/test_sync_olt_device.py b/xos/synchronizer/steps/test_sync_olt_device.py
index a1ef7b8..e73b249 100644
--- a/xos/synchronizer/steps/test_sync_olt_device.py
+++ b/xos/synchronizer/steps/test_sync_olt_device.py
@@ -126,7 +126,7 @@
with self.assertRaises(Exception) as e:
self.o.device_id = "idonotexist"
self.sync_step.get_ids_from_logical_device(self.o)
- self.assertEqual(e.exception.message, "Can't find a logical device for device id: idonotexist")
+ self.assertEqual(e.exception.message, "Can't find a logical_device for OLT device id: idonotexist")
@requests_mock.Mocker()
def test_sync_record_fail_add(self, m):
@@ -137,7 +137,7 @@
with self.assertRaises(Exception) as e:
self.sync_step().sync_record(self.o)
- self.assertEqual(e.exception.message, "Failed to add device: MockError")
+ self.assertEqual(e.exception.message, "Failed to add OLT device: MockError")
@requests_mock.Mocker()
def test_sync_record_fail_no_id(self, m):
@@ -148,7 +148,7 @@
with self.assertRaises(Exception) as e:
self.sync_step().sync_record(self.o)
- self.assertEqual(e.exception.message, "VOLTHA Device Id is empty, this probably means that the device is already provisioned in VOLTHA")
+ self.assertEqual(e.exception.message, "VOLTHA Device Id is empty. This probably means that the OLT device is already provisioned in VOLTHA")
@requests_mock.Mocker()
def test_sync_record_fail_enable(self, m):
@@ -160,7 +160,8 @@
with self.assertRaises(Exception) as e:
self.sync_step().sync_record(self.o)
- self.assertEqual(e.exception.message, "Failed to enable device: EnableError")
+
+ self.assertEqual(e.exception.message, "Failed to enable OLT device: EnableError")
@requests_mock.Mocker()
def test_sync_record_success(self, m):
@@ -180,6 +181,9 @@
m.post("http://onos_voltha_url:4321/onos/v1/network/configuration/", status_code = 200, additional_matcher=match_onos_req, json={})
+ # FIXME this is part of the block in the syncstep
+ m.delete("http://onos_voltha_url:4321/onos/v1/network/configuration/devices/0001000ce2314000", status_code=200)
+
self.sync_step().sync_record(self.o)
self.assertEqual(self.o.admin_state, "ACTIVE")
self.assertEqual(self.o.oper_status, "ENABLED")
@@ -193,9 +197,13 @@
self.o.admin_state = "ACTIVE"
self.o.oper_status = "ENABLED"
self.o.dp_id = "of:0000000ce2314000"
+ self.o.of_id = "0001000ce2314000"
m.post("http://onos_voltha_url:4321/onos/v1/network/configuration/", status_code = 200, additional_matcher=match_onos_req, json={})
+ # FIXME this is part of the block in the syncstep
+ m.delete("http://onos_voltha_url:4321/onos/v1/network/configuration/devices/0001000ce2314000", status_code=200)
+
self.sync_step().sync_record(self.o)
self.o.save.assert_not_called()