blob: 9b20eb043530639b3a404fe7ca8c007e52f8de49 [file] [log] [blame]
Jimo Jung14e87bf2018-09-03 16:28:13 +09001/*
2 * Copyright 2018-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/*
18 ONOS GUI -- Openstack Vtap View Module
19 */
20(function () {
21 'use strict';
22
23 // injected refs
24 var $log, tov, ovts, fs, wss, tts, api, gs, ps, ds;
25
26 // constants
27 var pCls = 'topo-p',
28 idVta = 'topo-p-vtap',
29 idVDi = 'vtap-dialog',
30 vtapPanelOpts = {
31 edge: 'left',
32 width: 330, // vtap panel width
33 }
34
35 // panels
36 var vtap;
37
38 // selected info
39 var selectedItem;
40
41 // constants
42 var osvIsActReq = 'openstackVtapIsActivatedRequest',
43 osvIsActResp = 'openstackVtapIsActivatedResponse',
44 osvCreateReq = 'openstackVtapCreateRequest',
45 osvCreateResp = 'openstackVtapCreateResponse';
46
47 // function to be replaced by the localization bundle function
48 var topoLion = function (x) {
49 return '#ttrafov#' + x + '#';
50 };
51
52 var overlay = {
53 overlayId: 'vtap-overlay',
54 glyphId: 'm_details',
55 tooltip: 'Openstack Vtap Overlay',
56
57 activate: function () {
58 $log.debug("Openstack Vtap topology overlay ACTIVATED");
59 },
60 deactivate: function () {
61 destroyVtapPanel();
62 $log.debug("Openstack Vtap topology overlay DEACTIVATED");
63 },
64
65 // detail panel button definitions
66 buttons: {
67 createHostVtapBtn: {
68 gid: 'm_details',
69 tt: 'Create Host-to-Host Vtap',
70 cb: displayVtap
71 },
72 showRelatedTraffic: {
73 gid: 'm_relatedIntents',
74 tt: function () { return topoLion('tr_btn_show_related_traffic'); },
75 cb: function (data) { tts.showRelatedIntents(); },
76 },
77 },
78
79 hooks: {
80 multi: function (selectOrder) {
81 var selectedHost = new Object();
82 for (var index in selectOrder) {
83 if (index == 0) {
84 selectedHost.src = selectOrder[index];
85 } else if (index == 1) {
86 selectedHost.dst = selectOrder[index];
87 }
88 }
89
90 selectedItem = selectedHost;
91
92 tov.addDetailButton('showRelatedTraffic');
93 if(selectOrder.length == 2) {
94 tov.addDetailButton('createHostVtapBtn');
95 }
96 }
97 }
98 };
99
100 // Panel API
101 function createTopoPanel(id, opts) {
102 var p = ps.createPanel(id, opts),
103 pid = id,
104 header, body, footer;
105 p.classed(pCls, true);
106
107 function panel() {
108 return p;
109 }
110
111 function hAppend(x) {
112 return header.append(x);
113 }
114
115 function bAppend(x) {
116 return body.append(x);
117 }
118
119 function fAppend(x) {
120 return footer.append(x);
121 }
122
123 function setup() {
124 p.empty();
125
126 p.append('div').classed('header', true);
127 p.append('div').classed('body', true);
128 p.append('div').classed('footer', true);
129
130 header = p.el().select('.header');
131 body = p.el().select('.body');
132 footer = p.el().select('.footer');
133 }
134
135 function destroy() {
136 ps.destroyPanel(pid);
137 }
138
139 return {
140 panel: panel,
141 setup: setup,
142 destroy: destroy,
143 appendHeader: hAppend,
144 appendBody: bAppend,
145 appendFooter: fAppend,
146 };
147 }
148
149 function hideVtapPanel() {
150 vtap.panel().hide();
151 }
152
153 function destroyVtapPanel() {
154 if(vtap != null) {
155 vtap.destroy();
156 }
157 vtap = null;
158 }
159
160 function addInput(tbody, type, id, label, value) {
161 var tr = tbody.append('tr'),
162 lab;
163 if (typeof label === 'string') {
164 lab = label.replace(/_/g, ' ');
165 } else {
166 lab = label;
167 }
168
169 tr.append('td').attr('class', 'label').text(lab + ' :');
170
171 if (type == 'radio') {
172 var td = tr.append('td');
173 for(var index in value) {
174 if(index == 0) {
175 td.append('input').classed( type + '-input', true)
176 .attr('type', type)
177 .attr('value', value[index])
178 .attr('name', label)
179 .attr('id', id)
180 .attr('checked', 'true');
181 } else {
182 td.append('input').classed( type + '-input', true)
183 .attr('type', type)
184 .attr('name', label)
185 .attr('id', id)
186 .attr('value', value[index]);
187 }
188 td.append('span').text(value[index]);
189 }
190 } else {
191 tr.append('td').append('input').classed(type + '-input', true).attr('type', type)
192 .attr('id', id).attr('value', value);
193 }
194 }
195
196 function addButton(tr, callback, value) {
197 tr.append('td').append('input').classed('button-input', true).attr('type', 'button')
198 .attr('value', value).on('click', callback);
199 }
200
201 function makeButton(callback, text, keyName) {
202 var cb = fs.isF(callback),
203 key = fs.isS(keyName);
204
205 function invoke() {
206 cb && cb();
207 }
208
209 return createDiv('vtap-button')
210 .text(text)
211 .on('click', invoke);
212 }
213
214 function createDiv(cls) {
215 var div = d3.select(document.createElement('div'));
216 if (cls) {
217 div.classed(cls, true);
218 }
219 return div;
220 }
221
222 function addInput(tbody, type, id, label, value) {
223 var tr = tbody.append('tr'),
224 lab;
225 if (typeof label === 'string') {
226 lab = label.replace(/_/g, ' ');
227 } else {
228 lab = label;
229 }
230
231 tr.append('td').attr('class', 'label').text(lab + ' :');
232
233 if (type == 'radio') {
234 var td = tr.append('td');
235 for(var index in value) {
236 if(index == 0) {
237 td.append('input').classed( type + '-input', true)
238 .attr('type', type)
239 .attr('value', value[index])
240 .attr('name', label)
241 .attr('id', id)
242 .attr('checked', 'true');
243 } else {
244 td.append('input').classed( type + '-input', true)
245 .attr('type', type)
246 .attr('name', label)
247 .attr('id', id)
248 .attr('value', value[index]);
249 }
250 td.append('span').text(value[index]);
251 }
252 } else {
253 tr.append('td').append('input').classed(type + '-input', true).attr('type', type)
254 .attr('id', id).attr('value', value);
255 }
256 }
257
258 function addButton(tr, callback, value) {
259 tr.append('td').append('input').classed('button-input', true).attr('type', 'button')
260 .attr('value', value).on('click', callback);
261 }
262
263 function makeButton(callback, text, keyName) {
264 var cb = fs.isF(callback),
265 key = fs.isS(keyName);
266
267 function invoke() {
268 cb && cb();
269 }
270
271 return createDiv('vtap-button')
272 .text(text)
273 .on('click', invoke);
274 }
275
276 function createDiv(cls) {
277 var div = d3.select(document.createElement('div'));
278 if (cls) {
279 div.classed(cls, true);
280 }
281 return div;
282 }
283
284 function displayVtap() {
285 $log.debug("sendEvent openstackVtapIsActivatedRequest: ", selectedItem);
286 wss.sendEvent(osvIsActReq, selectedItem);
287 }
288
289 function respIsActCb(selected) {
290 $log.debug("openstackVtapIsActivatedResponse: ", selected);
291 if(vtap == null) {
292 vtap = createTopoPanel(idVta, vtapPanelOpts);
293 }
294 vtap.setup();
295
296 var svg = vtap.appendHeader('div')
297 .classed('icon', true)
298 .append('svg'),
299 title = vtap.appendHeader('h2'),
300 table = vtap.appendBody('table'),
301 tbody = table.append('tbody'),
302 glyphId = 'm_details';
303
304 gs.addGlyph(svg, glyphId, 30, 0, [1, 1]);
305
306 title.text('Create OpenstackVtap');
307
308 addInput(tbody, 'text', 'srcIp', 'Source IP', selected.srcName);
309 addInput(tbody, 'text', 'dstIp', 'Destination IP', selected.dstName);
310 addInput(tbody, 'radio', 'ipProto', 'Protocol', selected.ipProtoList);
311 addInput(tbody, 'number', 'srcPort', 'Source Port', "");
312 addInput(tbody, 'number', 'dstPort', 'Destination Port', "");
313 addInput(tbody, 'radio', 'vtapType', 'Type', selected.vtapTypeList);
314
315 vtap.appendFooter('hr');
316 var footTr = vtap.appendFooter('table').append('tbody').append('tr');
317
318 addButton(footTr, createVtap, 'Create');
319 addButton(footTr, hideVtapPanel, 'Cancel');
320
321 vtap.panel().show();
322 }
323
324 function createVtap() {
325 var vtapInfo = {};
326
327 vtapInfo.srcIp = document.getElementById('srcIp').value;
328 vtapInfo.dstIp = document.getElementById('dstIp').value;
329 vtapInfo.ipProto = document.querySelector('input[name="Protocol"]:checked').value;
330 vtapInfo.srcPort = document.getElementById('srcPort').value;
331 vtapInfo.dstPort = document.getElementById('dstPort').value;
332 vtapInfo.vtapType = document.querySelector('input[name="Type"]:checked').value;
333
334 if(vtapInfo.srcPort == ""){
335 vtapInfo.srcPort = 0;
336 }
337 if(vtapInfo.dstPort == ""){
338 vtapInfo.dstPort = 0;
339 }
340
341 $log.debug("sendEvent openstackVtapCreateRequest: ", vtapInfo);
342 wss.sendEvent(osvCreateReq, vtapInfo);
343 hideVtapPanel();
344
345 }
346
347 function respCreateCb(result) {
348 $log.debug("respCreateCb: ", result);
349
350 function dOK() {
351 if(result.result == "Failed"){
352 displayVtap(selectedItem);
353 } else {
354 destroyVtapPanel();
355 }
356 }
357
358 function createContent(value) {
359 var content = ds.createDiv();
360 content.append('p').text(value);
361 return content;
362 }
363
364 ds.openDialog(idVDi, vtapPanelOpts)
365 .setTitle("Create Vtap " + result.result)
366 .addContent(createContent(result.value))
367 .addOk(dOK);
368 }
369
370 // invoke code to register with the overlay service
371 angular.module('ovOpenstackvtap', [])
372 .factory('OpenstackVtapTopovService',
373 ['$log', 'FnService', 'WebSocketService', 'GlyphService', 'PanelService', 'DialogService',
374
375 function (_$log_, _fs_, _wss_, _gs_, _ps_, _ds_) {
376 $log = _$log_;
377 fs = _fs_;
378 wss = _wss_;
379 gs = _gs_;
380 ps = _ps_;
381 ds = _ds_;
382
383 var handlers = {},
384 vtapOverlay = 'vtap-overlay',
385 defaultOverlay = 'traffic';
386
387 handlers[osvIsActResp] = respIsActCb;
388 handlers[osvCreateResp] = respCreateCb;
389
390 wss.bindHandlers(handlers);
391
392 return {
393 displayVtap: displayVtap
394 };
395 }])
396 .run(['$log', 'TopoOverlayService', 'OpenstackVtapTopovService', 'TopoTrafficService',
397
398 function (_$log_, _tov_, _ovts_, _tts_) {
399 $log = _$log_;
400 tov = _tov_;
401 ovts = _ovts_;
402 tts = _tts_;
403 tov.register(overlay);
404 }]
405 );
406}());