blob: b2d799964ba27a88073adbffeaf68952fd9e6a5d [file] [log] [blame]
daniel park128c52c2017-09-04 13:15:51 +09001/*
2 * Copyright 2017-present Open Networking Foundation
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/* OpenStack Networking UI Overlay description */
18(function () {
19 'use strict';
20
21 // injected refs
22 var $log, tov, sts, flash, ds, wss;
23 var traceSrc = null;
24 var traceDst = null;
Daniel Park577b69c2018-07-16 17:29:34 +090025 var srcDeviceId = null;
26 var dstDeviceId = null;
boyoung27b444122018-09-01 17:28:13 +090027 var flowStatsSrcIp = null;
28 var flowStatsDstIp = null;
daniel park128c52c2017-09-04 13:15:51 +090029
30 var traceInfoDialogId = 'traceInfoDialogId',
Daniel Park4e037f52018-09-20 18:04:18 +090031 traceInfoDialogOpt = {
boyoung27b444122018-09-01 17:28:13 +090032 width: 350,
daniel park128c52c2017-09-04 13:15:51 +090033 edge: 'left',
34 margin: 20,
35 hideMargin: -20
36 }
37
38 var overlay = {
39 // NOTE: this must match the ID defined in AppUiTopovOverlay
40 overlayId: 'sona-overlay',
41 glyphId: '*star4',
42 tooltip: 'OpenstackNetworking UI',
43
44 glyphs: {
45 star4: {
46 vb: '0 0 8 8',
47 d: 'M1,4l2,-1l1,-2l1,2l2,1l-2,1l-1,2l-1,-2z'
48 },
49 banner: {
50 vb: '0 0 6 6',
51 d: 'M1,1v4l2,-2l2,2v-4z'
52 }
53 },
54
55 activate: function () {
56 $log.debug("OpenstackNetworking UI ACTIVATED");
57 },
58 deactivate: function () {
59 sts.stopDisplay();
60 $log.debug("OpenstackNetworking UI DEACTIVATED");
61 },
62
63 // detail panel button definitions
64 buttons: {
65 flowtrace: {
66 gid: 'checkMark',
67 tt: 'Flow Trace',
68 cb: function (data) {
69
70 if (traceSrc == null && data.navPath == 'host') {
Daniel Park577b69c2018-07-16 17:29:34 +090071 traceSrc = data.propValues.ip;
72 srcDeviceId = data.propValues.DeviceId
daniel park128c52c2017-09-04 13:15:51 +090073
74 flash.flash('Src ' + traceSrc + ' selected. Please select the dst');
75 } else if (traceDst == null && data.title != traceSrc && data.navPath == 'host') {
Daniel Park577b69c2018-07-16 17:29:34 +090076 traceDst = data.propValues.ip;
77 dstDeviceId = data.propValues.DeviceId;
daniel park128c52c2017-09-04 13:15:51 +090078 openTraceInfoDialog();
79 flash.flash('Dst ' + traceDst + ' selected. Press Request button');
80 }
81
82 $log.debug('Perform flow trace test between VMs:', data);
83 }
84 },
85
86 reset: {
87 gid: 'xMark',
88 tt: 'Reset',
89 cb: function (data) {
90 flash.flash('Reset flow trace');
91 traceSrc = null;
92 traceDst = null;
93 ds.closeDialog();
94 $log.debug('BAR action invoked with data:', data);
95 }
96 },
97 toGateway: {
98 gid: 'm_switch',
99 tt: 'Trace to Gateway',
100 cb: function (data) {
101 if (traceSrc != null && data.title == traceSrc && data.navPath == 'host') {
102 //Set traceSrc to traceDst in case trace to gateway
103 traceDst = traceSrc;
Daniel Park577b69c2018-07-16 17:29:34 +0900104 dstDeviceId = 'toGateway';
daniel park128c52c2017-09-04 13:15:51 +0900105 openTraceInfoDialog();
106 flash.flash('Trace to Gateway');
107 }
108 }
109 },
110 toExternal: {
111 gid: 'm_cloud',
112 tt: 'Trace to External',
113 cb: function (data) {
114 if (traceSrc != null && data.title == traceSrc && data.navPath == 'host') {
115 //Set traceDst to 8.8.8.8 to check external connection
116 traceDst = '8.8.8.8';
Daniel Park577b69c2018-07-16 17:29:34 +0900117 dstDeviceId = 'toExternal';
daniel park128c52c2017-09-04 13:15:51 +0900118 openTraceInfoDialog();
119 flash.flash('Trace to External')
120 }
121 }
boyoung27b444122018-09-01 17:28:13 +0900122 },
123 FlowStats: {
124 gid: 'meterTable',
125 tt: 'Flow Statistics',
126 cb: function (data) {
127 if (flowStatsSrcIp == null && data.navPath == 'host') {
128 flowStatsSrcIp = data.propValues.ip;
129 flash.flash('Source ' + flowStatsSrcIp + ' is selected. Choose a destination IP address');
130 $log.info('Source VM is selected for Flow Statistics: ', data);
131 } else if (flowStatsDstIp == null && data.title != flowStatsSrcIp && data.navPath == 'host') {
132 flowStatsDstIp = data.propValues.ip;
133 flash.flash('Destination ' + flowStatsDstIp + ' is selected. Press [Request] button !');
134 openFlowStatsInfoDialog();
135 $log.info('Destination VM is selected for Flow Statistics: ', data);
136 }
137 }
daniel park128c52c2017-09-04 13:15:51 +0900138 }
139 },
140
141 keyBindings: {
142 0: {
143 cb: function () { sts.stopDisplay(); },
144 tt: 'Cancel OpenstackNetworking UI Overlay Mode',
145 gid: 'xMark'
146 },
147 V: {
148 cb: function () {
149 wss.bindHandlers({
150 flowTraceResult: sts,
151 });
152 sts.startDisplay('mouse');
153 },
154 tt: 'Start OpenstackNetworking UI Overlay Mode',
155 gid: 'crown'
156 },
157
158 _keyOrder: [
159 '0', 'V'
160 ]
161 },
162
163 hooks: {
164 // hook for handling escape key
165 // Must return true to consume ESC, false otherwise.
166 escape: function () {
167 // Must return true to consume ESC, false otherwise.
168 return sts.stopDisplay();
169 },
170 mouseover: function (m) {
171 // m has id, class, and type properties
172 $log.debug('mouseover:', m);
173 sts.updateDisplay(m);
174 },
175 mouseout: function () {
176 $log.debug('mouseout');
177 sts.updateDisplay();
178 }
179 }
180 };
181
boyoung27b444122018-09-01 17:28:13 +0900182 function openFlowStatsInfoDialog() {
183 ds.openDialog(traceInfoDialogId, traceInfoDialogOpt)
184 .setTitle('VM to VM Flow Statistics Rule Configuration')
185 .addContent(createFlowStatsInfoDiv(flowStatsSrcIp, flowStatsDstIp))
186 .addCancel(dStatsBoxClose, 'Close')
187 .addOk(flowStatsRemoveReqBtn, 'Remove Stats Rule')
188 .addOk(flowStatsAddReqBtn, 'Add Stats Rule')
189 .bindKeys();
190 }
191
192 function createFlowStatsInfoDiv(srcIp, dstIp) {
193 var texts = ds.createDiv('FlowStatsInfo');
194 texts.append('hr');
195 texts.append('table').append('tbody').append('tr');
196
197 var tBodySelection = texts.select('table').select('tbody').select('tr');
198
199 tBodySelection.append('td').text('Source IP: ').attr("class", "label");
200 tBodySelection.append('td').text(srcIp).attr("class", "value");
201
202 texts.select('table').select('tbody').append('tr');
203
204 tBodySelection = texts.select('table').select('tbody').select('tr:nth-child(2)');
205
206 tBodySelection.append('td').text('Destination IP: ').attr("class", "label");
207 tBodySelection.append('td').text(dstIp).attr("class", "value");
208
209 texts.append('hr');
210
211 return texts;
212 }
213
214 function dStatsBoxClose() {
215 $log.info('Dialog Close button clicked (or Esc pressed)');
216 flowStatsSrcIp = null;
217 flowStatsDstIp = null;
218 }
219
220 function flowStatsAddReqBtn() {
221 sts.sendFlowStatsAddRequest(flowStatsSrcIp, flowStatsDstIp);
222 ds.closeDialog();
223 flowStatsSrcIp = null;
224 flowStatsDstIp = null;
225 flash.flash('Send Flow Statistics Addition Request');
226 }
227
228 function flowStatsRemoveReqBtn() {
229 sts.sendFlowStatsRemoveRequest(flowStatsSrcIp, flowStatsDstIp);
230 ds.closeDialog();
231 flowStatsSrcIp = null;
232 flowStatsDstIp = null;
233 flash.flash('Send Flow Statistics Removal Request');
234 }
235
daniel park128c52c2017-09-04 13:15:51 +0900236 function openTraceInfoDialog() {
237 ds.openDialog(traceInfoDialogId, traceInfoDialogOpt)
238 .setTitle('Flow Trace Information')
239 .addContent(createTraceInfoDiv(traceSrc, traceDst))
240 .addOk(flowTraceResultBtn, 'Request')
241 .bindKeys();
242 }
243
244 function createTraceInfoDiv(src, dst) {
245 var texts = ds.createDiv('traceInfo');
246 texts.append('hr');
247 texts.append('table').append('tbody').append('tr');
248
249 var tBodySelection = texts.select('table').select('tbody').select('tr');
250
251 tBodySelection.append('td').text('Source IP:').attr("class", "label");
252 tBodySelection.append('td').text(src).attr("class", "value");
253
254 texts.select('table').select('tbody').append('tr');
255
256 tBodySelection = texts.select('table').select('tbody').select('tr:nth-child(2)');
257
258 tBodySelection.append('td').text('Destination IP:').attr("class", "label");
259 if (dst == src) {
260 tBodySelection.append('td').text('toGateway').attr("class", "value");
261 } else {
262 tBodySelection.append('td').text(dst).attr("class", "value");
263 }
264
Daniel Park577b69c2018-07-16 17:29:34 +0900265 texts.select('table').select('tbody').append('tr');
266 tBodySelection = texts.select('table').select('tbody').select('tr:nth-child(3)');
267 tBodySelection.append('td').text('SrcDeviceId').attr("class", "label");
268 tBodySelection.append('td').text(srcDeviceId).attr("class", "value");
269
270 texts.select('table').select('tbody').append('tr');
271 tBodySelection = texts.select('table').select('tbody').select('tr:nth-child(4)');
272 tBodySelection.append('td').text('DstDeviceId').attr("class", "label");
273 tBodySelection.append('td').text(dstDeviceId).attr("class", "value");
274
daniel park128c52c2017-09-04 13:15:51 +0900275 texts.append('hr');
276
277 return texts;
daniel park128c52c2017-09-04 13:15:51 +0900278 }
279
280 function flowTraceResultBtn() {
Daniel Park4e037f52018-09-20 18:04:18 +0900281 sts.sendFlowTraceRequest(traceSrc, traceDst, srcDeviceId, dstDeviceId, true);
daniel park128c52c2017-09-04 13:15:51 +0900282 ds.closeDialog();
283 traceSrc = null;
284 traceDst = null;
285 flash.flash('Send Flow Trace Request');
286 }
287
288 function buttonCallback(x) {
289 $log.debug('Toolbar-button callback', x);
290 }
291
292 // invoke code to register with the overlay service
293 angular.module('ovSonaTopov')
294 .run(['$log', 'TopoOverlayService', 'SonaTopovService',
295 'FlashService', 'DialogService', 'WebSocketService',
296
297 function (_$log_, _tov_, _sts_, _flash_, _ds_, _wss_) {
298 $log = _$log_;
299 tov = _tov_;
300 sts = _sts_;
301 flash = _flash_;
302 ds = _ds_;
303 wss = _wss_;
304 tov.register(overlay);
305 }]);
306
307}());