blob: c704e6d1f46b1d84b431dc0a38157f3bd5decd63 [file] [log] [blame]
# 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, sys
import json
from xossynchronizer.steps.syncstep import SyncStep, DeferredException
from xossynchronizer.modelaccessor import model_accessor, FabricCrossconnectServiceInstance, ServiceInstance, BNGPortMapping
import requests
from requests import ConnectionError
from requests.auth import HTTPBasicAuth
from requests.models import InvalidURL
from xosconfig import Config
from multistructlog import create_logger
from helpers import Helpers
log = create_logger(Config().get('logging'))
class SyncBNGPortMapping(SyncStep):
provides = [BNGPortMapping]
observes = BNGPortMapping
def remove_crossconnect(self, fcsis):
for fcsi in fcsis:
onos = Helpers.get_fabric_onos_info(self.model_accessor, fcsi.owner)
url = onos['url'] + '/onos/segmentrouting/xconnect'
data = {"deviceId": fcsi.switch_datapath_id,
"vlanId": fcsi.s_tag}
log.info("Sending request to ONOS", url=url)
r = requests.delete(url, json=data, auth=HTTPBasicAuth(onos['user'], onos['pass']))
if r.status_code != 204:
raise Exception("Failed to remove fabric crossconnect in ONOS: %s" % r.text)
fcsi.save(always_update_timestamp = True)
def find_crossconnect(self, bng_s_tag):
if(bng_s_tag.isnumeric()):
xconnect_si = self.model_accessor.FabricCrossconnectServiceInstance.objects.filter(s_tag=int(bng_s_tag))
if xconnect_si:
log.info("Crossconnects belonging having s-tag equal to s-tags: %s" % xconnect_si)
return xconnect_si
else:
[fcsis_range, fcsis_any] = [[], []]
for fcsi in self.model_accessor.FabricCrossconnectServiceInstance.objects.all():
if Helpers.range_matches(fcsi.s_tag, bng_s_tag):
fcsis_range.append(fcsi)
else:
fcsis_any.append(fcsi)
if fcsis_range:
log.info("Crossconnects belonging to bng range s-tags: %s" % fcsis_range)
return fcsis_range
else:
log.info("Crossconnects belonging to bng any s-tags: %s" % fcsis_any)
return fcsis_any
def check_switch_port_change(self, model):
fcsis = self.find_crossconnect(model.s_tag)
isChanged = False
remove_xconnect = []
if fcsis:
for fcsi in fcsis:
onos = Helpers.get_fabric_onos_info(self.model_accessor, fcsi.owner)
log.info("ONOS belonging to fabric crossconnect instance: %s" % onos)
url = onos['url'] + '/onos/segmentrouting/xconnect'
log.info("Sending request to ONOS", url=url)
r = requests.get(url, auth=HTTPBasicAuth(onos['user'], onos['pass']))
if r.status_code != 200:
log.error(r.text)
raise Exception("Failed to get onos devices")
else:
try:
log.info("Get devices response", json=r.json())
except Exception:
log.info("Get devices exception response", text=r.text)
xconnects = r.json()["xconnects"]
for xconn in xconnects:
val = xconn['deviceId']
if(str(fcsi.switch_datapath_id) == str(val)):
if model.switch_port not in xconn['endpoints']:
remove_xconnect.append(fcsi)
self.remove_crossconnect(remove_xconnect)
isChanged = True
else:
log.info("No Fabric-xconnect-si found & saving bng instance.")
return isChanged
def sync_record(self, model):
log.info("Sync started for BNGPortMapping instance: %s" % model.id)
log.info('Syncing BNGPortMapping instance', object=str(model), **model.tologdict())
if model.old_s_tag:
if (model.old_s_tag != model.s_tag):
fcsis = self.find_crossconnect(model.old_s_tag)
if fcsis:
log.info("Xconnect-instance linked to bng : %s" % fcsis)
self.remove_crossconnect(fcsis)
else:
log.info("No crossconnect is found for current bng instance")
else:
self.check_switch_port_change(model)
else:
if self.check_switch_port_change(model):
log.info("Changed bng switch port is repushed to ONOS")
log.info("Completing Synchronization for BNGPortMapping instance: %s" % model.id)
def delete_record(self,model):
log.info('Deleting BNGPortMapping instance', object=str(model), **model.tologdict())
fcsis = self.find_crossconnect(model.s_tag)
if fcsis:
log.info("Xconnect-instance linked to bng : %s" % fcsis)
self.remove_crossconnect(fcsis)
log.info("Completing deletion of bng instance")