blob: 21b495b87535562a7e159a254556417d25b90251 [file] [log] [blame]
daniel park128c52c2017-09-04 13:15:51 +09001/*
2 * Copyright 2017-present Open Networking Laboratory
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/*
18 OpenStack Networking UI Service
19
20 Provides a mechanism to highlight hosts, devices and links according to
21 a virtual network. Also provides trace functionality to prove that
22 flow rules for the specific vm are installed appropriately.
23 */
24
25(function () {
26 'use strict';
27
28 // injected refs
29 var $log, fs, flash, wss, ds;
30
Daniel Park4e037f52018-09-20 18:04:18 +090031 var traceSrc = null;
32 var traceDst = null;
33 var srcDeviceId = null;
34 var dstDeviceId = null;
35 var uplink = null;
36
daniel park128c52c2017-09-04 13:15:51 +090037 // constants
38 var displayStart = 'openstackNetworkingUiStart',
39 displayUpdate = 'openstackNetworkingUiUpdate',
40 displayStop = 'openstackNetworkingUiStop',
boyoung27b444122018-09-01 17:28:13 +090041 flowStatsAddRequest = 'flowStatsAddRequest',
42 flowStatsRemoveRequest = 'flowStatsRemoveRequest',
daniel park128c52c2017-09-04 13:15:51 +090043 flowTraceRequest = 'flowTraceRequest';
44
45 // internal state
46 var currentMode = null;
47
48 // === ---------------------------
49 // === Helper functions
50
51 function sendDisplayStart(mode) {
52 wss.sendEvent(displayStart, {
53 mode: mode
54 });
55 }
56
57 function sendDisplayUpdate(what) {
58 wss.sendEvent(displayUpdate, {
59 id: what ? what.id : ''
60 });
61 }
62
63 function sendDisplayStop() {
64 wss.sendEvent(displayStop);
65 }
66
boyoung27b444122018-09-01 17:28:13 +090067 function sendFlowStatsAddRequest(src, dst) {
68 wss.sendEvent(flowStatsAddRequest, {
69 srcIp: src,
70 dstIp: dst,
71 });
72 $log.info('FlowStatsAdd request message is sent.');
73 flash.flash('sendFlowStatsAddRequest called');
74 }
75
76 function sendFlowStatsRemoveRequest(src, dst) {
77 wss.sendEvent(flowStatsRemoveRequest, {
78 srcIp: src,
79 dstIp: dst,
80 });
81 $log.info('FlowStatsRemove request message is sent.');
82 flash.flash('sendFlowStatsRemoveRequest called');
83 }
84
Daniel Park4e037f52018-09-20 18:04:18 +090085 function sendFlowTraceRequest(src, dst, srcDeviceId, dstDeviceId, uplink) {
daniel park128c52c2017-09-04 13:15:51 +090086 wss.sendEvent(flowTraceRequest, {
87 srcIp: src,
Daniel Park577b69c2018-07-16 17:29:34 +090088 dstIp: dst,
89 srcDeviceId: srcDeviceId,
90 dstDeviceId: dstDeviceId,
Daniel Park4e037f52018-09-20 18:04:18 +090091 uplink: uplink,
daniel park128c52c2017-09-04 13:15:51 +090092 });
93 flash.flash('sendFlowTraceRequest called');
94 }
95
96 // === ---------------------------
97 // === Main API functions
98
99 function startDisplay(mode) {
100 if (currentMode === mode) {
101 $log.debug('(in mode', mode, 'already)');
102 } else {
103 currentMode = mode;
104 sendDisplayStart(mode);
105
106 flash.flash('Starting Openstack Networking UI mode');
107 }
108 }
109
110 function updateDisplay(m) {
111 if (currentMode) {
112 sendDisplayUpdate(m);
113 }
114 }
115
116 function stopDisplay() {
117 if (currentMode) {
118 currentMode = null;
119 sendDisplayStop();
120 flash.flash('Canceling Openstack Networking UI Overlay mode');
121 return true;
122 }
123 return false;
124 }
125
daniel park128c52c2017-09-04 13:15:51 +0900126 function dOk() {
127 ds.closeDialog();
128 }
boyoung27b444122018-09-01 17:28:13 +0900129
130 function openFlowStatsAddResultDialog(data) {
131 $log.info('Addition Result message: ', data);
132 var flowStatsAddResultDialogId = 'flowStatsAddResultDialogId',
133 flowStatsAddResultDialogOpt = {
134 width: 650,
135 edge: 'left',
136 margin: 20,
137 hideMargin: -20
138 }
139 var statsSuccess = data.statsSuccess == true ? "SUCCESS" : "FALSE";
140 ds.openDialog(flowStatsAddResultDialogId, flowStatsAddResultDialogOpt)
141 .setTitle('Flow Stats Addition Result: ' + statsSuccess)
142 .addContent(createStatsAddResultInfoDiv(data))
143 .addOk(dOk, 'Close')
144 .bindKeys();
145 }
146
147 function createStatsAddResultInfoDiv(data) {
148 var texts = ds.createDiv('flowStatsAddResult');
149 texts.append('p').text('Result of addition: ' + data.statsSuccess);
150 return texts;
151 }
152
153 function openFlowStatsRemoveResultDialog(data) {
154 $log.info('Removal Result message: ', data);
155 var flowStatsRemoveResultDialogId = 'flowStatsRemoveResultDialogId',
156 flowStatsRemoveResultDialogOpt = {
157 width: 650,
158 edge: 'left',
159 margin: 20,
160 hideMargin: -20
161 }
162 var statsSuccess = data.statsSuccess == true ? "SUCCESS" : "FALSE";
163 ds.openDialog(flowStatsRemoveResultDialogId, flowStatsRemoveResultDialogOpt)
164 .setTitle('Flow Stats Removal Result: ' + statsSuccess)
165 .addContent(createStatsRemoveResultInfoDiv(data))
166 .addOk(dOk, 'Close')
167 .bindKeys();
168 }
169
170 function createStatsRemoveResultInfoDiv(data) {
171 var texts = ds.createDiv('flowStatsRemoveResult');
172 texts.append('p').text('Result of removal: ' + data.statsSuccess);
173 return texts;
174 }
175
daniel park128c52c2017-09-04 13:15:51 +0900176 function openFlowTraceResultDialog(data) {
177 var flowTraceResultDialogId = 'flowTraceResultDialogId',
178 flowTraceResultDialogOpt = {
179 width: 650,
180 edge: 'left',
181 margin: 20,
182 hideMargin: -20
183 }
Daniel Park577b69c2018-07-16 17:29:34 +0900184 var traceSuccess = data.traceSuccess == true ? "SUCCESS" : "FALSE";
Daniel Park4e037f52018-09-20 18:04:18 +0900185 traceSrc = data.srcIp;
186 traceDst = data.dstIp;
187 srcDeviceId = data.srcDeviceId;
188 dstDeviceId = data.dstDeviceId;
189 uplink = data.uplink;
190
191 if (data.uplink == true) {
192 ds.openDialog(flowTraceResultDialogId, flowTraceResultDialogOpt)
193 .setTitle('Flow Trace Result: ' + traceSuccess)
194 .addContent(createTraceResultInfoDiv(data))
195 .addOk(downlinkTraceRequestBtn, 'Downlink Trace')
196 .bindKeys();
197 } else {
198 ds.openDialog(flowTraceResultDialogId, flowTraceResultDialogOpt)
199 .setTitle('Flow Trace Result: ' + traceSuccess)
200 .addContent(createTraceResultInfoDiv(data))
201 .addOk(dOk, 'Close')
202 .bindKeys();
203 }
204
205 }
206
207 function downlinkTraceRequestBtn() {
208 sendFlowTraceRequest(traceSrc, traceDst, srcDeviceId, dstDeviceId, false);
209 ds.closeDialog();
210 flash.flash('Send Downlink Flow Trace Request')
daniel park128c52c2017-09-04 13:15:51 +0900211 }
212
213 function createTraceResultInfoDiv(data) {
214 var texts = ds.createDiv('flowTraceResult');
215
216 texts.append('div').attr("class", "table-header");
217 texts.append('div').attr("class", "table-body");
218
219 texts.select('.table-header').append('table').append('tbody').append('tr');
220 texts.select('.table-body').append('table').append('tbody');
221
222
223 var theaderSelection = texts.select('.table-header')
224 .select('table').select('tbody').select('tr');
225
226 theaderSelection.append('td').text('Node');
227 theaderSelection.append('td').text('Table Id');
228 theaderSelection.append('td').text('Priority');
229 theaderSelection.append('td').text('Selector');
230 theaderSelection.append('td').text('Action');
231
232 var tbodySelection = texts.select('.table-body').select('table').select('tbody');
233 var rowNum = 1;
234
Daniel Park577b69c2018-07-16 17:29:34 +0900235 data.traceResult.forEach(function(result) {
236 result.flowRules.forEach(function(flowRule) {
daniel park128c52c2017-09-04 13:15:51 +0900237 tbodySelection.append('tr');
238 var tbodyTrSelection = tbodySelection.select('tr:nth-child(' + rowNum + ')');
Daniel Park577b69c2018-07-16 17:29:34 +0900239 tbodyTrSelection.append('td').text(result.traceNodeName);
daniel park128c52c2017-09-04 13:15:51 +0900240 tbodyTrSelection.append('td').text(flowRule.table);
241 tbodyTrSelection.append('td').text(flowRule.priority);
Daniel Park577b69c2018-07-16 17:29:34 +0900242 tbodyTrSelection.append('td').text(flowRule.selector);
243 tbodyTrSelection.append('td').text(flowRule.actions);
daniel park128c52c2017-09-04 13:15:51 +0900244 if (jsonToSring(flowRule.actions).includes("drop")) {
245 tbodyTrSelection.attr("class", "drop");
246 }
247 rowNum++;
248 });
249
250 });
251
252 return texts;
253 }
254
255 function jsonToSring(jsonData) {
256 var result = [];
257 for (var key in jsonData) {
258 result.push(key + ':' + jsonData[key]);
259 }
260
261 return result.join('/');
262
263 }
264
boyoung27b444122018-09-01 17:28:13 +0900265 function flowStatsAddResult(data) {
266 flash.flash('flowStatsAddResult called');
267 $log.debug(data);
268
269 openFlowStatsAddResultDialog(data)
270 }
271
272 function flowStatsRemoveResult(data) {
273 flash.flash('flowStatsRemoveResult called');
274 $log.debug(data);
275
276 openFlowStatsRemoveResultDialog(data)
277 }
278
279
daniel park128c52c2017-09-04 13:15:51 +0900280 function flowTraceResult(data) {
281 flash.flash('flowTraceResult called');
282 $log.debug(data);
283
284 openFlowTraceResultDialog(data)
285 }
286
287 // === ---------------------------
288 // === Module Factory Definition
289
290 angular.module('ovSonaTopov', [])
291 .factory('SonaTopovService',
292 ['$log', 'FnService', 'FlashService', 'WebSocketService', 'DialogService',
293
294 function (_$log_, _fs_, _flash_, _wss_, _ds_) {
295 $log = _$log_;
296 fs = _fs_;
297 flash = _flash_;
298 wss = _wss_;
299 ds = _ds_;
300
301 return {
302 startDisplay: startDisplay,
303 updateDisplay: updateDisplay,
304 stopDisplay: stopDisplay,
boyoung27b444122018-09-01 17:28:13 +0900305 flowStatsAddResult: flowStatsAddResult,
306 flowStatsRemoveResult: flowStatsRemoveResult,
307 sendFlowStatsAddRequest: sendFlowStatsAddRequest,
308 sendFlowStatsRemoveRequest: sendFlowStatsRemoveRequest,
daniel park128c52c2017-09-04 13:15:51 +0900309 flowTraceResult: flowTraceResult,
310 sendFlowTraceRequest: sendFlowTraceRequest,
311 };
312 }]);
313}());