blob: 978f57d2dc8428f66219eb61565c263130c07f6a [file] [log] [blame]
khenaidoob9203542018-09-17 22:56:37 -04001#
2# Copyright 2017 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17"""
khenaidoo6fdf0ba2018-11-02 14:38:33 -040018This facade handles kafka-formatted messages from the Core, extracts the kafka
19formatting and forwards the request to the concrete handler.
khenaidoob9203542018-09-17 22:56:37 -040020"""
khenaidoob9203542018-09-17 22:56:37 -040021
khenaidoo6fdf0ba2018-11-02 14:38:33 -040022from twisted.internet.defer import inlineCallbacks
khenaidoob9203542018-09-17 22:56:37 -040023from zope.interface import implementer
khenaidoo43c82122018-11-22 18:38:28 -050024from twisted.internet import reactor
khenaidoob9203542018-09-17 22:56:37 -040025
khenaidoofdbad6e2018-11-06 22:26:38 -050026from python.adapters.interface import IAdapterInterface
27from python.protos.core_adapter_pb2 import IntType, InterAdapterMessage, StrType, Error, ErrorCode
28from python.protos.device_pb2 import Device
29from python.protos.openflow_13_pb2 import FlowChanges, FlowGroups, Flows, \
30 FlowGroupChanges, ofp_packet_out
khenaidoo43c82122018-11-22 18:38:28 -050031from python.adapters.kafka.kafka_inter_container_library import IKafkaMessagingProxy, \
32 get_messaging_proxy
khenaidoob9203542018-09-17 22:56:37 -040033
34
35class MacAddressError(BaseException):
36 def __init__(self, error):
37 self.error = error
38
39
40class IDError(BaseException):
41 def __init__(self, error):
42 self.error = error
43
44
45@implementer(IAdapterInterface)
46class AdapterRequestFacade(object):
47 """
48 Gate-keeper between CORE and device adapters.
49
50 On one side it interacts with Core's internal model and update/dispatch
51 mechanisms.
52
53 On the other side, it interacts with the adapters standard interface as
54 defined in
55 """
56
57 def __init__(self, adapter):
58 self.adapter = adapter
59
60 @inlineCallbacks
61 def start(self):
62 self.log.debug('starting')
63
64 @inlineCallbacks
65 def stop(self):
66 self.log.debug('stopping')
67
khenaidoo43c82122018-11-22 18:38:28 -050068
69 def createKafkaDeviceTopic(self, deviceId):
70 kafka_proxy = get_messaging_proxy()
71 device_topic = kafka_proxy.get_default_topic() + "_" + deviceId
72 kafka_proxy.subscribe(topic=device_topic, target_cls=self)
73
khenaidoob9203542018-09-17 22:56:37 -040074 def adopt_device(self, device):
75 d = Device()
76 if device:
77 device.Unpack(d)
khenaidoo43c82122018-11-22 18:38:28 -050078
79 result = self.adapter.adopt_device(d)
80 # return True, self.adapter.adopt_device(d)
81
82 # Before we return, create a device specific topic to handle all
83 # subsequent requests from the Core. This adapter instance will
84 # handle all requests for that device
85 reactor.callLater(0, self.createKafkaDeviceTopic, d.id)
86
87 return True, result
khenaidoob9203542018-09-17 22:56:37 -040088 else:
khenaidoofdbad6e2018-11-06 22:26:38 -050089 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
90 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -040091
92 def get_ofp_device_info(self, device):
93 d = Device()
94 if device:
95 device.Unpack(d)
khenaidoo92e62c52018-10-03 14:02:54 -040096 return True, self.adapter.get_ofp_device_info(d)
khenaidoob9203542018-09-17 22:56:37 -040097 else:
khenaidoofdbad6e2018-11-06 22:26:38 -050098 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
99 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400100
101 def get_ofp_port_info(self, device, port_no):
102 d = Device()
103 if device:
104 device.Unpack(d)
105 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500106 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
107 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400108 p = IntType()
khenaidoofdbad6e2018-11-06 22:26:38 -0500109 if port_no:
110 port_no.Unpack(p)
111 else:
112 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
113 reason="port-no-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400114
khenaidoo92e62c52018-10-03 14:02:54 -0400115 return True, self.adapter.get_ofp_port_info(d, p.val)
khenaidoob9203542018-09-17 22:56:37 -0400116
khenaidoob9203542018-09-17 22:56:37 -0400117 def reconcile_device(self, device):
118 return self.adapter.reconcile_device(device)
119
120 def abandon_device(self, device):
121 return self.adapter.abandon_device(device)
122
123 def disable_device(self, device):
khenaidoo92e62c52018-10-03 14:02:54 -0400124 d = Device()
125 if device:
126 device.Unpack(d)
127 return True, self.adapter.disable_device(d)
128 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500129 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
130 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400131
132 def reenable_device(self, device):
khenaidoo92e62c52018-10-03 14:02:54 -0400133 d = Device()
134 if device:
135 device.Unpack(d)
136 return True, self.adapter.reenable_device(d)
137 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500138 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
139 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400140
141 def reboot_device(self, device):
142 d = Device()
143 if device:
144 device.Unpack(d)
145 return (True, self.adapter.reboot_device(d))
146 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500147 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
148 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400149
150 def download_image(self, device, request):
151 return self.adapter.download_image(device, request)
152
153 def get_image_download_status(self, device, request):
154 return self.adapter.get_image_download_status(device, request)
155
156 def cancel_image_download(self, device, request):
157 return self.adapter.cancel_image_download(device, request)
158
159 def activate_image_update(self, device, request):
160 return self.adapter.activate_image_update(device, request)
161
162 def revert_image_update(self, device, request):
163 return self.adapter.revert_image_update(device, request)
164
165 def self_test(self, device):
166 return self.adapter.self_test_device(device)
167
168 def delete_device(self, device):
khenaidoo4d4802d2018-10-04 21:59:49 -0400169 d = Device()
170 if device:
171 device.Unpack(d)
khenaidoo43c82122018-11-22 18:38:28 -0500172 result = self.adapter.delete_device(d)
173 # return (True, self.adapter.delete_device(d))
174
175 # Before we return, delete the device specific topic as we will no
176 # longer receive requests from the Core for that device
177 kafka_proxy = get_messaging_proxy()
178 device_topic = kafka_proxy.get_default_topic() + "/" + d.id
179 kafka_proxy.unsubscribe(topic=device_topic)
180
181 return (True, result)
khenaidoo4d4802d2018-10-04 21:59:49 -0400182 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500183 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
184 reason="device-invalid")
khenaidoob9203542018-09-17 22:56:37 -0400185
186 def get_device_details(self, device):
187 return self.adapter.get_device_details(device)
188
189 def update_flows_bulk(self, device, flows, groups):
khenaidoo19d7b632018-10-30 10:49:50 -0400190 d = Device()
191 if device:
192 device.Unpack(d)
193 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500194 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
195 reason="device-invalid")
khenaidoo19d7b632018-10-30 10:49:50 -0400196 f = Flows()
197 if flows:
198 flows.Unpack(f)
199
200 g = FlowGroups()
201 if groups:
202 groups.Unpack(g)
203
204 return (True, self.adapter.update_flows_bulk(d, f, g))
khenaidoob9203542018-09-17 22:56:37 -0400205
206 def update_flows_incrementally(self, device, flow_changes, group_changes):
khenaidoo19d7b632018-10-30 10:49:50 -0400207 d = Device()
208 if device:
209 device.Unpack(d)
210 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500211 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
212 reason="device-invalid")
khenaidoo19d7b632018-10-30 10:49:50 -0400213 f = FlowChanges()
214 if flow_changes:
215 flow_changes.Unpack(f)
216
217 g = FlowGroupChanges()
218 if group_changes:
219 group_changes.Unpack(g)
220
221 return (True, self.adapter.update_flows_incrementally(d, f, g))
khenaidoob9203542018-09-17 22:56:37 -0400222
223 def suppress_alarm(self, filter):
224 return self.adapter.suppress_alarm(filter)
225
226 def unsuppress_alarm(self, filter):
227 return self.adapter.unsuppress_alarm(filter)
228
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400229 def process_inter_adapter_message(self, msg):
230 m = InterAdapterMessage()
231 if msg:
232 msg.Unpack(m)
233 else:
khenaidoofdbad6e2018-11-06 22:26:38 -0500234 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
235 reason="msg-invalid")
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400236
237 return (True, self.adapter.process_inter_adapter_message(m))
khenaidoofdbad6e2018-11-06 22:26:38 -0500238
239
240 def receive_packet_out(self, deviceId, outPort, packet):
241 d_id = StrType()
242 if deviceId:
243 deviceId.Unpack(d_id)
244 else:
245 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
246 reason="deviceid-invalid")
247
248 op = IntType
249 if outPort:
250 outPort.Unpack(op)
251 else:
252 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
253 reason="outport-invalid")
254
255 p = ofp_packet_out()
256 if packet:
257 packet.Unpack(p)
258 else:
259 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
260 reason="packet-invalid")
261
262 return (True, self.adapter.receive_packet_out(d_id, op, p))
263