diff --git a/webroot/monitor/infra/underlay/ui/js/flow_queries.js b/webroot/monitor/infra/underlay/ui/js/flow_queries.js
index 1da5d700b..b101d8553 100644
--- a/webroot/monitor/infra/underlay/ui/js/flow_queries.js
+++ b/webroot/monitor/infra/underlay/ui/js/flow_queries.js
@@ -91,7 +91,7 @@ frQuery['columnDisplay'] = [
{select:"destip", display:{id:"destip", field:"destip", width:90, name:"Destination IP", groupable:true, formatter: function(r, c, v, cd, dc){ return (validateIPAddress(handleNull4Grid(dc['destip'])) == true ? handleNull4Grid(dc['destip']) : noDataStr)}}},
{select:"dport", display:{id:"dport", field:"dport", width:70, name:"Destination Port", groupable:true, formatter: function(r, c, v, cd, dc){ return handleNull4Grid(dc.dport);}}},
{select:"agg-bytes", display:{id:'agg-bytes', field:'agg-bytes', width:120, name:"Bytes/Packets", groupable:false,formatter: function(r, c, v, cd, dc) {return contrail.format("{0}/{1}",formatBytes(dc['agg-bytes'],'-'),dc['agg-packets']);}}},
-];
+ ];
frQuery['defaultColumns'] = ['sourcevn', 'sourceip', 'sport', 'destvn', 'destip', 'dport', 'protocol', 'direction_ing'];
fsQuery['defaultColumns'] = ['flow_class_id', 'direction_ing'];
@@ -803,7 +803,7 @@ function viewFRQueryResults(dataItem, params) {
loadFlowResultsForUnderlay(options, reqQueryObj, queryColumnDisplay);
};
-function loadFlowResultsForUnderlay(options, reqQueryObj, columnDisplay, fcGridDisplay,reverseTraceFlow) {
+function loadFlowResultsForUnderlay(options, reqQueryObj, columnDisplay, fcGridDisplay,traceFlow) {
var grid = $('#' + options.elementId).data('contrailGrid'),
url = "/api/admin/reports/query",
btnId = options.btnId,
@@ -879,6 +879,10 @@ function loadFlowResultsForUnderlay(options, reqQueryObj, columnDisplay, fcGridD
type: 'status',
iconClasses: '',
text: 'Your query has been queued.'
+ },error: {
+ type: 'error',
+ iconClasses: 'icon-warning',
+ text: 'Error in fetching details'
}
}
},
@@ -886,7 +890,7 @@ function loadFlowResultsForUnderlay(options, reqQueryObj, columnDisplay, fcGridD
pager : {
options : {
pageSize : options.pageSize,
- pageSizeSelect : [10, 50, 100, 200, 500 ]
+ pageSizeSelect : [10, 50, 100, 200 ]
}
}
}
@@ -900,42 +904,57 @@ function loadFlowResultsForUnderlay(options, reqQueryObj, columnDisplay, fcGridD
'];
}
else if(options.queryPrefix == 'fr'){
- var customControls = [
- ''
- ];
- if(reverseTraceFlow == true){
- customControls = [
- '',
- '',
- ];
- }
- gridConfig.header.customControls = customControls,
gridConfig.body.options = {
- checkboxSelectable: {
- enableRowCheckbox: true,
- onNothingChecked: function(e){
- $("#mapflow").attr('disabled','disabled');
- $("#traceFlowBtn").attr('disabled','disabled');
- $("#revTraceFlowBtn").attr('disabled','disabled');
- },
- onSomethingChecked: function(e){
- $("#mapflow").removeAttr('disabled');
- $("#traceFlowBtn").removeAttr('disabled');
- $("#revTraceFlowBtn").removeAttr('disabled');
- }
- },
actionCell: [],
lazyLoading:true,
+ actionCellPosition : 'start'
+ };
+ if(getValueByJsonPath(globalObj['webServerInfo'],'disabledFeatures;disabled',[]).indexOf('mon_infra_underlay') == -1) {
+ if(traceFlow == true) {
+ gridConfig.body.options.actionCell.push({
+ title:'TraceFlow',
+ iconClass: 'icon-contrail-trace-flow',
+ onClick: function(rowId,targetElement){
+ if(typeof underlayRenderer === 'object') {
+ $("#"+options.elementId+" div.selected-slick-row").each(function(idx,obj){
+ $(obj).removeClass('selected-slick-row');
+ });
+ $(targetElement).parent().parent().addClass('selected-slick-row');
+ underlayRenderer.getView().doTraceFlow(rowId);
+ }
+ }
+ },{
+ title:'Reverse TraceFlow',
+ iconClass: 'icon-contrail-reverse-flow',
+ onClick: function(rowId,targetElement){
+ if(typeof underlayRenderer === 'object') {
+ $("#"+options.elementId+" div.selected-slick-row").each(function(idx,obj){
+ $(obj).removeClass('selected-slick-row');
+ });
+ $(targetElement).parent().parent().addClass('selected-slick-row');
+ underlayRenderer.getView().doReverseTraceFlow(rowId);
+ }
+ }
+ });
+ } else {
+ gridConfig.body.options.actionCell.push({
+ title: 'Show Underlay Paths',
+ iconClass: 'icon-contrail-trace-flow',
+ onClick: function(rowIndex,targetElement){
+ var dataItem = $('#' + options.elementId).data('contrailGrid')._grid.getDataItem(rowIndex);
+ var startTime = $("#"+options.queryPrefix+"-results").data('startTimeUTC');
+ var endTime = $("#"+options.queryPrefix+"-results").data('endTimeUTC');
+ dataItem['startTime'] = startTime;
+ dataItem['endTime'] = endTime;
+ $("#fr-results div.selected-slick-row").each(function(idx,obj){
+ $(obj).removeClass('selected-slick-row');
+ });
+ $(targetElement).parent().parent().addClass('selected-slick-row');
+ showUnderlayPaths(dataItem);
+ }
+ });
+ }
};
- $("#mapflow").die('click').live('click',function(e){
- var startTime = $("#"+options.queryPrefix+"-results").data('startTimeUTC');
- var endTime = $("#"+options.queryPrefix+"-results").data('endTimeUTC');
- var checkedRows = $("#"+options.queryPrefix+"-results").data('contrailGrid').getCheckedRows();
- var dataItem = ifNull(checkedRows[0],{});
- dataItem['startTime'] = startTime;
- dataItem['endTime'] = endTime;
- showUnderlayPaths(dataItem);
- });
}
$("#" + options.elementId).contrailGrid(gridConfig);
gridObject = $("#"+options.elementId).data('contrailGrid');
diff --git a/webroot/monitor/infra/underlay/ui/js/monitor_infra_underlay.js b/webroot/monitor/infra/underlay/ui/js/monitor_infra_underlay.js
index c245be5db..0a452859f 100644
--- a/webroot/monitor/infra/underlay/ui/js/monitor_infra_underlay.js
+++ b/webroot/monitor/infra/underlay/ui/js/monitor_infra_underlay.js
@@ -453,7 +453,7 @@ underlayModel.prototype.destroy = function() {
this.reset();
}
-underlayModel.prototype.checkIPInVrouterList = function(data) {
+underlayModel.prototype.checkIPInVrouterList = function (data) {
var vRouterList = getValueByJsonPath(globalObj,'topologyResponse;vRouterList',[]);
for(var i = 0; i < ifNull(vRouterList,[]).length; i++) {
var vRouterData = vRouterList[i];
@@ -776,7 +776,7 @@ underlayView.prototype.createElementsFromAdjacencyList = function() {
return;
}
}
- }
+ }
var parentNode = jsonPath(nodes, "$[?(@.name=='" + parentElementLabel + "')]");
if(false !== parentNode && parentNode.length === 1) {
parentNode = parentNode[0];
@@ -790,7 +790,7 @@ underlayView.prototype.createElementsFromAdjacencyList = function() {
}
});
- _.each(adjacencyList, function(edges, parentElementLabel) {
+ _.each(adjacencyList, function(edges, parentElementLabel) {
var parentNode = jsonPath(nodes, "$[?(@.name=='" + parentElementLabel + "')]");
if(false !== parentNode && parentNode.length === 1) {
parentNode = parentNode[0];
@@ -1432,7 +1432,7 @@ underlayView.prototype.initGraphEvents = function() {
paper.on('blank:pointerdblclick', function (evt, x, y) {
evt.stopImmediatePropagation();
- _this.resetTopology();
+ _this.resetTopology(false);
});
paper.on("cell:pointerdblclick", function (cellView, evt, x, y) {
@@ -1579,7 +1579,7 @@ underlayView.prototype.initGraphEvents = function() {
}
var vnNameArr = ifNull(vnList[0].split(':'),[]);
var networkName = ifNull(vnNameArr[2],'-');
- var projectName = '('+ifNull(vnNameArr[2],'-')+')';
+ var projectName = '('+ifNull(vnNameArr[1],'-')+')';
srcVN += networkName +" "+ projectName;
break;
}
@@ -2084,7 +2084,10 @@ underlayView.prototype.renderTracePath = function(options) {
var name = $.grep(computeNodes,function(value,idx){
return (getValueByJsonPath(value,'more_attributes;VrouterAgent;self_ip_list;0','-') == dc['peer_vrouter']);
});
- return contrail.format('{0} ({1})',getValueByJsonPath(name,'0;name','-'),dc['peer_vrouter']);
+ if(validateIPAddress(dc['peer_vrouter']))
+ return contrail.format('{0} ({1})',getValueByJsonPath(name,'0;name','-'),dc['peer_vrouter']);
+ else
+ return '-';
}
},
{
@@ -2182,10 +2185,8 @@ underlayView.prototype.renderTracePath = function(options) {
text : 'Flows'
},
customControls: [
- '',
- '',
- '',
- '',
+ '',
+ '',
],
},
columnHeader : {
@@ -2195,19 +2196,33 @@ underlayView.prototype.renderTracePath = function(options) {
options : {
forceFitColumns: true,
sortable : false,
- checkboxSelectable: {
- enableRowCheckbox: true,
- onNothingChecked: function(e){
- $("#mapflow").attr('disabled','disabled');
- $("#traceFlowBtn").attr('disabled','disabled');
- $("#revTraceFlowBtn").attr('disabled','disabled');
- },
- onSomethingChecked: function(e){
- $("#mapflow").removeAttr('disabled');
- $("#traceFlowBtn").removeAttr('disabled');
- $("#revTraceFlowBtn").removeAttr('disabled');
+ actionCellPosition: 'start',
+ actionCell:[{
+ title:'TraceFlow',
+ iconClass: 'icon-contrail-trace-flow',
+ onClick: function(rowId,targetElement){
+ if(typeof underlayRenderer == 'object') {
+ $("#vrouterflows div.selected-slick-row").each(function(idx,obj){
+ $(obj).removeClass('selected-slick-row');
+ });
+ $(targetElement).parent().parent().addClass('selected-slick-row');
+ underlayRenderer.getView().doTraceFlow(rowId);
+ }
}
- },
+ },{
+ title:'Reverse TraceFlow',
+ iconClass: 'icon-contrail-reverse-flow',
+ onClick: function(rowId,targetElement){
+ if(typeof underlayRenderer == 'object') {
+ $("#vrouterflows div.selected-slick-row").each(function(idx,obj){
+ $(obj).removeClass('selected-slick-row');
+ });
+ $(targetElement).parent().parent().addClass('selected-slick-row');
+ underlayRenderer.getView().doReverseTraceFlow(rowId);
+ }
+ }
+ }
+ ],
},
dataSource : {
remote: {
@@ -2229,6 +2244,7 @@ underlayView.prototype.renderTracePath = function(options) {
onDataBoundCB : function () {
var gridObj = $("#vrouterflows").data('contrailGrid');
$("#vrouterflows").find('input.headerRowCheckbox').parent('span').remove();
+ vrouterflowsGrid.removeGridMessage('loading');
if(gridObj != null) {
var dataItems = gridObj._dataView.getItems();
var dataItemsLen = dataItems.length;
@@ -2254,12 +2270,12 @@ underlayView.prototype.renderTracePath = function(options) {
text: 'Error in getting Data.'
}
}
- },
- footer : false
+ },footer:false
});
var newAjaxConfig = {};
$("#btnNextFlows").click(function(){
if(flowKeyStack.length > 0 && flowKeyStack[flowKeyStack.length - 1] != null){
+ vrouterflowsGrid.showGridMessage('loading');
nextClicked = true;
newAjaxConfig = {
url: monitorInfraUrls['VROUTER_FLOWS'] + '?ip=' + getIPOrHostName(computeNodeInfo)
@@ -2272,9 +2288,8 @@ underlayView.prototype.renderTracePath = function(options) {
}
});
$("#btnPrevFlows").click(function(){
- if(nextClicked)
- flowKeyStack.pop();
- nextClicked = false;
+ flowKeyStack.pop();
+ vrouterflowsGrid.showGridMessage('loading');
if(flowKeyStack.length > 0) {
newAjaxConfig = {
url: monitorInfraUrls['VROUTER_FLOWS'] + '?ip=' + getIPOrHostName(computeNodeInfo)
@@ -2288,8 +2303,6 @@ underlayView.prototype.renderTracePath = function(options) {
+ '&introspectPort=' + computeNodeInfo['introspectPort'],
type:'Get'
};
- //Need to disable the prev button because flowKeystack < 1 which means first set of records call
- $("#btnPrevFlows").attr('disabled','disabled');
}
vrouterflowsGrid.setRemoteAjaxConfig(newAjaxConfig);
reloadGrid(vrouterflowsGrid);
@@ -2419,209 +2432,6 @@ underlayView.prototype.renderTracePath = function(options) {
}
}
});
-
- $("#traceFlowBtn").die('click').live('click',function(e){
- var flowGrid = $("#vrouterflows").data('contrailGrid');
- var checkedRows = flowGrid.getCheckedRows();
- var dataItem = ifNull(checkedRows[0],{});
- var item = tracePathDropdown.getSelectedData();
- var contextVrouterIp = '';
- try {
- contextVrouterIp = item[0]['text'].split("(")[1].slice(0,-1);
- }catch(err) {
- }
- /*
- * For egress flows the source vm ip may not spawned in the same vrouter,
- * so need to pick the peer_vrouter
- */
- var postData = {},nwFqName = '';
- var postData = {
- srcIP: dataItem['sourceip'] != null ? dataItem['sourceip'] : dataItem['sip'],
- destIP: dataItem['destip'] != null ? dataItem['destip'] : dataItem['dip'],
- srcPort: dataItem['sport'] != null ? dataItem['sport'] : dataItem['src_port'],
- destPort: dataItem['dport'] != null ? dataItem['dport'] : dataItem['dst_port'],
- srcVN: dataItem['src_vn'] != null ? dataItem['src_vn'] : dataItem['sourcevn'],
- destVN: dataItem['dst_vn'] != null ? dataItem['dst_vn'] : dataItem['destvn'],
- protocol: dataItem['protocol'],
- maxAttempts: 3,
- interval: 5,
- };
- //We are sending the VrfId of the flow for trace router request, in some cases like egress flows, the Vrf Id is in context with the
- //current Vrouter introspect but we are issuing the trace route request to other vrouter,which throws error to fix these cases
- //resolveVrfId IP used.
- if(dataItem['direction_ing'] == 1 || dataItem['direction'] == 'ingress') {
- if($("#vrouterRadiobtn").is(':checked')) {
- postData['nodeIP'] = contextVrouterIp;
- postData['resolveVrfId'] = contextVrouterIp;
- } else if($("#instRadiobtn").is(':checked')) {
- if (dataItem['vrouter_ip'] != null) {
- postData['nodeIP'] = dataItem['vrouter_ip'];
- } else if (dataItem['vrouter'] != null){
- var vrouterDetails = underlayView.prototype.getvRouterVMDetails(dataItem['vrouter'],'name',VROUTER);
- postData['nodeIP'] = getValueByJsonPath(vrouterDetails,'more_attributes;VrouterAgent;self_ip_list;0','-');
- }
- }
- if(dataItem['raw_json'] != null && dataItem['raw_json']['vrf'] != null) {
- postData['vrfId'] = parseInt(dataItem['raw_json']['vrf']);
- }
- nwFqName = dataItem['sourcevn'] != null ? dataItem['sourcevn'] : dataItem['src_vn'];
- } else if(dataItem['direction_ing'] == 0 || dataItem['direction'] == 'egress') {
- if(dataItem['raw_json'] != null && dataItem['raw_json']['vrf'] != null) {
- postData['vrfId'] = parseInt(dataItem['raw_json']['vrf']);
- postData['resolveVrfId'] = contextVrouterIp;
- }
- postData['nodeIP'] = dataItem['other_vrouter_ip'] != null ? dataItem['other_vrouter_ip'] : dataItem['peer_vrouter'];
- nwFqName = dataItem['sourcevn'] != null ? dataItem['sourcevn'] : dataItem['src_vn'];
- }
- if(typeof underlayRenderer === 'object' && !underlayRenderer.getModel().checkIPInVrouterList(postData)) {
- showInfoWindow("Cannot Trace the path for the selected flow", "Info");
- return;
- }
- var progressBar = $("#network_topology").find('.topology-visualization-loading');
- $(progressBar).show();
- $(progressBar).css('margin-bottom',$(progressBar).parent().height());
- if (postData['vrfId'] != null) {
- doTraceFlow(postData);
- } else {
- $.ajax({
- url:'api/tenant/networking/virtual-network/summary?fqNameRegExp='+nwFqName,
- }).always(function(networkDetails){
- if(networkDetails['value']!= null && networkDetails['value'][0] != null && networkDetails['value'][0]['value'] != null) {
- var vrfList = getValueByJsonPath(networkDetails,'value;0;value;UveVirtualNetworkConfig;routing_instance_list',[]);
- if(vrfList[0] != null)
- nwFqName += ":"+vrfList[0];
- } else
- // if there is no vrf name in the response then just constructing it in general format
- nwFqName += ":"+nwFqName.split(':')[2];
- postData['vrfName'] = nwFqName;
- doTraceFlow(postData);
- });
- }
-
- function doTraceFlow (postData) {
- $.ajax({
- url:'/api/tenant/networking/trace-flow',
- type:'POST',
- timeout:5000,
- data:{
- data: postData
- }
- }).done(function(response) {
- if(typeof underlayRenderer === 'object') {
- underlayRenderer.getModel().setFlowPath(response);
- }
- _this.highlightPath(response, {data: postData});
- }).fail(function(error,status) {
- _this.resetTopology(false);
- if(status == 'timeout') {
- showInfoWindow('Timeout in fetching details','Error');
- } else if (status != 'success') {
- showInfoWindow('Error in fetching details','Error');
- }
- }).always(function(ajaxObj,status) {
- $(progressBar).hide();
- });
- }
- });
- $("#revTraceFlowBtn").die('click').live('click',function(e){
- var flowGrid = $("#vrouterflows").data('contrailGrid');
- var checkedRows = flowGrid.getCheckedRows();
- var dataItem = ifNull(checkedRows[0],{}),nwFqName = '';
- var item = tracePathDropdown.getSelectedData();
- var contextVrouterIp = '';
- try {
- contextVrouterIp = item[0]['text'].split("(")[1].slice(0,-1);
- }catch(err) {
- }
- /*
- * For egress flows the source vm ip may not spawned in the same vrouter,
- * so need to pick the peer_vrouter
- */
- var postData = {
- srcIP: dataItem['destip'] != null ? dataItem['destip'] : dataItem['dip'],
- destIP: dataItem['sourceip'] != null ? dataItem['sourceip'] : dataItem['sip'],
- srcPort: dataItem['dport'] != null ? dataItem['dport'] : dataItem['dst_port'],
- destPort: dataItem['sport'] != null ? dataItem['sport'] : dataItem['src_port'],
- srcVN: dataItem['src_vn'] != null ? dataItem['src_vn'] : dataItem['sourcevn'],
- destVN: dataItem['dst_vn'] != null ? dataItem['dst_vn'] : dataItem['destvn'],
- protocol: dataItem['protocol'],
- maxAttempts: 3,
- interval: 5,
- };
- if(dataItem['direction_ing'] == 0 || dataItem['direction'] == 'egress') {
- if($("#vrouterRadiobtn").is(':checked')) {
- postData['nodeIP'] = contextVrouterIp;
- postData['resolveVrfId'] = contextVrouterIp;
- } else if($("#instRadiobtn").is(':checked')) {
- if (dataItem['vrouter_ip'] != null) {
- postData['nodeIP'] = dataItem['vrouter_ip'];
- } else if (dataItem['vrouter'] != null){
- var vrouterDetails = underlayView.prototype.getvRouterVMDetails(dataItem['vrouter'],'name',VROUTER);
- postData['nodeIP'] = getValueByJsonPath(vrouterDetails,'more_attributes;VrouterAgent;self_ip_list;0','-');
- }
- }
- nwFqName = dataItem['destvn'] != null ? dataItem['destvn'] : dataItem['dst_vn'];
- if(dataItem['raw_json'] != null && dataItem['raw_json']['dest_vrf'] != null) {
- postData['vrfId'] = parseInt(dataItem['raw_json']['dest_vrf']);
- }
- } else if(dataItem['direction_ing'] == 1 || dataItem['direction'] == 'ingress') {
- postData['nodeIP'] = dataItem['other_vrouter_ip'] != null ? dataItem['other_vrouter_ip'] : dataItem['peer_vrouter'];
- nwFqName = dataItem['destvn'] != null ? dataItem['destvn'] : dataItem['dst_vn'];
- if(dataItem['raw_json'] != null && dataItem['raw_json']['dest_vrf'] != null) {
- postData['vrfId'] = parseInt(dataItem['raw_json']['dest_vrf']);
- postData['resolveVrfId'] = contextVrouterIp;
- }
- }
- if(typeof underlayRenderer === 'object' && !underlayRenderer.getModel().checkIPInVrouterList(postData)) {
- showInfoWindow("Cannot Trace the path for the selected flow", "Info");
- return;
- }
- var progressBar = $("#network_topology").find('.topology-visualization-loading');
- $(progressBar).show();
- $(progressBar).css('margin-bottom',$(progressBar).parent().height());
- if(postData['vrfId'] != null) {
- doReverseFlow(postData);
- } else {
- $.ajax({
- url:'api/tenant/networking/virtual-network/summary?fqNameRegExp='+nwFqName,
- }).always(function(networkDetails){
- if(networkDetails['value']!= null && networkDetails['value'][0] != null && networkDetails['value'][0]['value'] != null) {
- var vrfList = getValueByJsonPath(networkDetails,'value;0;value;UveVirtualNetworkConfig;routing_instance_list',[]);
- if(vrfList[0] != null)
- nwFqName += ":"+vrfList[0];
- } else
- // if there is no vrf name in the response then just constructing it in general format
- nwFqName += ":"+nwFqName.split(':')[2];
- postData['vrfName'] = nwFqName;
- doReverseFlow(postData);
- });
- }
- function doReverseFlow (postData) {
- $.ajax({
- url:'/api/tenant/networking/trace-flow',
- type:'POST',
- timeout:5000,
- data:{
- data: postData
- }
- }).done(function(response) {
- if(typeof underlayRenderer === 'object') {
- underlayRenderer.getModel().setFlowPath(response);
- }
- _this.highlightPath(response, {data: postData});
- }).fail(function(error,status) {
- _this.resetTopology(false);
- if(status == 'timeout') {
- showInfoWindow('Timeout in fetching details','Error');
- } else if (status != 'success') {
- showInfoWindow('Error in fetching details','Error');
- }
- }).always(function(ajaxObj,status) {
- $(progressBar).hide();
- });
- }
- });
-
function getInstFlowsUrl(name){
var req = {};
var ajaxData = {
@@ -2656,6 +2466,167 @@ underlayView.prototype.renderTracePath = function(options) {
return req;
}
}
+
+underlayView.prototype.doTraceFlow = function (rowId) {
+ var flowGrid = $("#vrouterflows").data('contrailGrid');
+ var checkedRows = flowGrid.getCheckedRows(),tracePathDropdown = $("#tracePathDropdown").data('contrailDropdown');;
+ var dataItem = null;
+ if (rowId != null) {
+ dataItem = ifNull(flowGrid._grid.getDataItem(rowId),{});
+ } else {
+ dataItem = ifNull(checkedRows[0],{});
+ }
+ var item = tracePathDropdown.getSelectedData();
+ var contextVrouterIp = '';
+ try {
+ contextVrouterIp = item[0]['text'].split("(")[1].slice(0,-1);
+ }catch(err) {
+ }
+ /*
+ * For egress flows the source vm ip may not spawned in the same vrouter,
+ * so need to pick the peer_vrouter
+ */
+ var postData = {},nwFqName = '';
+ var postData = {
+ srcIP: dataItem['sourceip'] != null ? dataItem['sourceip'] : dataItem['sip'],
+ destIP: dataItem['destip'] != null ? dataItem['destip'] : dataItem['dip'],
+ srcPort: dataItem['sport'] != null ? dataItem['sport'] : dataItem['src_port'],
+ destPort: dataItem['dport'] != null ? dataItem['dport'] : dataItem['dst_port'],
+ srcVN: dataItem['src_vn'] != null ? dataItem['src_vn'] : dataItem['sourcevn'],
+ destVN: dataItem['dst_vn'] != null ? dataItem['dst_vn'] : dataItem['destvn'],
+ protocol: dataItem['protocol'],
+ maxAttempts: 3,
+ interval: 5,
+ };
+ //We are sending the VrfId of the flow for trace router request, in some cases like egress flows, the Vrf Id is in context with the
+ //current Vrouter introspect but we are issuing the trace route request to other vrouter,which throws error to fix these cases
+ //resolveVrfId IP used.
+ if(dataItem['direction_ing'] == 1 || dataItem['direction'] == 'ingress') {
+ if($("#vrouterRadiobtn").is(':checked')) {
+ postData['nodeIP'] = contextVrouterIp;
+ postData['resolveVrfId'] = contextVrouterIp;
+ } else if($("#instRadiobtn").is(':checked')) {
+ if (dataItem['vrouter_ip'] != null) {
+ postData['nodeIP'] = dataItem['vrouter_ip'];
+ } else if (dataItem['vrouter'] != null){
+ var vrouterDetails = underlayView.prototype.getvRouterVMDetails(dataItem['vrouter'],'name',VROUTER);
+ postData['nodeIP'] = getValueByJsonPath(vrouterDetails,'more_attributes;VrouterAgent;self_ip_list;0','-');
+ }
+ }
+ if(dataItem['raw_json'] != null && dataItem['raw_json']['vrf'] != null) {
+ postData['vrfId'] = parseInt(dataItem['raw_json']['vrf']);
+ }
+ nwFqName = dataItem['sourcevn'] != null ? dataItem['sourcevn'] : dataItem['src_vn'];
+ } else if(dataItem['direction_ing'] == 0 || dataItem['direction'] == 'egress') {
+ if(dataItem['raw_json'] != null && dataItem['raw_json']['vrf'] != null) {
+ postData['vrfId'] = parseInt(dataItem['raw_json']['vrf']);
+ postData['resolveVrfId'] = contextVrouterIp;
+ }
+ postData['nodeIP'] = dataItem['other_vrouter_ip'] != null ? dataItem['other_vrouter_ip'] : dataItem['peer_vrouter'];
+ nwFqName = dataItem['sourcevn'] != null ? dataItem['sourcevn'] : dataItem['src_vn'];
+ }
+ if(typeof underlayRenderer === 'object' && !underlayRenderer.getModel().checkIPInVrouterList(postData)) {
+ showInfoWindow("Cannot Trace route for the selected flow", "Info");
+ return;
+ }
+ if (postData['vrfId'] != null) {
+ doTraceFlowRequest(postData);
+ } else {
+ $.ajax({
+ url:'api/tenant/networking/virtual-network/summary?fqNameRegExp='+nwFqName,
+ }).always(function(networkDetails){
+ if(networkDetails['value']!= null && networkDetails['value'][0] != null && networkDetails['value'][0]['value'] != null) {
+ var vrfList = getValueByJsonPath(networkDetails,'value;0;value;UveVirtualNetworkConfig;routing_instance_list',[]);
+ if(vrfList[0] != null)
+ nwFqName += ":"+vrfList[0];
+ } else
+ // if there is no vrf name in the response then just constructing it in general format
+ nwFqName += ":"+nwFqName.split(':')[2];
+ postData['vrfName'] = nwFqName;
+ doTraceFlowRequest(postData);
+ });
+ }
+}
+
+underlayView.prototype.doReverseTraceFlow = function (rowId) {
+
+ var flowGrid = $("#vrouterflows").data('contrailGrid');
+ var checkedRows = flowGrid.getCheckedRows(),tracePathDropdown = $("#tracePathDropdown").data('contrailDropdown');
+ var dataItem = null;
+ if (rowId != null) {
+ dataItem = ifNull(flowGrid._grid.getDataItem(rowId),{});
+ } else {
+ dataItem = ifNull(checkedRows[0],{});
+ }
+ var item = tracePathDropdown.getSelectedData();
+ var contextVrouterIp = '';
+ try {
+ contextVrouterIp = item[0]['text'].split("(")[1].slice(0,-1);
+ }catch(err) {
+ }
+ /*
+ * For egress flows the source vm ip may not spawned in the same vrouter,
+ * so need to pick the peer_vrouter
+ */
+ var postData = {
+ srcIP: dataItem['destip'] != null ? dataItem['destip'] : dataItem['dip'],
+ destIP: dataItem['sourceip'] != null ? dataItem['sourceip'] : dataItem['sip'],
+ srcPort: dataItem['dport'] != null ? dataItem['dport'] : dataItem['dst_port'],
+ destPort: dataItem['sport'] != null ? dataItem['sport'] : dataItem['src_port'],
+ srcVN: dataItem['src_vn'] != null ? dataItem['src_vn'] : dataItem['sourcevn'],
+ destVN: dataItem['dst_vn'] != null ? dataItem['dst_vn'] : dataItem['destvn'],
+ protocol: dataItem['protocol'],
+ maxAttempts: 3,
+ interval: 5,
+ };
+ if(dataItem['direction_ing'] == 0 || dataItem['direction'] == 'egress') {
+ if($("#vrouterRadiobtn").is(':checked')) {
+ postData['nodeIP'] = contextVrouterIp;
+ postData['resolveVrfId'] = contextVrouterIp;
+ } else if($("#instRadiobtn").is(':checked')) {
+ if (dataItem['vrouter_ip'] != null) {
+ postData['nodeIP'] = dataItem['vrouter_ip'];
+ } else if (dataItem['vrouter'] != null){
+ var vrouterDetails = underlayView.prototype.getvRouterVMDetails(dataItem['vrouter'],'name',VROUTER);
+ postData['nodeIP'] = getValueByJsonPath(vrouterDetails,'more_attributes;VrouterAgent;self_ip_list;0','-');
+ }
+ }
+ nwFqName = dataItem['destvn'] != null ? dataItem['destvn'] : dataItem['dst_vn'];
+ if(dataItem['raw_json'] != null && dataItem['raw_json']['dest_vrf'] != null) {
+ postData['vrfId'] = parseInt(dataItem['raw_json']['dest_vrf']);
+ }
+ } else if(dataItem['direction_ing'] == 1 || dataItem['direction'] == 'ingress') {
+ postData['nodeIP'] = dataItem['other_vrouter_ip'] != null ? dataItem['other_vrouter_ip'] : dataItem['peer_vrouter'];
+ nwFqName = dataItem['destvn'] != null ? dataItem['destvn'] : dataItem['dst_vn'];
+ if(dataItem['raw_json'] != null && dataItem['raw_json']['dest_vrf'] != null) {
+ postData['vrfId'] = parseInt(dataItem['raw_json']['dest_vrf']);
+ postData['resolveVrfId'] = contextVrouterIp;
+ }
+ }
+ if(typeof underlayRenderer === 'object' && !underlayRenderer.getModel().checkIPInVrouterList(postData)) {
+ showInfoWindow("Cannot Trace route for the selected flow", "Info");
+ return;
+ }
+ if(postData['vrfId'] != null) {
+ doTraceFlowRequest(postData);
+ } else {
+ $.ajax({
+ url:'api/tenant/networking/virtual-network/summary?fqNameRegExp='+nwFqName,
+ }).always(function(networkDetails){
+ if(networkDetails['value']!= null && networkDetails['value'][0] != null && networkDetails['value'][0]['value'] != null) {
+ var vrfList = getValueByJsonPath(networkDetails,'value;0;value;UveVirtualNetworkConfig;routing_instance_list',[]);
+ if(vrfList[0] != null)
+ nwFqName += ":"+vrfList[0];
+ } else
+ // if there is no vrf name in the response then just constructing it in general format
+ nwFqName += ":"+nwFqName.split(':')[2];
+ postData['vrfName'] = nwFqName;
+ doTraceFlowRequest(postData);
+ });
+ }
+
+}
+
/*
* This is utility function which accepts value to compare and key to lookup
* and type to check in globalObj and get the response where we lookup for the
@@ -3390,4 +3361,44 @@ underlayController.prototype.getModelData = function(cfg) {
underlayController.prototype.destroy = function() {
//tbd
}
-
+function doTraceFlowRequest (postData) {
+ var progressBar = $("#network_topology").find('.topology-visualization-loading');
+ $(progressBar).show();
+ $(progressBar).css('margin-bottom',$(progressBar).parent().height());
+
+ $.ajax({
+ url:'/api/tenant/networking/trace-flow',
+ type:'POST',
+ timeout:5000,
+ data:{
+ data: postData
+ }
+ }).done(function(response) {
+ if(typeof underlayRenderer === 'object') {
+ underlayRenderer.getModel().setFlowPath(response);
+ }
+ if(response.nodes <=0 || response.links <= 0){
+ showInfoWindow("Cannot Trace the path for the selected flow.", "Info");
+ if(null !== underlayRenderer && typeof underlayRenderer === "object"){
+ underlayRenderer.getView().resetTopology(false);
+ }
+ return;
+ }
+ if(typeof underlayRenderer == 'object') {
+ underlayRenderer.getView().highlightPath(response, {data: postData});
+ }
+ if(typeof response != 'string')
+ $('html,body').animate({scrollTop:0}, 500);
+ }).fail(function(error,status) {
+ if(typeof underlayRenderer == 'object') {
+ underlayRenderer.getView().resetTopology(false);
+ }
+ if(status == 'timeout') {
+ showInfoWindow('Timeout in fetching details','Error');
+ } else if (status != 'success') {
+ showInfoWindow('Error in fetching details','Error');
+ }
+ }).always(function(ajaxObj,status) {
+ $(progressBar).hide();
+ });
+}
diff --git a/webroot/monitor/infra/vrouter/ui/js/monitor_infra_vrouter_flows.js b/webroot/monitor/infra/vrouter/ui/js/monitor_infra_vrouter_flows.js
index 209ae7a7c..ea8392db8 100644
--- a/webroot/monitor/infra/vrouter/ui/js/monitor_infra_vrouter_flows.js
+++ b/webroot/monitor/infra/vrouter/ui/js/monitor_infra_vrouter_flows.js
@@ -425,7 +425,7 @@ monitorInfraComputeFlowsClass = (function() {
if(isAllPrevFirstTimeClicked) {
//we need to do this because when we click the prev for the first time the stack would contain the next uuid as well.
//We need to pop out the uuids 3 times to get the prev uuid.
- flowKeyStack.pop();
+ //flowKeyStack.pop();
isAllPrevFirstTimeClicked = false;
}
flowKeyStack.pop();//need to pop twice to get the prev last flowkey