[CORD-2962] Refactoring vrouter and adding support for static routes
Change-Id: Ie2719ca94296559caee4a1e433631cbd43019bf9
diff --git a/xos/synchronizer/steps/helpers.py b/xos/synchronizer/steps/helpers.py
new file mode 100644
index 0000000..63585aa
--- /dev/null
+++ b/xos/synchronizer/steps/helpers.py
@@ -0,0 +1,30 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class Helpers():
+ @staticmethod
+ def format_url(url):
+ if 'http' in url:
+ return url
+ else:
+ return 'http://%s' % url
+
+ @staticmethod
+ def get_onos_info(onos_service):
+ return {
+ 'url': Helpers.format_url(onos_service.rest_hostname),
+ 'port': onos_service.rest_port,
+ 'user': onos_service.rest_username,
+ 'pass': onos_service.rest_password
+ }
diff --git a/xos/synchronizer/steps/sync_routes.py b/xos/synchronizer/steps/sync_routes.py
new file mode 100644
index 0000000..5086933
--- /dev/null
+++ b/xos/synchronizer/steps/sync_routes.py
@@ -0,0 +1,83 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import requests
+from requests.auth import HTTPBasicAuth
+from synchronizers.new_base.syncstep import SyncStep, DeferredException
+from synchronizers.new_base.modelaccessor import VRouterStaticRoute
+
+from helpers import Helpers
+from multistructlog import create_logger
+from xosconfig import Config
+
+log = create_logger(Config().get('logging'))
+
+class SyncRoutes(SyncStep):
+ provides = [VRouterStaticRoute]
+ observes = VRouterStaticRoute
+
+ # Get fabric service info
+ def get_onos_fabric_service(self, model):
+ vrouter_service = model.vrouter.owner
+ fabric_service = vrouter_service.subscriber_services[0]
+ onos_fabric_service = fabric_service.subscriber_services[0]
+
+ return onos_fabric_service
+
+ def sync_record(self, model):
+ onos_fabric_service = self.get_onos_fabric_service(model)
+
+ onos = Helpers.get_onos_info(onos_fabric_service.leaf_model)
+ onos_basic_auth = HTTPBasicAuth(onos['user'], onos['pass'])
+
+ data = {
+ "prefix": model.prefix,
+ "nextHop": model.next_hop
+ }
+
+ url = '%s:%s/onos/routeservice/routes' % (onos['url'], onos['port'])
+ request = requests.post(url, json=data, auth=onos_basic_auth)
+
+ if request.status_code != 204:
+ log.error("Request failed", response=request.text)
+ raise Exception("Failed to add static route %s via %s in ONOS" % (model.prefix, model.next_hop))
+ else:
+ try:
+ print request.json()
+ except Exception:
+ print request.text
+
+ def delete_record(self, model):
+ onos_fabric_service = self.get_onos_fabric_service(model)
+
+ onos = Helpers.get_onos_info(onos_fabric_service.leaf_model)
+ onos_basic_auth = HTTPBasicAuth(onos['user'], onos['pass'])
+
+ data = {
+ "prefix": model.prefix,
+ "nextHop": model.next_hop
+ }
+
+ url = '%s:%s/onos/routeservice/routes' % (onos['url'], onos['port'])
+ request = requests.delete(url, json=data, auth=onos_basic_auth)
+
+ if request.status_code != 204:
+ log.error("Request failed", response=request.text)
+ raise Exception("Failed to delete static route %s via %s in ONOS" % (model.prefix, model.next_hop))
+ else:
+ try:
+ print request.json()
+ except Exception:
+ print request.text
diff --git a/xos/synchronizer/steps/sync_vrouterapp.py b/xos/synchronizer/steps/sync_vrouterapp.py
deleted file mode 100644
index 6c83700..0000000
--- a/xos/synchronizer/steps/sync_vrouterapp.py
+++ /dev/null
@@ -1,85 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import os
-import sys
-import requests
-import json
-from synchronizers.new_base.syncstep import SyncStep
-from synchronizers.new_base.modelaccessor import *
-from xos.logger import Logger, logging
-
-from requests.auth import HTTPBasicAuth
-logger = Logger(level=logging.INFO)
-
-
-class SyncVRouterApp(SyncStep):
- provides = [VRouterApp]
-
- observes = VRouterApp
-
- requested_interval = 0
-
- def __init__(self, *args, **kwargs):
- super(SyncVRouterApp, self).__init__(*args, **kwargs)
-
- def get_onos_fabric_addr(self, app):
- vrouter_service = VRouterService.objects.get(id=app.vrouter_service_id)
-
- return "http://%s:%s/onos/v1/network/configuration/" % (vrouter_service.rest_hostname, vrouter_service.rest_port)
-
- def get_onos_fabric_auth(self, app):
- vrouter_service = VRouterService.objects.get(id=app.vrouter_service_id)
-
- return HTTPBasicAuth(vrouter_service.rest_user, vrouter_service.rest_pass)
-
- def sync_record(self, app):
-
- logger.info("Sync'ing Edited vRouterApps: %s" % app.name)
-
- onos_addr = self.get_onos_fabric_addr(app)
-
- data = {}
- data["controlPlaneConnectPoint"] = app.control_plane_connect_point
- data["ospfEnabled"] = app.ospf_enabled
- data["interfaces"] = app.interfaces
-
- url = onos_addr + "apps/" + app.name + "/router/"
-
- print "POST %s for app %s" % (url, app.name)
-
- # XXX fixme - hardcoded auth
- auth = self.get_onos_fabric_auth(app)
- r = requests.post(url, data=json.dumps(data), auth=auth)
- if (r.status_code != 200):
- print r
- raise Exception("Received error from vrouter app update (%d)" % r.status_code)
-
- def delete_record(self, app):
-
- logger.info("Sync'ing Deleted vRouterApps: %s" % app.name)
-
- onos_addr = self.get_onos_fabric_addr()
-
- url = onos_addr + "apps/" + app.name + "/"
-
- print "DELETE %s for app %s" % (url, app.name)
-
- auth = self.get_onos_fabric_auth(app)
- r = requests.delete(url, auth=auth)
- if (r.status_code != 204):
- print r
- raise Exception("Received error from vrouter app deletion (%d)" % r.status_code)
\ No newline at end of file
diff --git a/xos/synchronizer/steps/sync_vrouterdevice.py b/xos/synchronizer/steps/sync_vrouterdevice.py
deleted file mode 100644
index 179ec91..0000000
--- a/xos/synchronizer/steps/sync_vrouterdevice.py
+++ /dev/null
@@ -1,82 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import os
-import sys
-import requests
-import json
-from synchronizers.new_base.syncstep import SyncStep
-from synchronizers.new_base.modelaccessor import *
-from xos.logger import Logger, logging
-
-from requests.auth import HTTPBasicAuth
-logger = Logger(level=logging.INFO)
-
-
-class SyncVRouterDevice(SyncStep):
- provides = [VRouterDevice]
-
- observes = VRouterDevice
-
- requested_interval = 0
-
- def __init__(self, *args, **kwargs):
- super(SyncVRouterDevice, self).__init__(*args, **kwargs)
-
- def get_onos_fabric_addr(self, app):
- vrouter_service = VRouterService.objects.get(id=app.vrouter_service_id)
-
- return "http://%s:%s/onos/v1/network/configuration/" % (vrouter_service.rest_hostname, vrouter_service.rest_port)
-
- def get_onos_fabric_auth(self, app):
- vrouter_service = VRouterService.objects.get(id=app.vrouter_service_id)
-
- return HTTPBasicAuth(vrouter_service.rest_user, vrouter_service.rest_pass)
-
- def sync_record(self, device):
-
- logger.info("Sync'ing Edited vRouterDevice: %s" % device.name)
-
- onos_addr = self.get_onos_fabric_addr(device)
-
- data = {}
- data["driver"] = device.driver
-
- url = onos_addr + "devices/" + device.openflow_id + "/" + device.config_key + "/"
-
- print "POST %s for device %s" % (url, device.name)
-
- auth = self.get_onos_fabric_auth(device)
- r = requests.post(url, data=json.dumps(data), auth=auth)
- if (r.status_code != 200):
- print r
- raise Exception("Received error from vrouter device update (%d)" % r.status_code)
-
- def delete_record(self, device):
-
- logger.info("Sync'ing Deleted vRouterDevice: %s" % device.name)
-
- onos_addr = self.get_onos_fabric_addr()
-
- url = onos_addr + "devices/" + device.openflow_id + "/"
-
- print "DELETE %s for device %s" % (url, device.name)
-
- auth = self.get_onos_fabric_auth(device)
- r = requests.delete(url, auth=auth)
- if (r.status_code != 204):
- print r
- raise Exception("Received error from vrouter device deletion (%d)" % r.status_code)
\ No newline at end of file
diff --git a/xos/synchronizer/steps/sync_vrouterports.py b/xos/synchronizer/steps/sync_vrouterports.py
deleted file mode 100644
index fe8eb1c..0000000
--- a/xos/synchronizer/steps/sync_vrouterports.py
+++ /dev/null
@@ -1,105 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import os
-import sys
-import requests
-import json
-import urllib
-from synchronizers.new_base.syncstep import SyncStep
-from synchronizers.new_base.modelaccessor import *
-from xos.logger import Logger, logging
-
-from requests.auth import HTTPBasicAuth
-logger = Logger(level=logging.INFO)
-
-
-class SyncVRouterPort(SyncStep):
- provides = [VRouterPort]
-
- observes = VRouterPort
-
- requested_interval = 0
-
- def __init__(self, *args, **kwargs):
- super(SyncVRouterPort, self).__init__(*args, **kwargs)
-
- def get_onos_fabric_addr(self, app):
- vrouter_service = VRouterService.objects.get(id=app.vrouter_service_id)
-
- return "http://%s:%s/onos/v1/network/configuration/" % (vrouter_service.rest_hostname, vrouter_service.rest_port)
-
- def get_onos_fabric_auth(self, app):
- vrouter_service = VRouterService.objects.get(id=app.vrouter_service_id)
-
- return HTTPBasicAuth(vrouter_service.rest_user, vrouter_service.rest_pass)
-
- def sync_record(self, port):
-
- logger.info("Sync'ing Edited vRouterPort: %s" % port.name)
-
- # NOTE port is now related to service,
- # probably it makes more sense to relate them to a device (and device is related to service)
- onos_addr = self.get_onos_fabric_addr(port)
-
- # NOTE
- # from a port read all interfaces
- # from interfaces read all ips
-
- ifaces = []
- for interface in port.interfaces.all():
- iface = {
- 'name': interface.name,
- 'mac': interface.mac,
- 'vlan': interface.vlan,
- 'ips': []
- }
-
- for ip in interface.ips.all():
- iface["ips"].append(ip.ip)
-
- ifaces.append(iface)
-
- data = {}
- data[port.openflow_id] = {
- 'interfaces': ifaces
- }
-
- url = onos_addr + "ports/"
-
- print "POST %s for port %s" % (url, port.name)
-
- auth = self.get_onos_fabric_auth(port)
- r = requests.post(url, data=json.dumps(data), auth=auth)
- if (r.status_code != 200):
- print r
- raise Exception("Received error from vrouter port update (%d)" % r.status_code)
-
- def delete_record(self, port):
-
- logger.info("Sync'ing Deleted vRouterPort: %s" % port.name)
-
- onos_addr = self.get_onos_fabric_addr()
-
- url = onos_addr + "ports/" + urllib.quote(port.openflow_id, safe='') + "/"
-
- print "DELETE %s for port %s" % (url, port.name)
-
- auth = self.get_onos_fabric_auth(port)
- r = requests.delete(url, auth=auth)
- if (r.status_code != 204):
- print r
- raise Exception("Received error from vrouter port deletion (%d)" % r.status_code)
\ No newline at end of file