[CORD-3156] Adding support for mac_address in olt-service
Change-Id: I945257416f527b2d019231c9abc4cdf44a5a6a58
diff --git a/samples/olt_device.yaml b/samples/olt_device_host_and_port.yaml
similarity index 91%
rename from samples/olt_device.yaml
rename to samples/olt_device_host_and_port.yaml
index 93c905f..db74731 100644
--- a/samples/olt_device.yaml
+++ b/samples/olt_device_host_and_port.yaml
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# curl -H "xos-username: admin@opencord.org" -H "xos-password: letmein" -X POST --data-binary @olt_device.yaml http://192.168.99.100:30007/run
+# curl -H "xos-username: admin@opencord.org" -H "xos-password: letmein" -X POST --data-binary @olt_device_host_and_port.yaml http://192.168.99.100:30007/run
tosca_definitions_version: tosca_simple_yaml_1_0
imports:
@@ -32,7 +32,7 @@
type: tosca.nodes.OLTDevice
properties:
name: test_olt
- device_type: simulated_olt
+ device_type: ponsim
host: 172.17.0.1
port: 50060
switch_datapath_id: of:0000000000000001
diff --git a/samples/olt_device.yaml b/samples/olt_device_mac_address.yaml
similarity index 90%
copy from samples/olt_device.yaml
copy to samples/olt_device_mac_address.yaml
index 93c905f..42213bb 100644
--- a/samples/olt_device.yaml
+++ b/samples/olt_device_mac_address.yaml
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# curl -H "xos-username: admin@opencord.org" -H "xos-password: letmein" -X POST --data-binary @olt_device.yaml http://192.168.99.100:30007/run
+# curl -H "xos-username: admin@opencord.org" -H "xos-password: letmein" -X POST --data-binary @olt_device_mac_address.yaml http://192.168.99.100:30007/run
tosca_definitions_version: tosca_simple_yaml_1_0
imports:
@@ -33,8 +33,7 @@
properties:
name: test_olt
device_type: simulated_olt
- host: 172.17.0.1
- port: 50060
+ mac_address: 00:0c:e2:31:40:00
switch_datapath_id: of:0000000000000001
switch_port: "1"
outer_tpid: "0x8100"
diff --git a/xos/synchronizer/models/models.py b/xos/synchronizer/models/models.py
index ed1e062..3dcefae 100644
--- a/xos/synchronizer/models/models.py
+++ b/xos/synchronizer/models/models.py
@@ -46,6 +46,13 @@
def get_volt_si(self):
return VOLTServiceInstance.objects.all()
+ def save(self, *args, **kwargs):
+
+ if (self.host or self.port) and self.mac_address:
+ raise XOSValidationError("You can't specify both host/port and mac_address for OLTDevice [host=%s, port=%s, mac_address=%s]" % (self.host, self.port, self.mac_address))
+
+ super(OLTDevice, self).save(*args, **kwargs)
+
def delete(self, *args, **kwargs):
onus = []
diff --git a/xos/synchronizer/models/test_oltdevice_model.py b/xos/synchronizer/models/test_oltdevice_model.py
index 34bf200..5da9583 100644
--- a/xos/synchronizer/models/test_oltdevice_model.py
+++ b/xos/synchronizer/models/test_oltdevice_model.py
@@ -40,13 +40,24 @@
from models import OLTDevice
- print OLTDevice
-
self.olt_device = OLTDevice()
self.olt_device.id = None # this is a new model
self.olt_device.is_new = True
self.olt_device.device_id = 1234
+ def test_create_mac_address(self):
+ from models import OLTDevice
+ olt = OLTDevice()
+
+ olt.host = "1.1.1.1"
+ olt.port = "9101"
+ olt.mac_address = "00:0c:d5:00:05:40"
+
+ with self.assertRaises(Exception) as e:
+ olt.save()
+
+ self.assertEqual(e.exception.message,
+ "You can't specify both host/port and mac_address for OLTDevice [host=%s, port=%s, mac_address=%s]" % (olt.host, olt.port, olt.mac_address))
def test_delete(self):
self.olt_device.delete()
diff --git a/xos/synchronizer/models/volt.xproto b/xos/synchronizer/models/volt.xproto
index 39383f4..3106210 100644
--- a/xos/synchronizer/models/volt.xproto
+++ b/xos/synchronizer/models/volt.xproto
@@ -23,8 +23,9 @@
required manytoone volt_service->VOLTService:volt_devices = 1 [db_index = True, null = False, blank = False];
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];
+ optional string host = 4 [help_text = "Device IP", max_length = 254, null = True, db_index = False, blank = True];
+ optional int32 port = 5 [help_text = "Device port", null = True, db_index = False, blank = True, tosca_key_one_of=host];
+ optional string mac_address = 6 [help_text = "Device mac address", null = True, db_index = False, blank = True, tosca_key_one_of=host];
optional string device_id = 10 [help_text = "Device ID", null = True, db_index = False, blank = False, feedback_state = True];
optional string admin_state = 11 [help_text = "admin_state", null = True, db_index = False, blank = False, feedback_state = True];
diff --git a/xos/synchronizer/steps/sync_olt_device.py b/xos/synchronizer/steps/sync_olt_device.py
index 8ebef89..29722f9 100644
--- a/xos/synchronizer/steps/sync_olt_device.py
+++ b/xos/synchronizer/steps/sync_olt_device.py
@@ -57,14 +57,13 @@
voltha = Helpers.get_voltha_info(model.volt_service)
data = {
- "type": model.device_type,
- "host_and_port": "%s:%s" % (model.host, model.port)
+ "type": model.device_type
}
- 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"
+ if hasattr(model, "host") and hasattr(model, "port"):
+ data["host_and_port"] = "%s:%s" % (model.host, model.port)
+ elif hasattr(model, "mac_address"):
+ data["mac_address"] = model.mac_address
log.info("Pushing OLT to Voltha", data=data)
diff --git a/xos/synchronizer/steps/test_sync_olt_device.py b/xos/synchronizer/steps/test_sync_olt_device.py
index 4d785b5..2ee20ff 100644
--- a/xos/synchronizer/steps/test_sync_olt_device.py
+++ b/xos/synchronizer/steps/test_sync_olt_device.py
@@ -13,6 +13,7 @@
# limitations under the License.
import unittest
+import functools
from mock import patch, call, Mock, PropertyMock
import requests_mock
@@ -51,6 +52,12 @@
return False
return True
+def match_json(desired, req):
+ if desired!=req.json():
+ raise Exception("Got request %s, but body is not matching" % req.url)
+ return False
+ return True
+
class TestSyncOLTDevice(unittest.TestCase):
def setUp(self):
global DeferredException
@@ -82,7 +89,7 @@
pon_port.port_id = "00ff00"
pon_port.s_tag = "s_tag"
- # Create a mock service instance
+ # Create a mock OLTDevice
o = Mock()
o.volt_service.voltha_url = "voltha_url"
o.volt_service.voltha_port = 1234
@@ -176,7 +183,13 @@
"""
If device.enable succed should fetch the state, retrieve the of_id and push it to ONOS
"""
- m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json={"id": "123"})
+
+ expected_conf = {
+ "type": self.o.device_type,
+ "host_and_port": "%s:%s" % (self.o.host, self.o.port)
+ }
+
+ m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json={"id": "123"}, additional_matcher=functools.partial(match_json, expected_conf))
m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
m.get("http://voltha_url:1234/api/v1/devices/123", json={"oper_status": "ENABLED", "admin_state": "ACTIVE"})
logical_devices = {
@@ -196,6 +209,42 @@
self.o.save.assert_called_once()
@requests_mock.Mocker()
+ def test_sync_record_success_mac_address(self, m):
+ """
+ A device should be pre-provisioned via mac_address, the the process is the same
+ """
+
+ del self.o.host
+ del self.o.port
+ self.o.mac_address = "00:0c:e2:31:40:00"
+
+ expected_conf = {
+ "type": self.o.device_type,
+ "mac_address": self.o.mac_address
+ }
+
+ m.post("http://voltha_url:1234/api/v1/devices", status_code=200, json={"id": "123"},
+ additional_matcher=functools.partial(match_json, expected_conf))
+ m.post("http://voltha_url:1234/api/v1/devices/123/enable", status_code=200)
+ m.get("http://voltha_url:1234/api/v1/devices/123", json={"oper_status": "ENABLED", "admin_state": "ACTIVE"})
+ logical_devices = {
+ "items": [
+ {"root_device_id": "123", "id": "0001000ce2314000", "datapath_id": "55334486016"},
+ {"root_device_id": "0001cc4974a62b87", "id": "0001000000000001"}
+ ]
+ }
+ m.get("http://voltha_url:1234/api/v1/logical_devices", status_code=200, json=logical_devices)
+
+ m.post("http://onos_voltha_url:4321/onos/v1/network/configuration/", status_code=200,
+ additional_matcher=match_onos_req, json={})
+
+ self.sync_step().sync_record(self.o)
+ self.assertEqual(self.o.admin_state, "ACTIVE")
+ self.assertEqual(self.o.oper_status, "ENABLED")
+ self.assertEqual(self.o.of_id, "0001000ce2314000")
+ self.o.save.assert_called_once()
+
+ @requests_mock.Mocker()
def test_sync_record_already_existing_in_voltha(self, m):
# mock device feedback state
self.o.device_id = "123"