blob: c704e6d1f46b1d84b431dc0a38157f3bd5decd63 [file] [log] [blame]
Himanshu Bhandari32738e82020-06-10 21:08:49 +05301# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import os, sys
16import json
17from xossynchronizer.steps.syncstep import SyncStep, DeferredException
18from xossynchronizer.modelaccessor import model_accessor, FabricCrossconnectServiceInstance, ServiceInstance, BNGPortMapping
19
20import requests
21from requests import ConnectionError
22from requests.auth import HTTPBasicAuth
23from requests.models import InvalidURL
24
25from xosconfig import Config
26from multistructlog import create_logger
27
28from helpers import Helpers
29log = create_logger(Config().get('logging'))
30
31
32class SyncBNGPortMapping(SyncStep):
33 provides = [BNGPortMapping]
34 observes = BNGPortMapping
35
36 def remove_crossconnect(self, fcsis):
37 for fcsi in fcsis:
38 onos = Helpers.get_fabric_onos_info(self.model_accessor, fcsi.owner)
39
40 url = onos['url'] + '/onos/segmentrouting/xconnect'
41 data = {"deviceId": fcsi.switch_datapath_id,
42 "vlanId": fcsi.s_tag}
43 log.info("Sending request to ONOS", url=url)
44 r = requests.delete(url, json=data, auth=HTTPBasicAuth(onos['user'], onos['pass']))
45 if r.status_code != 204:
46 raise Exception("Failed to remove fabric crossconnect in ONOS: %s" % r.text)
47 fcsi.save(always_update_timestamp = True)
48
49 def find_crossconnect(self, bng_s_tag):
50 if(bng_s_tag.isnumeric()):
51 xconnect_si = self.model_accessor.FabricCrossconnectServiceInstance.objects.filter(s_tag=int(bng_s_tag))
52 if xconnect_si:
53 log.info("Crossconnects belonging having s-tag equal to s-tags: %s" % xconnect_si)
54 return xconnect_si
55 else:
56 [fcsis_range, fcsis_any] = [[], []]
57 for fcsi in self.model_accessor.FabricCrossconnectServiceInstance.objects.all():
58 if Helpers.range_matches(fcsi.s_tag, bng_s_tag):
59 fcsis_range.append(fcsi)
60 else:
61 fcsis_any.append(fcsi)
62 if fcsis_range:
63 log.info("Crossconnects belonging to bng range s-tags: %s" % fcsis_range)
64 return fcsis_range
65 else:
66 log.info("Crossconnects belonging to bng any s-tags: %s" % fcsis_any)
67 return fcsis_any
68
69 def check_switch_port_change(self, model):
70 fcsis = self.find_crossconnect(model.s_tag)
71 isChanged = False
72 remove_xconnect = []
73 if fcsis:
74 for fcsi in fcsis:
75 onos = Helpers.get_fabric_onos_info(self.model_accessor, fcsi.owner)
76 log.info("ONOS belonging to fabric crossconnect instance: %s" % onos)
77
78 url = onos['url'] + '/onos/segmentrouting/xconnect'
79 log.info("Sending request to ONOS", url=url)
80 r = requests.get(url, auth=HTTPBasicAuth(onos['user'], onos['pass']))
81 if r.status_code != 200:
82 log.error(r.text)
83 raise Exception("Failed to get onos devices")
84 else:
85 try:
86 log.info("Get devices response", json=r.json())
87 except Exception:
88 log.info("Get devices exception response", text=r.text)
89 xconnects = r.json()["xconnects"]
90 for xconn in xconnects:
91 val = xconn['deviceId']
92 if(str(fcsi.switch_datapath_id) == str(val)):
93 if model.switch_port not in xconn['endpoints']:
94 remove_xconnect.append(fcsi)
95 self.remove_crossconnect(remove_xconnect)
96 isChanged = True
97 else:
98 log.info("No Fabric-xconnect-si found & saving bng instance.")
99 return isChanged
100
101 def sync_record(self, model):
102 log.info("Sync started for BNGPortMapping instance: %s" % model.id)
103 log.info('Syncing BNGPortMapping instance', object=str(model), **model.tologdict())
104 if model.old_s_tag:
105 if (model.old_s_tag != model.s_tag):
106 fcsis = self.find_crossconnect(model.old_s_tag)
107 if fcsis:
108 log.info("Xconnect-instance linked to bng : %s" % fcsis)
109 self.remove_crossconnect(fcsis)
110 else:
111 log.info("No crossconnect is found for current bng instance")
112 else:
113 self.check_switch_port_change(model)
114 else:
115 if self.check_switch_port_change(model):
116 log.info("Changed bng switch port is repushed to ONOS")
117 log.info("Completing Synchronization for BNGPortMapping instance: %s" % model.id)
118
119 def delete_record(self,model):
120 log.info('Deleting BNGPortMapping instance', object=str(model), **model.tologdict())
121 fcsis = self.find_crossconnect(model.s_tag)
122 if fcsis:
123 log.info("Xconnect-instance linked to bng : %s" % fcsis)
124 self.remove_crossconnect(fcsis)
125 log.info("Completing deletion of bng instance")