blob: 8f03075e6f8c2ddf639b26122cd5ed63873313fb [file] [log] [blame]
Scott Bakera6c687c2018-07-16 15:08:49 -07001# 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
15from synchronizers.new_base.syncstep import SyncStep, DeferredException
16from synchronizers.new_base.modelaccessor import model_accessor, FabricCrossconnectServiceInstance, ServiceInstance
17
18from xosconfig import Config
19from multistructlog import create_logger
20import urllib
21import requests
22from requests.auth import HTTPBasicAuth
23
24
25class SyncFabricCrossconnectServiceInstance(SyncStep):
26 provides = [FabricCrossconnectServiceInstance]
27 log = create_logger(Config().get('logging'))
28
29 observes = FabricCrossconnectServiceInstance
30
31 @staticmethod
32 def format_url(url):
33 if 'http' in url:
34 return url
35 else:
36 return 'http://%s' % url
37
38 @staticmethod
39 def get_fabric_onos_info(si):
40
41 # get the fabric-crossconnect service
42 fabric_crossconnect = si.owner
43
44 # get the onos_fabric service
45 fabric_onos = [s.leaf_model for s in fabric_crossconnect.provider_services if "onos" in s.name.lower()]
46
47 if len(fabric_onos) == 0:
48 raise Exception('Cannot find ONOS service in provider_services of Fabric-Crossconnect')
49
50 fabric_onos = fabric_onos[0]
51
52 return {
53 'url': SyncFabricCrossconnectServiceInstance.format_url("%s:%s" % (fabric_onos.rest_hostname, fabric_onos.rest_port)),
54 'user': fabric_onos.rest_username,
55 'pass': fabric_onos.rest_password
56 }
57
58 def get_bng_port(self, o):
59 # TODO(smbaker): Get BNG port from somewhere
60 return 2
61
62 def sync_record(self, o):
63 self.log.info("Sync'ing Fabric Crossconnect Service Instance", service_instance=o)
64
65 onos = self.get_fabric_onos_info(o)
66
67 si = ServiceInstance.objects.get(id=o.id)
68
69 s_tag = si.get_westbound_service_instance_properties("s_tag")
70 west_dpid = si.get_westbound_service_instance_properties("switch_datapath_id")
71 west_port = si.get_westbound_service_instance_properties("switch_port")
72 east_port = self.get_bng_port(o)
73
74 data = { "deviceId": west_dpid,
75 "vlanId": s_tag,
76 "ports": [ west_port, east_port ] }
77
78 url = onos['url'] + '/onos/segmentsrouting/xconnect'
79
80 self.log.info("Sending request to ONOS", url=url, body=data)
81
82 r = requests.post(url, json=data, auth=HTTPBasicAuth(onos['user'], onos['pass']))
83
84 if r.status_code != 200:
85 raise Exception("Failed to create fabric crossconnect in ONOS: %s" % r.text)
86
87 self.log.info("ONOS response", res=r.text)
88
89 def delete_record(self, o):
90 self.log.info("Deleting Fabric Crossconnect Service Instance", service_instance=o)
91
92 # TODO(smbaker): make sure it's not in use by some other subscriber
93
94 if o.enacted:
95 onos = self.get_fabric_onos_info(o)
96
97 si = ServiceInstance.objects.get(id=o.id)
98
99 # TODO(smbaker): unable to get westbound service_instance while deleting?
100
101 s_tag = si.get_westbound_service_instance_properties("s_tag")
102 west_dpid = si.get_westbound_service_instance_properties("switch_datapath_id")
103
104 data = { "deviceId": west_dpid,
105 "vlanID": s_tag }
106
107 url = onos['url'] + '/onos/segmentrouting/xconnect'
108
109 r = requests.delete(url, json=data, auth=HTTPBasicAuth(onos['user'], onos['pass']))
110
111 if r.status_code != 204:
112 raise Exception("Failed to remove fabric crossconnect in ONOS: %s" % r.text)
113
114 self.log.info("ONOS response", res=r.text)