diff --git a/webroot/config/physicaldevices/physicalinterfaces/api/parseURL.xml b/webroot/config/physicaldevices/physicalinterfaces/api/parseURL.xml new file mode 100644 index 000000000..c9dc0b644 --- /dev/null +++ b/webroot/config/physicaldevices/physicalinterfaces/api/parseURL.xml @@ -0,0 +1,54 @@ + + + + parseURLReq + process.mainModule.exports["corePath"] + '/src/serverroot/common/parseURLRequire' + + + physicalinterfacesconfigapi + ./physicalinterfacesconfig.api + + + + + /api/tenants/config/physical-interfaces/:pRouterId + get + physicalinterfacesconfig + physicalinterfacesconfigapi.getPhysicalInterfaces + + + /api/tenants/config/physical-interfaces/:pRouterId/:infType + post + physicalinterfacesconfig + physicalinterfacesconfigapi.createPhysicalInterfaces + + + /api/tenants/config/physical-interface/:pRouterId/:infType/:pInterfaceId + put + physicalinterfacesconfig + physicalinterfacesconfigapi.updatePhysicalInterfaces + + + /api/tenants/config/physical-interface/:pRouterId/:infType/:pInterfaceId + delete + physicalinterfacesconfig + physicalinterfacesconfigapi.deletePhysicalInterfaces + + + /api/tenants/config/virtual-network-internals/:id + get + physicalinterfacesconfig + physicalinterfacesconfigapi.getVirtualNetworkInternals + + \ No newline at end of file diff --git a/webroot/config/physicaldevices/physicalinterfaces/api/physicalinterfacesconfig.api.js b/webroot/config/physicaldevices/physicalinterfaces/api/physicalinterfacesconfig.api.js new file mode 100644 index 000000000..19dba63f9 --- /dev/null +++ b/webroot/config/physicaldevices/physicalinterfaces/api/physicalinterfacesconfig.api.js @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + + /** + * @quotasconfig.api.js + * - Handlers for project quotas + * - Interfaces with config api server + */ +var rest = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/rest.api'); +var async = require('async'); +var quotasconfigapi = module.exports; +var logutils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/log.utils'); +var commonUtils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/common.utils'); +var config = require(process.mainModule.exports["corePath"] + + '/config/config.global.js'); +var messages = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/messages'); +var global = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/global'); +var appErrors = require(process.mainModule.exports["corePath"] + + '/src/serverroot/errors/app.errors'); +var util = require('util'); +var url = require('url'); +var jsonPath = require('JSONPath').eval; +var configApiServer = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/configServer.api'); +var async = require('async'); + +/** + * @getPhysicalInterfaces + * public function + * 1. URL /api/tenants/config/physical-interfaces/:pRouterId + * 2. Gets physical interfaces from config api server + */ +function getPhysicalInterfaces (request, response, appData) +{ + var physicalRouterID = validateQueryParam(request, 'pRouterId'); + configApiServer.apiGet('/physical-router/' + physicalRouterID, appData, + function(error, data) { + getPhysicalInterfacesDetails(error, data, response, appData); + }); +} + +function getPhysicalInterfacesDetails(error, data, response, appData) +{ + var reqUrl = null; + var dataObjArr = []; + var i = 0, pInterfacesLength = 0; + + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + if(data && data['physical-router'] != null) { + if(data['physical-router']['physical_interfaces'] && data['physical-router']['physical_interfaces'].length > 0) { + pInterfacesLength = data['physical-router']['physical_interfaces'].length; + for(i = 0; i < pInterfacesLength; i++) { + var pInterface = data['physical-router']['physical_interfaces'][i]; + reqUrl = '/physical-interface/' + pInterface['uuid']; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + } + var lRootInterfaces = data['physical-router']['logical_interfaces']; + if(lRootInterfaces != null && lRootInterfaces.length > 0) { + for(var i = 0; i < lRootInterfaces.length; i++) { + var lRootInterface = lRootInterfaces[i]; + reqUrl = '/logical-interface/' + lRootInterface['uuid']; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + + } + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, true), + function(error, results) { + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + if(results.length > 0) { + var lInfDataObjArr = []; + var lInfReqUrl = null; + for(var i = 0; i < results.length; i++) { + var pInterface = results[i]['physical-interface']; + if(pInterface != null && pInterface['logical_interfaces'] && pInterface['logical_interfaces'].length > 0) { + var lInterfaces = pInterface['logical_interfaces'] + for(var j = 0; j < lInterfaces.length; j++) { + var lInterface = lInterfaces[j]; + lInfReqUrl = '/logical-interface/' + lInterface['uuid']; + commonUtils.createReqObj(lInfDataObjArr, lInfReqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + + } + var lInf = results[i]['logical-interface']; + if(lInf != null) { + lInfReqUrl = '/logical-interface/' + lInf['uuid']; + commonUtils.createReqObj(lInfDataObjArr, lInfReqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + } + if(lInfDataObjArr.length > 0) { + async.map(lInfDataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, true), + function(err,lInfDetails){ + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + if(lInfDetails.length > 0) { + var vmiList = []; + for(var j = 0; j < lInfDetails.length; j++) { + var lInterface = lInfDetails[j]['logical-interface']; + if('virtual_machine_interface_refs' in lInterface) { + vmiList.push({li_uuid : lInterface.uuid, uuid : lInterface['virtual_machine_interface_refs'][0].uuid}); + } + } + if(vmiList.length > 0) { + processVirtualMachineInterfaceDetails(response, appData, vmiList, function(vmiData) { + if(vmiData != null && vmiData.length > 0) { + var vmiListLen = vmiList.length; + for(var i = 0; i < vmiListLen; i++) { + vmiList[i]['vmi_details'] = vmiData[i]; + } + for(var j = 0; j < lInfDetails.length; j++) { + var lInterface = lInfDetails[j]['logical-interface']; + for(var k = 0; k < vmiList.length; k++) { + if(vmiList[k].li_uuid === lInterface.uuid) { + lInterface['vmi_details'] = vmiList[k]['vmi_details']; + } + } + } + } + + //map logical interfaces to corresponding physical interface + if(lInfDetails.length > 0) { + for(var i = 0; i < results.length; i++) { + var pInterface = results[i]['physical-interface']; + var lInf = results[i]['logical-interface']; + if(pInterface != null) { + pInterface['logical_interfaces'] = []; + } + for(var j = 0; j < lInfDetails.length; j++) { + var lInterface = lInfDetails[j]['logical-interface']; + if(pInterface != null && (pInterface['uuid'] === lInterface['parent_uuid'])) { + pInterface['logical_interfaces'].push(lInfDetails[j]); + } + if(lInf != null) { + if(lInf['uuid'] == lInterface['uuid']) { + results[i]['logical-interface'] = lInterface; + } + } + } + } + } + commonUtils.handleJSONResponse(error, response, results); + }); + } else { + //map logical interfaces to corresponding physical interface + if(lInfDetails.length > 0) { + for(var i = 0; i < results.length; i++) { + var pInterface = results[i]['physical-interface']; + if(pInterface != null) { + pInterface['logical_interfaces'] = []; + for(var j = 0; j < lInfDetails.length; j++) { + var lInterface = lInfDetails[j]['logical-interface']; + if(pInterface['uuid'] === lInterface['parent_uuid']) { + pInterface['logical_interfaces'].push(lInfDetails[j]); + } + } + } + } + } + commonUtils.handleJSONResponse(error, response, results); + } + } + } + ) + } else { + commonUtils.handleJSONResponse(error, response, results); + } + } else { + commonUtils.handleJSONResponse(error, response, null); + } + } + ) + } else { + commonUtils.handleJSONResponse(error, response, null); + } +} + +/** + * @createPhysicalInterfaces + * public function + * 1. URL /api/tenants/config/physical-interfaces/:pRouterId/:infType + * 2. creats a physical interface in config api server + */ +function createPhysicalInterfaces (request, response, appData) +{ + var postData = request.body; + var url = getInterfaceUrl(request, 'create'); + updateVMIDetails(request, appData, postData, function() { + configApiServer.apiPost(url, postData, appData, + function(error, data) { + if(error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalInterfaces(request, response, appData); + }); + }); +} + +/** + * @updatePhysicalInterfaces + * public function + * 1. URL /api/tenants/config/physical-interface/:pRouterId/:infType/:pInterfaceId + * 2. updates a physical interface in config api server + */ +function updatePhysicalInterfaces (request, response, appData) +{ + var pInterfaceId = validateQueryParam(request,'pInterfaceId'); + var url = getInterfaceUrl(request); + var postData = request.body; + updateVMIDetails(request, appData, postData, function() { + configApiServer.apiPut(url + pInterfaceId, postData, appData, + function(error, data) { + if(error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalInterfaces(request, response, appData); + }); + }); +} + +/** + * @deletePhysicalInterfaces + * public function + * 1. URL /api/tenants/config/physical-interface/:pRouterId/:infType/:pInterfaceId + * 2. deletes a physical interface in config api server + */ +function deletePhysicalInterfaces (request, response, appData) +{ + var pInterfaceId = validateQueryParam(request,'pInterfaceId'); + var url = getInterfaceUrl(request); + var postData = request.body; + configApiServer.apiDelete(url + pInterfaceId, appData, + function(error, data) { + if(error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalInterfaces(request, response, appData); + }); +} + +function validateQueryParam (request, key) +{ + var paramValue = null; + if (!(paramValue = request.param(key).toString())) { + error = new appErrors.RESTServerError('Add Virtual Router id'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + return paramValue; +} + +function getInterfaceUrl(request, operation) { + var infUrl = ''; + var infType = validateQueryParam(request, 'infType'); + if(infType === 'Physical') { + infUrl = operation === 'create' ? '/physical-interfaces' : '/physical-interface/'; + } else if(infType === 'Logical') { + infUrl = operation === 'create' ? '/logical-interfaces' : '/logical-interface/'; + } + return infUrl; +} + +/** + * @getVirtualNetworkInternals + * public function + * 1. URL /api/tenants/config/virtual-network-internals/:id + * 2. Gets physical interfaces from config api server + */ +function getVirtualNetworkInternals (request, response, appData) +{ + var vnID = validateQueryParam(request, 'id'); + configApiServer.apiGet('/virtual-network/' + vnID, appData, + function(error, data) { + if(error || data == null || data['virtual-network'] == null || data['virtual-network']['virtual_machine_interface_back_refs'] == null) { + commonUtils.handleJSONResponse(error, response, null); + } else { + processVirtualMachineInterfaceDetails(response, appData, data['virtual-network']['virtual_machine_interface_back_refs']); + } + }); +} + +function processVirtualMachineInterfaceDetails(response, appData, result, callback) +{ + var dataObjArr = []; + var resultJSON = []; + var tempVMIResourceObj = []; + var vmiBackRefs = result; + var vmiCnt = vmiBackRefs.length; + for(var i = 0; i < vmiCnt; i++) { + var vmiUrl = '/virtual-machine-interface/' + vmiBackRefs[i].uuid; + commonUtils.createReqObj(dataObjArr, vmiUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, true), + function(error, data) { + if ((null != error) || (null == data) || (!data.length)) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + dataObjArr = []; + vmiCnt = data.length; + for(var j = 0; j < vmiCnt; j++) { + if ((null == data[j]) || (null == data[j]['virtual-machine-interface'])) { + continue; + } + var vmi = data[j]['virtual-machine-interface']; + tempVMIResourceObj.push({"mac": vmi + ['virtual_machine_interface_mac_addresses']['mac_address'], "owner" : vmi['virtual_machine_interface_device_owner'], + "instance-ip": vmi['instance_ip_back_refs'], "fq_name": vmi['fq_name'], "vn_refs" : vmi['virtual_network_refs']}); + var instIPBackRefs = vmi['instance_ip_back_refs']; + //var instIPBackRefsCnt = instIPBackRefsCntinstIPBackRefs.length; + if(instIPBackRefs != null && instIPBackRefs.length > 0) { + for (var k = 0; k < instIPBackRefs.length ; k++) { + var instIPUrl = '/instance-ip/' + instIPBackRefs[k]['uuid']; + commonUtils.createReqObj(dataObjArr, instIPUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + } + } + if(dataObjArr.length > 0) { + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, true), + function(error, data) { + if ((null != error) || (null == data) || (!data.length)) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + var instIPDataCnt = data.length; + var tempVMIResourceObjCnt = tempVMIResourceObj.length; + var total = 0; + for (var i = 0; i < tempVMIResourceObjCnt; i++) { + if(tempVMIResourceObj[i]['instance-ip'] != null && tempVMIResourceObj[i]['instance-ip'].length > 0) { + var instIpCnt = tempVMIResourceObj[i]['instance-ip'].length; + var tempInstIPData = data.slice(total, total + instIpCnt); + total += instIpCnt; + var ipAddrs = jsonPath(tempInstIPData, "$..instance_ip_address"); + if(tempVMIResourceObj[i]['owner'] == null || tempVMIResourceObj[i]['owner'] == "") { + resultJSON.push({"mac": tempVMIResourceObj[i]['mac'], "ip": ipAddrs, + "vmi_fq_name": tempVMIResourceObj[i]['fq_name'], "vn_refs" : tempVMIResourceObj[i]["vn_refs"]}); + } + } else { + resultJSON.push({"mac": tempVMIResourceObj[i]['mac'], "ip": [], + "vmi_fq_name": tempVMIResourceObj[i]['fq_name'], "vn_refs" : tempVMIResourceObj[i]["vn_refs"]}); + } + } + if(callback != null) { + callback(resultJSON); + } else { + commonUtils.handleJSONResponse(null, response, resultJSON); + } + }); + } else { + if(tempVMIResourceObj[i]['owner'] == null || tempVMIResourceObj[i]['owner'] == "") { + resultJSON.push({"mac": tempVMIResourceObj[i]['mac'], "ip": [], + "vmi_fq_name": tempVMIResourceObj[i]['fq_name'], "vn_refs" : tempVMIResourceObj[i]["vn_refs"]}); + } + if(callback != null) { + callback(resultJSON); + } else { + commonUtils.handleJSONResponse(null, response, resultJSON); + } + } + } + ); +} + +function updateVMIDetails(request, appData, postData, callback) { + var infType = validateQueryParam(request, 'infType'); + if(infType === "Logical") { + var vmiData = postData['logical-interface']['virtual_machine_interface_refs']; + var vmiID = vmiData != null && vmiData.length > 0 ? vmiData[0].to[2] : null; + if(vmiID != null) { + configApiServer.apiGet('/virtual-machine-interface/' + vmiID, appData, + function(error, data) { + if(data != null && data['virtual-machine-interface'] != null && data['virtual-machine-interface']['logical_interface_back_refs'] != null) { + var liID = data['virtual-machine-interface']['logical_interface_back_refs'][0].uuid; + configApiServer.apiGet('/logical-interface/' + liID, appData, function(err, liData) { + liData['logical-interface']['virtual_machine_interface_refs'] =[]; + configApiServer.apiPut('/logical-interface/' + liID, liData, appData, function(error, result) { + callback(); + }); + }); + } else { + callback(); + } + }); + } else { + callback(); + } + } else { + callback(); + } +} + + /* List all public function here */ +exports.getPhysicalInterfaces = getPhysicalInterfaces; +exports.createPhysicalInterfaces = createPhysicalInterfaces; +exports.updatePhysicalInterfaces = updatePhysicalInterfaces; +exports.deletePhysicalInterfaces = deletePhysicalInterfaces; +exports.getVirtualNetworkInternals = getVirtualNetworkInternals; diff --git a/webroot/config/physicaldevices/physicalinterfaces/ui/js/physicalinterfaces_config.js b/webroot/config/physicaldevices/physicalinterfaces/ui/js/physicalinterfaces_config.js new file mode 100644 index 000000000..090c5a489 --- /dev/null +++ b/webroot/config/physicaldevices/physicalinterfaces/ui/js/physicalinterfaces_config.js @@ -0,0 +1,1008 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + +physicalInterfacesConfigObj = new physicalInterfacesConfig(); +function physicalInterfacesConfig() { + //Variable Definations + var gridPhysicalInterfaces; + var currentUUID; + var dsSrcDest = []; + var doubleCreation = false; + var interfaceDelimiters = []; + var vmiDetails = null; + var flow = null; + //Method Definations + this.load = load; + this.destroy = destroy; + + function load() { + var configTemplate = Handlebars.compile($("#physicalinterfaces-config-template").html()); + $(contentContainer).html(''); + $(contentContainer).html(configTemplate); + init(); + } + + function init() { + initComponents(); + initActions(); + fetchPhysicalRouters(); + fetchVirtualNetworks(); + fetchConfigurations(); + } + + function initComponents() { + //initializing the virtual routers Grid + $("#gridPhysicalInterfaces").contrailGrid({ + header : { + title: { + text : 'Interfaces', + //cssClass : 'blue', + //icon : 'icon-list', + //iconCssClass : 'blue' + }, + customControls: ['', + '', + 'Router:
',] + }, + columnHeader : { + columns : [ + { + id : 'name', + field : 'name', + name : 'Name' + }, + { + id : 'type', + field : 'type', + name : 'Type' + }, + { + id : 'parent', + field : 'parent', + name : 'Parent' + }, + { + id : 'vlan', + field : 'vlan', + name : 'VLAN' + }, + { + id : 'server', + field : 'server', + name : 'Server' + }] + + }, + body : { + options : { + checkboxSelectable: { + onNothingChecked: function(e){ + $('#btnDeletePhysicalInterface').addClass('disabled-link'); + }, + onSomethingChecked: function(e){ + $('#btnDeletePhysicalInterface').removeClass('disabled-link'); + } + }, + forceFitColumns: true, + actionCell: [ + { + title: 'Edit', + iconClass: 'icon-edit', + onClick: function(rowIndex){ + physicalInterfaceEditWindow(rowIndex); + } + }, + { + title: 'Delete', + iconClass: 'icon-trash', + onClick: function(rowIndex){ + showPhysicalInterfaceDelWindow(rowIndex); + } + } + ], + detail : { + template : $("#gridPhysicalInterfacesDetailTemplate").html() + } + }, + dataSource : { + data : [] + }, + statusMessages: { + loading: { + text: 'Loading Interfaces..' + }, + empty: { + text: 'No Interfaces.' + }, + errorGettingData: { + type: 'error', + iconClasses: 'icon-warning', + text: 'Error in getting Interfaces.' + } + } + } + }); + gridPhysicalInterfaces = $("#gridPhysicalInterfaces").data('contrailGrid'); + + $('#ddPhysicalRouters').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + change:onPhysicalRouterSelChange + }); + + $('#ddType').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + change:onTypeSelChange + }); + + var ddType = $('#ddType').data('contrailDropdown'); + ddType.setData([{text : 'Physical', value : 'physical'},{text : 'Logical', value : 'logical'}]); + ddType.value('logical') + + $('#ddParent').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + minimumResultsForSearch : 1, + query : select2Query + }) + .on('select2-open', function() { + loadSelect2OpenActions(); + }); + + $('#ddLIType').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + change:onLITypeChange + }); + + var ddLIType = $('#ddLIType').data('contrailDropdown'); + ddLIType.setData([{text : 'L2', value : 'l2'}, {text : 'L3', value : 'l3'}]); + ddLIType.value('l2'); + + $('#ddVN').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + change:onVNSelChange, + minimumResultsForSearch : 1 + }); + + // $('#ddVMI').contrailDropdown({ + // dataTextField:'text', + // dataValueField:'value', + // minimumResultsForSearch : 1 + // }); + + $('#ddVMI').contrailCombobox({ + dataTextField:'text', + dataValueField:'value', + change : onVMISelChanges, + placeholder : 'Enter or Select a Server' + }); + + //initializing add record window + $('#addPhysicalInterfaceWindow').modal({backdrop:'static',keyboard:false,show:false}); + $('#addPhysicalInterfaceWindow').find(".modal-header-title").text('Add Interface'); + + //initializing delete record window + $('#confirmMainDelete').modal({backdrop:'static',keyboard:false,show:false}); + $('#confirmMainDelete').find(".modal-header-title").text('Confirm'); + collapseElement('#vmSection','#infWidget'); + $('#ddParent').data('contrailDropdown').enable(false); + } + + function onPhysicalRouterSelChange(e) { + currentUUID = e.added.value; + fetchData(); + } + + function onTypeSelChange(e) { + var inf = e.added.value; + if(inf === "logical") { + // if($('#infWidget').hasClass('collapsed')) { + // collapseElement('#vmSection', '#infWidget'); + // } + $('#vmSection').removeClass('hide').addClass('show'); + $('#ddParent').data('contrailDropdown').enable(true); + } else { + $('#vmSection').removeClass('show').addClass('hide'); + $('#ddParent').data('contrailDropdown').value(dsSrcDest[0].children[1].value); + $('#ddParent').data('contrailDropdown').enable(false); + } + } + + function onVNSelChange(e) { + var id = e.added.value; + flow = null; + fetchVirtualNetworkInternals(id); + } + + function onVMISelChanges(e) { + var ipObj = $('#ddVMI').data('contrailCombobox').getSelectedItem(); + if(typeof ipObj === 'object') { + $('#txtVMI').val(ipObj.ip); + $('#txtVMI').attr('disabled','disabled'); + } else { + $('#txtVMI').val(''); + $('#txtVMI').removeAttr('disabled'); + } + } + + function onLITypeChange(e) { + var id = e.added.value; + if(id === 'l2') { + $('#l3SubnetPanel').removeClass('show').addClass('hide'); + $('#l2TypePanel').removeClass('hide').addClass('show'); + $('#l2ServerPanel').removeClass('hide').addClass('show'); + } else if(id === 'l3') { + $('#l2TypePanel').removeClass('show').addClass('hide'); + $('#l2ServerPanel').removeClass('show').addClass('hide'); + $('#l3SubnetPanel').removeClass('hide').addClass('show'); + } + } + + function initActions() { + $('#btnCreatePhysicalInterface').click(function() { + $('#addPhysicalInterfaceWindow').find(".modal-header-title").text('Add Interface'); + populateCreateEditWindow('create'); + }); + + $('#btnAddPhysicalInterfaceOk').click(function() { + if(validate()) { + $('#addPhysicalInterfaceWindow').modal('hide'); + var isVMICreate = !$('#txtVMI').is('[disabled]'); + if(isVMICreate) { + var postObject; + if($('#txtVMI').val() != '') { + postObject = {"vnUUID": $('#ddVN').data('contrailDropdown').value(), "fixedIPs":[$('#txtVMI').val()], "macAddress":$('#ddVMI').data('contrailCombobox').value()}; + } else { + postObject = {"vnUUID": $('#ddVN').data('contrailDropdown').value(), "macAddress":$('#ddVMI').data('contrailCombobox').value()}; + } + doAjaxCall('/api/tenants/config/create-port', 'POST', JSON.stringify(postObject), 'successHandlerForVMICreation', 'failureHandlerForVMICreation', null, null); + } else { + createUpdatePhysicalInterface(); + } + } + }); + window.successHandlerForVMICreation = function(result) { + if(result != null) { + vmiDetails = result; + createUpdatePhysicalInterface(); + } + } + + window.failureHandlerForVMICreation = function(error) { + + } + + $('#btnDeletePhysicalInterface').click(function(){ + $('#confirmMainDelete').modal('show'); + }); + $('#btnCnfDelMainPopupOK').click(function(args){ + var selected_rows = gridPhysicalInterfaces.getCheckedRows(); + $('#confirmMainDelete').modal("hide"); + deletePhysicalInterface(selected_rows); + }); + $('#txtPhysicalInterfaceName').bind('blur', function(e) { + if($('#ddType').data('contrailDropdown').value() === "logical") { + var infName = $('#txtPhysicalInterfaceName').val().trim(); + var delimiter; + for(var i = 0; i < interfaceDelimiters.length; i++) { + if(infName.indexOf(interfaceDelimiters[i]) !== -1) { + delimiter = interfaceDelimiters[i]; + break; + } + } + var infNameArry = infName.split(delimiter); + var physicalInfName = ''; + if(infNameArry.length === 2) { + physicalInfName = infNameArry[0]; + verifySetSelectedItem(physicalInfName, $('#ddParent').data('contrailDropdown')); + } else { + $('#ddParent').data('contrailDropdown').value(dsSrcDest[0].children[1].value); + } + } + }); + $('input[type=radio][name=l2Type]').on('change', function(e){ + if(e.target.value === 'l2Server') { + $('#lblServer').text('Server'); + } else if(e.target.value === 'l2Gateway') { + $('#lblServer').text('L2 Gateway'); + } + }); + } + + window.showPhysicalInterfaceDelWindow = function(index) { + $.contrailBootstrapModal ( + { + id: 'confirmRemove', + title: 'Remove', + body: '
Confirm Removing record
', + footer: [ + { + title: 'Cancel', + onclick: 'close', + }, + { + id: 'btnRemovePopupOK', + title: 'Confirm', + onclick: function(){ + var selected_row = gridPhysicalInterfaces._dataView.getItem(index); + deletePhysicalInterface([selected_row]); + $('#confirmRemove').modal('hide'); + }, + className: 'btn-primary' + }] + }); + } + + function deletePhysicalInterface(selected_rows) { + $('#btnDeletePhysicalInterface').addClass('disabled-link'); + if(selected_rows && selected_rows.length > 0){ + var deleteAjaxs = []; + for(var i = 0;i < selected_rows.length;i++){ + var sel_row_data = selected_rows[i]; + deleteAjaxs[i] = $.ajax({ + url:'/api/tenants/config/physical-interface/' + currentUUID + '/' + sel_row_data['type'] + '/' + sel_row_data['uuid'], + type:'DELETE' + }); + } + $.when.apply($,deleteAjaxs).then( + function(response){ + //all success + fetchData(); + }, + function(){ + //if at least one delete operation fails + var r = arguments; + showInfoWindow(r[0].responseText,r[2]); + fetchData(); + } + ); + } + } + + window.physicalInterfaceEditWindow = function(index) { + gblSelRow = gridPhysicalInterfaces._dataView.getItem(index); + $('#addPhysicalInterfaceWindow').find(".modal-header-title").text('Edit Interface'); + populateCreateEditWindow('edit'); + } + + function populateCreateEditWindow(m) { + mode = m; + clearCreateEditWindow(); + if(mode === 'edit') { + $('#txtPhysicalInterfaceName').val(gblSelRow.name); + $('#txtPhysicalInterfaceName').attr('disabled','disabled'); + $('#ddParent').data('contrailDropdown').enable(true); + $('#ddParent').data('contrailDropdown').text(gblSelRow.parent); + $('#ddParent').data('contrailDropdown').enable(false); + $('#ddType').data('contrailDropdown').text(gblSelRow.type); + $('#ddType').data('contrailDropdown').enable(false); + if(gblSelRow.type === 'Logical') { + flow = 'edit'; + $('#vmSection').removeClass('hide').addClass('show'); + if(gblSelRow.vlan != "-") { + $('#txtVlan').val(gblSelRow.vlan); + } + if(gblSelRow.vn != '-') { + var ddVN = $('#ddVN').data('contrailDropdown'); + ddVN.value(getCurrentVirtualNetworkId(gblSelRow.vn)); + fetchVirtualNetworkInternals(ddVN.value()); + } + if(gblSelRow.li_type != '-') { + $('#ddLIType').data('contrailDropdown').text(gblSelRow.li_type); + } + } else { + $('#vmSection').removeClass('show').addClass('hide'); + } + } + $('#addPhysicalInterfaceWindow').modal('show'); + } + + function getCurrentVirtualNetworkId(name) { + var data = $('#ddVN').data('contrailDropdown').getAllData(); + for(var i = 0; i < data.length; i++) { + if(data[i].text.indexOf(name) !== -1) { + return data[i].value; + } + } + return ''; + } + + function getCurrentVMIId(name) { + var data = $('#ddVMI').data('contrailCombobox').getAllData(); + for(var i = 0; i < data.length; i++) { + if(data[i].text.indexOf(name) !== -1) { + return data[i].id; + } + } + return ''; + } + + function createUpdatePhysicalInterface() { + var methodType = 'POST'; + var infType = $('#ddType').data('contrailDropdown').text(); + var url = '/api/tenants/config/physical-interfaces/' + currentUUID + '/' + infType; + if(mode === 'edit') { + methodType = 'PUT'; + url = '/api/tenants/config/physical-interface/' + currentUUID + '/' + gblSelRow.type + '/' + gblSelRow.uuid + } + var type = $("#ddType").data('contrailDropdown').value(); + var name = $("#txtPhysicalInterfaceName").val(); + var vlan = $("#txtVlan").val() === '' ? 0 : parseInt($("#txtVlan").val()); + var pRouterDD = $('#ddPhysicalRouters').data('contrailDropdown'); + var postObject = {}; + gridPhysicalInterfaces._dataView.setData([]); + gridPhysicalInterfaces.showGridMessage('loading'); + if(infType === 'Physical') { + postObject["physical-interface"] = {}; + postObject["physical-interface"]["fq_name"] = ["default-global-system-config", pRouterDD.text(), name]; + postObject["physical-interface"]["parent_type"] = "physical-router"; + postObject["physical-interface"]["name"] = name; + } else { + var liType = $('#ddLIType').data('contrailDropdown').value(); + var parent = $('#ddParent').data('contrailDropdown'); + //var ddVMIValue = $('#ddVMI').data('contrailDropdown').value(); + var ddVMIValue = getCurrentVMIId($('#ddVMI').data('contrailCombobox').text()); + var vmiData = 'none'; + if(vmiDetails != null) { + vmiData = vmiDetails['virtual-machine-interface']['fq_name']; + } else { + vmiData = ddVMIValue === 'none' || ddVMIValue == 'empty' || ddVMIValue == '' ? 'none' : JSON.parse(ddVMIValue); + } + if(pRouterDD.value() === parent.value()) { + postObject["logical-interface"] = {}; + postObject["logical-interface"]["fq_name"] = ["default-global-system-config", pRouterDD.text(), name]; + postObject["logical-interface"]["parent_type"] = "physical-router"; + postObject["logical-interface"]["name"] = name; + postObject["logical-interface"]["logical_interface_vlan_tag"] = vlan; + if(vmiData != 'none') { + postObject["logical-interface"]['virtual_machine_interface_refs'] = [{"to" : [vmiData[0], vmiData[1], vmiData[2]]}]; + } else { + postObject["logical-interface"] ['virtual_machine_interface_refs'] = []; + } + postObject["logical-interface"]["logical_interface_type"] = liType; + } else { + if(!isItemExists(parent.text(), dsSrcDest)) { + doubleCreation = true; + postObject["physical-interface"] = {}; + postObject["physical-interface"]["fq_name"] = ["default-global-system-config", pRouterDD.text(), parent.text()]; + postObject["physical-interface"]["parent_type"] = "physical-router"; + postObject["physical-interface"]["name"] = parent.text(); + url = '/api/tenants/config/physical-interfaces/' + currentUUID + '/Physical'; + } else { + doubleCreation = false; + postObject["logical-interface"] = {}; + postObject["logical-interface"]["fq_name"] = ["default-global-system-config", pRouterDD.text(), parent.text() , name]; + postObject["logical-interface"]["parent_type"] = "physical-interface"; + postObject["logical-interface"]["parent_uuid"] = parent.value(); + postObject["logical-interface"]["name"] = name; + postObject["logical-interface"]["logical_interface_vlan_tag"] = vlan; + if(vmiData != 'none') { + postObject["logical-interface"]['virtual_machine_interface_refs'] = [{"to" : [vmiData[0], vmiData[1], vmiData[2]]}]; + } else { + postObject["logical-interface"] ['virtual_machine_interface_refs'] = []; + } + postObject["logical-interface"]["logical_interface_type"] = liType; + } + } + } + doAjaxCall(url, methodType, JSON.stringify(postObject), 'successHandlerForPhysicalInterfaces', 'failureHandlerForPhysicalInterfaces', null, null); + } + + function clearCreateEditWindow() { + $('#ddType').data('contrailDropdown').value('logical'); + $('#txtPhysicalInterfaceName').removeAttr('disabled'); + $('#txtPhysicalInterfaceName').val(''); + $('#txtVlan').val(''); + var ddPhysicalRouters = $('#ddPhysicalRouters').data('contrailDropdown'); + $('#ddParent').data('contrailDropdown').value(ddPhysicalRouters.value()); + $('#vmSection').removeClass('hide').addClass('show'); + doubleCreation = false; + $('#ddParent').data('contrailDropdown').enable(true); + $('#ddType').data('contrailDropdown').enable(true); + $('#ddVN').data('contrailDropdown').value('none'); + // $('#ddVMI').data('contrailDropdown').value('none'); + $('#ddVMI').data('contrailCombobox').value('none'); + $('#ddLIType').data('contrailDropdown').value('l2'); + vmiDetails = null; + flow = null; + $('#txtVMI').val(''); + $('#txtVMI').attr('disabled', 'disabled'); + $('#l2Server').attr('checked','checked'); + $('#lblServer').text('Server'); + $('#l3SubnetPanel').removeClass('show').addClass('hide'); + $('#l2TypePanel').removeClass('hide').addClass('show'); + $('#l2ServerPanel').removeClass('hide').addClass('show'); + fetchVirtualNetworkInternals('none'); + } + + function fetchPhysicalRouters() { + //reading uuid from query string + var queryParams = window.location.href.split("&"); + if(queryParams != undefined && queryParams.length > 1 && queryParams[1].indexOf('=') != -1) { + currentUUID = queryParams[1].split('=')[1]; + } + doAjaxCall('/api/tenants/config/physical-routers-list','GET', null, 'successHandlerForPhysicalRouters', 'failureHandlerForPhysicalRouters', null, null); + } + window.successHandlerForPhysicalRouters = function(result) { + var pRoutersDS = []; + if(result && result['physical-routers'].length > 0) { + var physicalRouters = result['physical-routers']; + for(var i = 0; i < physicalRouters.length;i++) { + var physicalRouter = physicalRouters[i]; + pRoutersDS.push({text : physicalRouter.fq_name[1], value : physicalRouter.uuid}); + } + + } else { + pRoutersDS.push({text : 'No Physical Router found', value: 'Message'}); + } + var pRouterDD = $('#ddPhysicalRouters').data('contrailDropdown'); + pRouterDD.setData(pRoutersDS); + if(currentUUID) { + pRouterDD.value(currentUUID); + } else { + pRouterDD.value(pRoutersDS[0].value) + currentUUID = pRouterDD.value(); + } + fetchData(); + } + window.failureHandlerForPhysicalRouters = function(error) { + gridPhysicalInterfaces.showGridMessage('errorGettingData'); + } + + function fetchVirtualNetworks() { + doAjaxCall('/api/admin/config/get-data?type=virtual-network','GET', null, 'successHandlerForVN', 'failureHandlerForVN', null, null); + } + + window.successHandlerForVN = function(result) { + var vnDataSrc = [{text : 'None', value : 'none'}]; + if(result != null && result['data'] != null && result['data'].length > 0) { + var vns = result['data']; + for(var i = 0; i < vns.length; i++) { + var vn = vns[i]['virtual-network']; + var fqn = vn.fq_name; + var subnetStr = ''; + if('network_ipam_refs' in vn) { + var ipamRefs = vn['network_ipam_refs']; + for(var j = 0; j < ipamRefs.length; j++) { + if('subnet' in ipamRefs[j]) { + if(subnetStr === '') { + subnetStr = ipamRefs[j].subnet.ipam_subnet; + } else { + subnetStr += ', ' + ipamRefs[j].subnet.ipam_subnet; + } + } + } + } + var textVN = fqn[2] + " (" + fqn[0] + ":" + fqn[1] + ")"; + if(subnetStr != '') { + textVN += ' (' + subnetStr + ')'; + } + vnDataSrc.push({ text : textVN, value : vn.uuid}); + } + } else { + vnDataSrc.push({text : 'No Virtual Network found', value : 'empty'}); + } + var ddVN = $('#ddVN').data('contrailDropdown'); + ddVN.setData(vnDataSrc); + fetchVirtualNetworkInternals(ddVN.value()); + } + + window.failureHandlerForVN = function(error) { + var r = arguments; + showInfoWindow(r[0].responseText,r[2]) + } + + + function fetchVirtualNetworkInternals(id) { + if(id === 'empty' || id === '') { + //$('#ddVMI').data('contrailDropdown').setData([{text : 'No Server found', value : 'empty'}]); + $('#ddVMI').data('contrailCombobox').setData([{text : 'No Server found', value : 'empty'}]); + $('#ddVMI').data('contrailCombobox').value('empty'); + } else if(id === 'none') { + var vmiDataSrc = [{text : 'None', value : 'none'}]; + //$('#ddVMI').data('contrailDropdown').setData(vmiDataSrc); + $('#ddVMI').data('contrailCombobox').setData(vmiDataSrc); + $('#ddVMI').data('contrailCombobox').value('none'); + }else { + doAjaxCall('/api/tenants/config/virtual-network-internals/' + id,'GET', null, 'successHandlerForVNInternals', 'failureHandlerForVNInternals', null, null); + } + } + + window.successHandlerForVNInternals = function(result) { + if(result != null && result.length > 0) { + var vmiDataSrc = [{text : 'None', value : 'none'}]; + for(var i = 0; i < result.length; i++) { + var vmi = result[i]; + var txt = vmi.mac[0]; //+ ' (' + vmi.ip[0] + ')'; + vmiDataSrc.push({text : txt, value : JSON.stringify(vmi.vmi_fq_name), ip : vmi.ip[0]}); + } + $('#ddVMI').data('contrailCombobox').setData(vmiDataSrc); + if(flow === 'edit' && gblSelRow.server != '-') { + // $('#ddVMI').data('contrailDropdown').text(gblSelRow.server); + var vmiMac = gblSelRow.server.split('(')[0]; + $('#ddVMI').data('contrailCombobox').text(vmiMac); + $('#txtVMI').val(gblSelRow.vmi_ip); + $('#txtVMI').attr('disabled', 'disabled'); + } else { + // $('#ddVMI').data('contrailDropdown').value('none'); + $('#ddVMI').data('contrailCombobox').value('none'); + $('#txtVMI').val(''); + $('#txtVMI').attr('disabled', 'disabled'); + } + } else { + // $('#ddVMI').data('contrailDropdown').setData([{text : 'No Server found', value : 'empty'}]); + $('#ddVMI').data('contrailCombobox').setData([{text : 'No Server found', value : 'empty'}]); + $('#ddVMI').data('contrailCombobox').value('empty'); + + } + } + + window.failureHandlerForVNInternals = function(error){ + var r = arguments; + showInfoWindow(r[0].responseText,r[2]) + } + + function fetchConfigurations() { + doAjaxCall('/api/admin/webconfig/physicaldevices/interface_delimiters' ,'GET', null, 'successHandlerForConfigurations', 'failureHandlerForForConfigurations', null, null); + } + + window.successHandlerForConfigurations = function(result) { + if(result != null && result['interface_delimiters'] != null && result['interface_delimiters'].length > 0) { + interfaceDelimiters = result['interface_delimiters']; + } + } + + window.failureHandlerForForConfigurations = function(error) { + + } + + function fetchData() { + gridPhysicalInterfaces._dataView.setData([]); + gridPhysicalInterfaces.showGridMessage('loading'); + doAjaxCall('/api/tenants/config/physical-interfaces/' + currentUUID,'GET', null, 'successHandlerForPhysicalInterfaces', 'failureHandlerForPhysicalInterfaces', null, null); + } + + window.successHandlerForPhysicalInterfaces = function(result) { + var gridDS = []; + var mainDS = []; + var pRouterDS = []; + var pRouterDD = $('#ddPhysicalRouters').data('contrailDropdown'); + var ddParent = $('#ddParent').data('contrailDropdown'); + var pInterfaceDS = [{text : 'Enter or Select a Interface', value : 'dummy', disabled : true}]; + pRouterDS.push({text : 'Select the Router', value : 'dummy', disabled : true}, + {text : pRouterDD.text(), value : pRouterDD.value(), parent : 'physical_router'}); + if(result && result.length > 0) { + var pInterfaces = result; + for(var i = 0; i < pInterfaces.length;i++) { + var pInterface , infType; + var liDetails = {}; + if(pInterfaces[i]['physical-interface'] != null) { + pInterface = pInterfaces[i]['physical-interface']; + infType = "Physical"; + } else { + pInterface = pInterfaces[i]['logical-interface']; + infType = "Logical"; + liDetails = getLogicalInterfaceDetails(pInterface); + } + gridDS.push({ + uuid : pInterface.uuid, + name : pInterface.name, + type : infType, + parent : pInterface.fq_name[1], + vlan : liDetails.vlanTag != null ? liDetails.vlanTag : '-', + server : liDetails.vmiDetails != null ? liDetails.vmiDetails : '-', + vn : liDetails.vnRefs != null ? liDetails.vnRefs : '-', + li_type : liDetails.liType != null ? liDetails.liType : '-' , + vmi_ip : liDetails.vmiIP != null ? liDetails.vmiIP : '-' + }); + var lInterfaces = pInterfaces[i]['physical-interface'] ? pInterfaces[i]['physical-interface']['logical_interfaces'] : null; + var lInterfaceNames = ''; + var infDS = []; + if(lInterfaces != null && lInterfaces.length > 0) { + for(var j = 0; j < lInterfaces.length; j++) { + var lInterface = lInterfaces[j]['logical-interface']; + var lInterfaceName = lInterface.fq_name[3]; + if(lInterfaceNames === ''){ + lInterfaceNames = lInterfaceName; + } else { + lInterfaceNames += ',' + lInterfaceName; + } + liDetails = getLogicalInterfaceDetails(lInterface); + infDS.push({ + uuid : lInterface.uuid, + name : lInterface.name, + type : "Logical", + parent : lInterface.fq_name[2], + vlan : liDetails.vlanTag, + server : liDetails.vmiDetails, + vn : liDetails.vnRefs, + li_type : liDetails.liType, + vmi_ip : liDetails.vmiIP + }); + } + var currPhysicalInfRow = getCurrentPhysicalInfRow(gridDS, pInterface.uuid); + if(currPhysicalInfRow != '') { + currPhysicalInfRow['lInterfaces'] = lInterfaceNames; + } + gridDS = gridDS.concat(infDS); + } + } + + for(var i = 0; i < gridDS.length; i++) { + if(gridDS[i].type === 'Physical') { + pInterfaceDS.push({text : gridDS[i].name, value : gridDS[i].uuid, parent : 'physical_interface'}); + } + } + mainDS.push({text : 'Physical Router', id : 'physical_router', children : pRouterDS}, + {text : 'Physical Interface', id : 'physical_interface', children : pInterfaceDS}); + dsSrcDest = mainDS; + if(doubleCreation) { + createUpdatePhysicalInterface(); + } else { + //set parent drop down data here + ddParent.setData(mainDS); + } + } else { + mainDS.push({text : 'Physical Router', id : 'physical_router', children : pRouterDS}, + {text : 'Physical Interface', id : 'physical_interface', children : pInterfaceDS}); + dsSrcDest = mainDS; + ddParent.setData(mainDS); + ddParent.value(mainDS[0].children[0].value); + gridPhysicalInterfaces.showGridMessage("empty"); + } + gridPhysicalInterfaces._dataView.setData(gridDS); + } + + + function fetchVMIDetails(id) { + doAjaxCall('/api/tenants/config/virtual-machine-interface-details/' + id,'GET', null, 'successHandlerForVMIDetails', 'failureHandlerForVMIDetails', null, null); + } + + window.successHandlerForVMIDetails = function(result) { + + } + + window.failureHandlerForVMIDetails = function(error) { + } + + function getCurrentPhysicalInfRow(dataSrc,id) { + for(var i = 0; i < dataSrc.length; i++) { + if(dataSrc[i].uuid === id) { + return dataSrc[i]; + } + } + return ''; + } + + function getLogicalInterfaceDetails(inf) { + var vnRefs = '-'; + var vlanTag = inf['logical_interface_vlan_tag'] != null ? inf['logical_interface_vlan_tag'] : '-' ; + var liType = inf['logical_interface_type'] != null ? inf['logical_interface_type'] : '-' ; + var vmiIP ; + if(liType != '-') { + liType = liType === 'l2' ? 'L2' : 'L3'; + } + var vmiDetails = inf['vmi_details'] ? inf['vmi_details'].mac[0] +' ('+ inf['vmi_details'].ip[0] + ')' : '-'; + if(vmiDetails != '-') { + vmiIP = inf['vmi_details'].ip[0]; + vnRefs = inf['vmi_details']['vn_refs'] ? inf['vmi_details']['vn_refs'][0].to : '-'; + if(vnRefs != '-') { + vnRefs = vnRefs[2] + ' (' + vnRefs[0] + ':' + vnRefs[1] + ')'; + } + } + return { vlanTag : vlanTag, liType : liType, vmiDetails : vmiDetails, vnRefs : vnRefs, vmiIP : vmiIP}; + } + + window.failureHandlerForPhysicalInterfaces = function(error) { + //gridPhysicalInterfaces.showGridMessage("errorGettingData"); + fetchData(); + } + + function validate() { + var name = $('#txtPhysicalInterfaceName').val().trim(); + if(name === ""){ + showInfoWindow("Enter an Interface Name","Input required"); + return false; + } + if($('#txtVlan').val() != '') { + var vlan = parseInt($('#txtVlan').val().trim()); + if(isNaN(vlan) || vlan < 0 || vlan > 4094) { + showInfoWindow('Vlan ID should be in "0 - 4094" range', "Input required"); + return false; + } + } + return true; + } + + function destroy() { + var configTemplate = $("#physicalinterfaces-config-template"); + if(isSet(configTemplate)) { + configTemplate.remove(); + configTemplate = $(); + } + var configDetailTemplate = $("#gridPhysicalInterfacesDetailTemplate"); + if(isSet(configDetailTemplate)) { + configDetailTemplate.remove(); + configDetailTemplate = $(); + } + var ddPhysicalRouters = $("#ddPhysicalRouters").data("contrailDropdown"); + if(isSet(ddPhysicalRouters)) { + ddPhysicalRouters.destroy(); + ddPhysicalRouters = $(); + } + } + + function select2Query(query) { + //using predefined process method to make work select2 selection + var t = query.term,filtered = { results: [] }, process; + process = function(datum, collection) { + var group, attr; + datum = datum[0]; + if (datum.children) { + group = {}; + for (attr in datum) { + if (datum.hasOwnProperty(attr)) group[attr]=datum[attr]; + } + group.children=[]; + $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); }); + if (group.children.length || query.matcher(t, '', datum)) { + collection.push(group); + } + } else { + if (query.matcher(t, '', datum)) { + collection.push(datum); + } + } + }; + if(t != ""){ + $(dsSrcDest).each2(function(i, datum) { process(datum, filtered.results); }) + } + + var data = {results: []}; + var grpName = 'physical_interface';//getSelectedGroupName(); + if(query.term != undefined && query.term != "") { + data.results.push({ id : query.term, text : query.term, parent : 'physical_interface'}); + this.data = []; + $.extend(true, this.data, dsSrcDest); + for(var i = 0; i < this.data.length;i++) { + var children = [] ; + $.extend(true, children, this.data[i].children);; + for(var j = 0; j < children.length; j++) { + if(children[j].text.indexOf(query.term) == -1 && children[j].disabled != true) { + var newIndex = getIndexOf(this.data[i].children, children[j].value); + this.data[i].children.splice(newIndex, 1); + } + } + data.results.push(this.data[i]); + } + addNewTermDataSource(grpName, query.term, data.results); + } else{ + data.results = dsSrcDest; + } + query.callback(data); + //set focus for a searched item + setFocusSelectedItem(grpName, query.term, data.results); + + //hide inbuilt select2 search results for custom term + $('.select2-results > .select2-results-dept-0.select2-result-selectable').attr('style','display:none'); + + var subEleArry = $(".select2-result-sub"); + if(subEleArry && subEleArry.length > 0) { + $(subEleArry[0]).attr('style','max-height:150px;overflow:auto;'); + $(subEleArry[1]).attr('style','max-height:150px;overflow:auto;'); + $(subEleArry[2]).attr('style','max-height:150px;overflow:auto;'); + } + retainExpandedGroup(); + + if($(".select2-result-label") && $(".select2-result-label").length > 0) { + $('.select2-results>.select2-results-dept-0>.select2-result-label').attr('style','background-color:#E2E2E2;margin-top:2px;'); + $(".select2-result-label").on('click', function() { + if($(this).parent().hasClass('select2-disabled')) { + return; + } + $('.select2-result-sub').addClass('hide'); + $(this).parent().find('.select2-result-sub').removeClass('hide'); + }); + } + } + + function setFocusSelectedItem(grpName, term, data) { + for(var i = 0; i < data.length ; i++) { + if(data[i].text === grpName && data[i].children.length === 2) { + $($('div:contains('+ term +')').parent()).addClass('select2-highlighted'); + break; + } + } + } + + function retainExpandedGroup() { + var subEleArry = $(".select2-result-sub"); + if(subEleArry && subEleArry.length > 0) { + subEleArry.addClass('hide'); + var grpName = 'physical_interface'; + var subEle = $(subEleArry[1]); + switch(grpName) { + case 'physical_router' : + subEle = $(subEleArry[0]); + break; + case 'physical_interface' : + subEle = $(subEleArry[1]); + break; + } + subEle.removeClass('hide'); + } + } + + function addNewTermDataSource(grpName, term, data) { + var newItem = {id : term, text : term, parent : grpName}; + for(var i = 0; i < data.length ; i++) { + if(data[i].text === grpName && data[i].children.length === 1) { + data[i].children.push(newItem); + break; + } + } + } + + function getIndexOf(arry, txt) { + for(var i = 0; i < arry.length; i ++) { + if(arry[i].value === txt) { + return i; + } + } + return 0; + } + + function isItemExists(txt, data) { + var isThere = false; + for(var i = 0; i < data.length; i++) { + for(var j = 0; j < data[i].children.length; j++) { + if(txt === data[i].children[j].text) { + return true; + } + } + } + return isThere; + } + + function verifySetSelectedItem(selTxt, dropDown) { + if(!isItemExists(selTxt, dsSrcDest)) { + addNewItemMainDataSource(selTxt, dsSrcDest); + dropDown.setData(dsSrcDest); + dropDown.text(selTxt); + removeNewItemMainDataSource(selTxt); + } else { + dropDown.text(selTxt); + } + } + + function addNewItemMainDataSource(txt, data) { + var grpName = "physical_interface"; + var grpTxt = "Physical Interface" + for(var i = 0; i < data.length; i++) { + if(data[i].text === grpTxt) { + data[i].children.push({text : txt, value : txt, parent : grpName}); + break; + } + } + } + + function removeNewItemMainDataSource(txt) { + var grpName = "physical_interface"; + var grpTxt = "Physical Interface" + for(var i = 0; i < dsSrcDest.length; i++) { + if(dsSrcDest[i].text === grpTxt) { + var remItemIndex = getIndexOf(dsSrcDest[i].children, txt); + dsSrcDest[i].children.splice(remItemIndex, 1); + break; + } + } + } + + function loadSelect2OpenActions() { + $('.select2-results').attr('style','max-height:400px;'); + } + } \ No newline at end of file diff --git a/webroot/config/physicaldevices/physicalinterfaces/ui/views/physicalinterfaces_config.view b/webroot/config/physicaldevices/physicalinterfaces/ui/views/physicalinterfaces_config.view new file mode 100644 index 000000000..0a8dfb577 --- /dev/null +++ b/webroot/config/physicaldevices/physicalinterfaces/ui/views/physicalinterfaces_config.view @@ -0,0 +1,161 @@ + + \ No newline at end of file diff --git a/webroot/config/physicaldevices/physicalrouters/api/parseURL.xml b/webroot/config/physicaldevices/physicalrouters/api/parseURL.xml new file mode 100644 index 000000000..538a44be4 --- /dev/null +++ b/webroot/config/physicaldevices/physicalrouters/api/parseURL.xml @@ -0,0 +1,52 @@ + + + + parseURLReq + process.mainModule.exports["corePath"] + '/src/serverroot/common/parseURLRequire' + + + physicalroutersapi + ./physicalroutersconfig.api + + + + + /api/tenants/config/physical-routers-list + get + physicalroutersconfig + physicalroutersapi.getPhysicalRoutersList + + + /api/tenants/config/physical-routers + get + physicalroutersconfig + physicalroutersapi.getPhysicalRouters + + + /api/tenants/config/physical-routers + post + physicalroutersconfig + physicalroutersapi.createPhysicalRouters + + + /api/tenants/config/physical-router/:id + put + physicalroutersconfig + physicalroutersapi.updatePhysicalRouters + + + /api/tenants/config/physical-router/:id + delete + physicalroutersconfig + physicalroutersapi.deletePhysicalRouters + + + diff --git a/webroot/config/physicaldevices/physicalrouters/api/physicalroutersconfig.api.js b/webroot/config/physicaldevices/physicalrouters/api/physicalroutersconfig.api.js new file mode 100644 index 000000000..44c362392 --- /dev/null +++ b/webroot/config/physicaldevices/physicalrouters/api/physicalroutersconfig.api.js @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + + /** + * @physicalroutersconfig.api.js + * - Handlers for physical routers + * - Interfaces with config api server + */ +var rest = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/rest.api'); +var async = require('async'); +var quotasconfigapi = module.exports; +var logutils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/log.utils'); +var commonUtils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/common.utils'); +var config = require(process.mainModule.exports["corePath"] + + '/config/config.global.js'); +var messages = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/messages'); +var global = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/global'); +var appErrors = require(process.mainModule.exports["corePath"] + + '/src/serverroot/errors/app.errors'); +var util = require('util'); +var url = require('url'); +var configApiServer = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/configServer.api'); +var async = require('async'); + + +/** + * @listPolicysCb + * private function + * 1. Callback for getPhysicalRouters + * 2. Reads the response from config api server + * and sends it back to the client. + */ +function getPhysicalRoutersCb(error, physicalRoutersData, response) +{ + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + commonUtils.handleJSONResponse(error, response, physicalRoutersData); +} + +/** + * @getPhysicalRoutersList + * public function + * 1. URL /api/tenants/config/physical-routers + * 2. Gets physical routers from config api server + */ +function getPhysicalRoutersList (request, response, appData) +{ + configApiServer.apiGet('/physical-routers', appData, + function(error, data) { + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + commonUtils.handleJSONResponse(error, response, data); + } + ); +} + +/** + * @getPhysicalRouters + * public function + * 1. URL /api/tenants/config/physical-routers-details + * 2. Gets list of physical-routers from config api server + * 3. Calls getPhysicalRoutersCb that process data from config + * api server and sends back the http response. + */ +function getPhysicalRouters (request, response, appData) +{ + configApiServer.apiGet('/physical-routers', appData, + function(error, data) { + getPhysicalRoutersDetails(error, data, response, appData); + }); +} + +function getPhysicalRoutersDetails(error, data, response, appData) +{ + var reqUrl = null; + var dataObjArr = []; + var i = 0, pRoutersLength = 0; + + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + pRoutersLength = data['physical-routers'].length; + for(i = 0; i < pRoutersLength; i++) { + reqUrl = '/physical-router/' + data['physical-routers'][i]['uuid']; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, false), + function(error, results) { + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalInterfaceDetails(error, results, response, appData); + } + ); +} + +function getPhysicalInterfaceDetails(error, pRouters, response, appData){ + var pInterfacesLength = 0; + var result = []; + var dataObjArr = []; + + for(var k = 0; k < pRouters.length; k++){ + var prouter = pRouters[k]; + if(prouter['physical-router'] != null && prouter['physical-router']['physical_interfaces'] != null && prouter['physical-router']['physical_interfaces'].length > 0){ + pInterfacesLength = prouter['physical-router']['physical_interfaces'].length; + for(i = 0; i < pInterfacesLength; i++) { + var pInterface = prouter['physical-router']['physical_interfaces'][i]; + reqUrl = '/physical-interface/' + pInterface['uuid']; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + } + } + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, false), + function(error, pInterfaces) { + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + if(pInterfaces.length > 0){ + + for(var j=0 ;j < pRouters.length; j++){ + pRouters[j]['physical-router']['physical_interfaces'] = []; + for(var l=0 ; l < pInterfaces.length; l++){ + if(pRouters[j]['physical-router']['uuid'] == pInterfaces[l]['physical-interface']['parent_uuid']){ + pRouters[j]['physical-router']['physical_interfaces'].push(pInterfaces[l]['physical-interface']); + } + } + } + commonUtils.handleJSONResponse(error, response, pRouters); + } + } + ); +} + + +/** + * @setPRouterRead + * private function + * 1. Callback for Fip create / update operations + * 2. Reads the response of Fip get from config api server + * and sends it back to the client. + */ +function setPRouterRead(error, fipConfig, response, appData) +{ + var fipGetURL = '/floating-ip/'; + + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + + fipGetURL += fipConfig['floating-ip']['uuid']; + configApiServer.apiGet(fipGetURL, appData, + function(error, data) { + fipSendResponse(error, data, response) + }); +} + +/** + * @createPhysicalRouter + * public function + * 1. URL /api/tenants/config/physical-routers - Post + */ +/** + * @createPhysicalRouters + * public function + * 1. URL /api/tenants/config/physical-routers/ + * 2. creats a physical router in config api server + */ +function createPhysicalRouters (request, response, appData) +{ + var postData = request.body; + console.log('postData : ' + JSON.stringify(postData)); + console.log('type' + postData['physical-router']['virtual_router_type']); + console.log('virtualrouters' + JSON.stringify(postData['physical-router']['virtual-routers'])); + //Read the virtual router type to be created + //if embedded use the details to create a virtual router. If it fails dont create physical router as well. + if(postData['physical-router']['virtual_router_type'] != null){ + if(postData['physical-router']['virtual_router_type'] == 'Embedded'){ + var vrouterPostData = postData['physical-router']['virtual-routers'][0]; + console.log("vrouter post data :"+ JSON.stringify(vrouterPostData)); + if(vrouterPostData){ + configApiServer.apiPost('/virtual-routers', vrouterPostData, appData, + function(error, data) { + console.log('response for vrouters create'); + if(error) { + console.log('error creating vrouter'); + commonUtils.handleJSONResponse(error, response, null); + return; + } else { + delete postData['physical-router']['virtual-routers']; + delete postData['physical-router']['virtual_router_type']; + //create physical router + console.log('creating prouter'); + configApiServer.apiPost('/physical-routers', postData, appData, + function(error, data) { + if(error){ + console.log('error creating prtouer'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + console.log('created prouter'); + getPhysicalRouters(request, response, appData); + }); + } + }); + } else { + delete postData['physical-router']['virtual-routers']; + delete postData['physical-router']['virtual_router_type']; + //create physical router + console.log('creating prouter'); + configApiServer.apiPost('/physical-routers', postData, appData, + function(error, data) { + if(error){ + console.log('error creating prtouer'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + console.log('created prouter'); + getPhysicalRouters(request, response, appData); + }); + } + } + //If Tor Agent + //Try to create the TOR Agent and TSN. Even if they fail go ahead and create physical router + else if(postData['physical-router']['virtual_router_type'] == 'TOR Agent'){ + var vrouterPostData = postData['physical-router']['virtual-routers']; + if(vrouterPostData.length > 0){ + console.log('trying to create tor agent'); + var reqUrl = null; + var dataObjArr = []; + for(i = 0; i < vrouterPostData.length; i++) { + reqUrl = '/virtual-routers'; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_POST, + vrouterPostData[i], null, null, appData); + } + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiPost, false), + function(error, results) { + if (error) { + console.log('error creating vrouters'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + console.log('creating prouter'); + delete postData['virtual-routers']; + delete postData['virtual_router_type']; + //create physical router + configApiServer.apiPost('/physical-routers', postData, appData, + function(error, data) { + if(error){ + console.log('error creating prouter'); + console.log(error); + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + } + ); + } else { + delete postData['virtual-routers']; + delete postData['virtual_router_type']; + //create physical router + configApiServer.apiPost('/physical-routers', postData, appData, + function(error, data) { + if(error){ + console.log('error creating prouter'); + console.log(error); + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + } + } + } else { + //create physical router + console.log('no vrouters just creating the prouter'); + configApiServer.apiPost('/physical-routers', postData, appData, + function(error, data) { + if(error){ + console.log('error creating prouter'); + console.log(error); + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + } +} + +/** + * @updatePhysicalRouters + * public function + * 1. URL /api/tenants/config/physical-router/:id + * 2. updates a physical router in config api server + */ +function updatePhysicalRouters (request, response, appData) +{ + /* var pRouterId = validatePhysicalRouterId(request); + var postData = request.body; + configApiServer.apiPut('/physical-router/' + pRouterId, postData, appData, + function(error, data) { + if(error){ + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + */ + var pRouterId = validatePhysicalRouterId(request); + var postData = request.body; + console.log('postData : ' + JSON.stringify(postData)); + console.log('type' + postData['physical-router']['virtual_router_type']); + console.log('virtualrouters' + JSON.stringify(postData['physical-router']['virtual-routers'])); + //Read the virtual router type to be created + //if embedded use the details to create a virtual router. If it fails dont create physical router as well. + if(postData['physical-router']['virtual_router_type'] != null){ + if(postData['physical-router']['virtual_router_type'] == 'Embedded'){ + var vrouterPostData = postData['physical-router']['virtual-routers'][0]; + console.log("vrouter post data :"+ JSON.stringify(vrouterPostData)); + if(vrouterPostData){ + configApiServer.apiPost('/virtual-routers', vrouterPostData, appData, + function(error, data) { + console.log('response for vrouters create'); + if(error) { + console.log('error creating vrouter'); + commonUtils.handleJSONResponse(error, response, null); + return; + } else { + delete postData['physical-router']['virtual-routers']; + delete postData['physical-router']['virtual_router_type']; + //create physical router + console.log('creating prouter'); + configApiServer.apiPut('/physical-router/' + pRouterId, postData, appData, + function(error, data) { + if(error){ + console.log('error creating prtouer'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + console.log('created prouter'); + getPhysicalRouters(request, response, appData); + }); + } + }); + } else { + delete postData['physical-router']['virtual-routers']; + delete postData['physical-router']['virtual_router_type']; + //create physical router + console.log('creating prouter'); + configApiServer.apiPut('/physical-router/' + pRouterId, postData, appData, + function(error, data) { + if(error){ + console.log('error updating prtouer'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + console.log('created prouter'); + getPhysicalRouters(request, response, appData); + }); + } + } + //If Tor Agent + //Try to create the TOR Agent and TSN. Even if they fail go ahead and create physical router + else if(postData['physical-router']['virtual_router_type'] == 'TOR Agent'){ + var vrouterPostData = postData['physical-router']['virtual-routers']; + if(vrouterPostData.length > 0){ + console.log('trying to create tor agent'); + var reqUrl = null; + var dataObjArr = []; + for(i = 0; i < vrouterPostData.length; i++) { + reqUrl = '/virtual-routers'; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_POST, + vrouterPostData[i], null, null, appData); + } + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiPost, false), + function(error, results) { + if (error) { + console.log('error creating vrouters'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + console.log('creating prouter'); + delete postData['virtual-routers']; + delete postData['virtual_router_type']; + //create physical router + configApiServer.apiPut('/physical-router/' + pRouterId, postData, appData, + function(error, data) { + if(error){ + console.log('error updating prouter'); + console.log(error); + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + } + ); + } else { + delete postData['virtual-routers']; + delete postData['virtual_router_type']; + //create physical router + configApiServer.apiPut('/physical-router/' + pRouterId, postData, appData, + function(error, data) { + if(error){ + console.log('error updating prouter'); + console.log(error); + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + } + } + } else { + //create physical router + console.log('no vrouters just creating the prouter'); + configApiServer.apiPut('/physical-router/' + pRouterId, postData, appData, + function(error, data) { + if(error){ + console.log('error updating prouter'); + console.log(error); + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); + } + +} + +/** + * @deletePhysicalRouters + * public function + * 1. URL /api/tenants/config/physical-router/:id + * 2. deletes a physical router in config api server + */ +function deletePhysicalRouters (request, response, appData) +{ + var pRouterID = validatePhysicalRouterId(request); + var postData = request.body; + configApiServer.apiDelete('/physical-router/' + pRouterID, appData, + function(error, data) { + if(error){ + commonUtils.handleJSONResponse(error, response, null); + return; + } + getPhysicalRouters(request, response, appData); + }); +} + + +function validatePhysicalRouterId (request) +{ + var pRouterId = null; + if (!(pRouterId = request.param('id').toString())) { + error = new appErrors.RESTServerError('Add Physical Router id'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + return pRouterId; +} + + /* List all public function here */ + + exports.getPhysicalRoutersList= getPhysicalRoutersList; + exports.getPhysicalRouters = getPhysicalRouters; + exports.createPhysicalRouters = createPhysicalRouters; + exports.updatePhysicalRouters = updatePhysicalRouters; + exports.deletePhysicalRouters = deletePhysicalRouters; \ No newline at end of file diff --git a/webroot/config/physicaldevices/physicalrouters/ui/js/physicalrouters_config.js b/webroot/config/physicaldevices/physicalrouters/ui/js/physicalrouters_config.js new file mode 100644 index 000000000..94bfd6e92 --- /dev/null +++ b/webroot/config/physicaldevices/physicalrouters/ui/js/physicalrouters_config.js @@ -0,0 +1,740 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + +physicalRoutersConfigObj = new physicalRoutersConfig(); +function physicalRoutersConfig() { + //Variable Definitions + var gridPhysicalRouters; + var globalVRoutersMap = {}; + + //Method Definitions + this.load = load; + this.destroy = destroy; + + function load() { + var configTemplate = Handlebars.compile($("#physicalrouters-config-template").html()); + $(contentContainer).html(''); + $(contentContainer).html(configTemplate); + init(); + } + + function init() { + initComponents(); + initActions(); + fetchData(); + fetchBGPRouters(); + fetchVNs(); + fetchVirtualRouters(); + } + + function initComponents() { + //initializing the physical routers Grid + $("#gridPhysicalRouters").contrailGrid({ + header : { + title: { + text : 'Physical Routers', + //cssClass : 'blue', + //icon : 'icon-list', + //iconCssClass : 'blue' + }, + customControls: ['', + ''] + }, + columnHeader : { + columns : [ + { + id : 'name', + field : 'name', + name : 'Name' , + cssClass :'cell-hyperlink-blue', + events : { + onClick : function(e, dc) { + layoutHandler.setURLHashParams({uuid : dc.uuid} ,{p : 'config_pd_interfaces' ,merge : false ,triggerHashChange : true}); + } + } + }, + { + id : 'mgmt_ip_address', + field : 'mgmt_ip_address', + name : 'Management IP' + }, + { + id : 'data_ip_address', + field : 'data_ip_address', + name : 'Tunnel Source IP' + }, + { + id : 'interfaces', + field : 'interfaces', + name : 'Interfaces', + cssClass :'cell-hyperlink-blue', + events : { + onClick : function(e, dc) { + layoutHandler.setURLHashParams({uuid : dc.uuid} ,{p : 'config_pd_interfaces' ,merge : false ,triggerHashChange : true}); + } + } + }] + }, + body : { + options : { + checkboxSelectable: { + onNothingChecked: function(e){ + $('#btnDeletePhysicalRouter').addClass('disabled-link'); + }, + onSomethingChecked: function(e){ + $('#btnDeletePhysicalRouter').removeClass('disabled-link'); + } + }, + forceFitColumns: true, + actionCell: [ + { + title: 'Edit', + iconClass: 'icon-edit', + onClick: function(rowIndex){ + physicalRouterEditWindow(rowIndex); + } + }, + { + title: 'Delete', + iconClass: 'icon-trash', + onClick: function(rowIndex){ + showPhysicalRouterDelWindow(rowIndex); + } + } + ], + detail : { + template : $("#gridPhysicalRoutersDetailTemplate").html() + } + }, + dataSource : { + data : [] + }, + statusMessages: { + loading: { + text: 'Loading Physical Routers..' + }, + empty: { + text: 'No Physical Routers.' + }, + errorGettingData: { + type: 'error', + iconClasses: 'icon-warning', + text: 'Error in getting Physical Routers.' + } + } + } + }); + gridPhysicalRouters = $("#gridPhysicalRouters").data('contrailGrid'); + + //initializing add record window + $('#addPhysicalRouterWindow').modal({backdrop:'static',keyboard:false,show:false}); + $('#addPhysicalRouterWindow').find(".modal-header-title").text('Add Physical Router'); + + //Initializing the bgp router dropdown + $('#ddBgpRouter').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + }); + var ddBgp = $('#ddBgpRouter').data('contrailDropdown'); + + //initializing physical router type multi select + $('#msVN').contrailMultiselect({ + dataTextField:'text', + dataValueField:'value', + }); + + //initializing physical router type multi select + $('#ddVirtualRoutersType').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + change:onVrouterTypeChange, + }); + + var vrType = $('#ddVirtualRoutersType').data('contrailDropdown'); + var vrTypeDS = [{ text : 'None', value : 'none'}, + { text : 'Embedded', value : 'embedded'}, + { text : 'TOR Agent', value : 'tor-agent'} + ]; + vrType.setData(vrTypeDS); + + $('#ddTorAgentName').contrailCombobox({ + dataTextField:'text', + dataValueField:'value', + minimumResultsForSearch : 1, + change:onTorAgentChange + }); + + $('#ddTsnName').contrailCombobox({ + dataTextField:'text', + dataValueField:'value', + minimumResultsForSearch : 1, + change:onTsnChange + }); + + //initializing delete record window + //deleteRecordWindowObj.modal({backdrop:'static',keyboard:false,show:false}); + //deleteRecordWindowObj.find(".modal-header-title").text('Confirm'); + + $('#confirmMainDelete').modal({backdrop:'static',keyboard:false,show:false}); + $('#confirmMainDelete').find(".modal-header-title").text('Confirm'); + } + + function onVrouterTypeChange(e){ + var inf = e.added.value; + if(inf === "tor-agent") { + $('#vRouterTorAgentFields').removeClass('hide').addClass('show'); + } else { + $('#vRouterTorAgentFields').removeClass('show').addClass('hide'); + } + } + + function onTorAgentChange(e){ +// var inf = e.added.value; + var torcb = $('#ddTorAgentName').data('contrailCombobox'); + var inf = torcb.value(); + var allData = torcb.getAllData(); + var isSelectedFromList = false; + $.each(allData,function(i,d){ + if(d.id == inf){ + isSelectedFromList = true; + } + }); + if(inf != null && isSelectedFromList){ + $('#txtTorAgentIp').val(inf); + $('#txtTorAgentIp').attr("disabled", "disabled"); + } else { + $('#txtTorAgentIp').val(''); + $('#txtTorAgentIp').removeAttr("disabled"); + } + } + + function onTsnChange(e){ +// var inf = e.added.value; + var tsncb = $('#ddTsnName').data('contrailCombobox'); + var inf = tsncb.value(); + var allData = tsncb.getAllData(); + var isSelectedFromList = false; + $.each(allData,function(i,d){ + if(d.id == inf){ + isSelectedFromList = true; + } + }); + if(inf != null && inf != '' && isSelectedFromList){ + $('#txtTsnIp').val(inf); + $('#txtTsnIp').attr("disabled", "disabled"); + } else { + $('#txtTsnIp').val(''); + $('#txtTsnIp').removeAttr("disabled"); + } + } + + function initActions() { + $('#btnCreatePhysicalRouter').click(function() { + $('#addPhysicalRouterWindow').find(".modal-header-title").text('Add Physical Router'); + populateCreateEditWindow('create'); + }); + + $('#btnAddPhysicalRouterOk').click(function() { + if(validate()) { + $('#addPhysicalRouterWindow').modal('hide'); + createUpdatePhysicalRouter(); + } + }); + $('#btnDeletePhysicalRouter').click(function(){ + $('#confirmMainDelete').modal('show'); + }); + $('#btnCnfDelMainPopupOK').click(function(args){ + var selected_rows = gridPhysicalRouters.getCheckedRows(); + $('#confirmMainDelete').modal("hide"); + deletePhysicalRouter(selected_rows); + }); + } + + window.showPhysicalRouterDelWindow = function(index) { + $.contrailBootstrapModal ( + { + id: 'confirmRemove', + title: 'Remove', + body: '
Confirm Removing record
', + footer: [ + { + title: 'Cancel', + onclick: 'close', + }, + { + id: 'btnRemovePopupOK', + title: 'Confirm', + onclick: function(){ + var selected_row = gridPhysicalRouters._dataView.getItem(index); + deletePhysicalRouter([selected_row]); + $('#confirmRemove').modal('hide'); + }, + className: 'btn-primary' + }] + }); + } + + function deletePhysicalRouter(selected_rows) { + $('#btnDeletePhysicalRouter').addClass('disabled-link'); + if(selected_rows && selected_rows.length > 0){ + var deleteAjaxs = []; + for(var i = 0;i < selected_rows.length;i++){ + var sel_row_data = selected_rows[i]; + deleteAjaxs[i] = $.ajax({ + url:'/api/tenants/config/physical-router/' + sel_row_data['uuid'], + type:'DELETE' + }); + } + $.when.apply($,deleteAjaxs).then( + function(response){ + //all success + fetchData(); + }, + function(){ + //if at least one delete operation fails + var r = arguments; + showInfoWindow(r[0].responseText,r[2]); + fetchData(); + } + ); + } + } + + window.physicalRouterEditWindow = function(index) { + gblSelRow = gridPhysicalRouters._dataView.getItem(index); + populateCreateEditWindow('edit'); + } + + function populateCreateEditWindow(m) { + mode = m; + clearCreateEditWindow(); +//TODO this need to be called on load of the window otherwise the data obtained will be stale fetchVirtualRouters(); + if(mode === 'edit') { + + $('#addPhysicalRouterWindow').find(".modal-header-title").text('Edit Physical Router'); + $('#txtPhysicalRouterName').val(gblSelRow.name); + if(gblSelRow.vendor != '-') + $('#txtVendor').val(gblSelRow.vendor); + $('#txtPhysicalRouterName').attr('disabled','disabled'); + if(gblSelRow.mgmt_ip_address != '-') + $('#txtMgmtIPAddress').val(gblSelRow.mgmt_ip_address); + if(gblSelRow.data_ip_address != '-') + $('#txtDataIPAddress').val(gblSelRow.data_ip_address); + if(gblSelRow.username != '-') + $('#txtUsername').val(gblSelRow.username); + if(gblSelRow.password != '-') + $('#txtPassword').val(gblSelRow.password); + if(gblSelRow.bgp_routers != '-') + $('#ddBgpRouter').data('contrailDropdown').text(gblSelRow.bgp_routers); + var msVNData = $('#msVN').data('contrailMultiselect').getAllData(); + var valueArr = []; + for(var i = 0; i < msVNData.length ; i++){ + for(var j = 0; j < gblSelRow.virtual_networks.length ; j++){ + if(msVNData[i].text == gblSelRow.virtual_networks[j]){ + valueArr.push(msVNData[i].value); + } + } + } + $('#msVN').data('contrailMultiselect').value(valueArr); + + if(gblSelRow.virtual_router != '-'){ + var selectedVRouters = gblSelRow.virtual_router.split(','); + var vRoutersWithType = []; + var vrType = 'None'; + $.each(selectedVRouters,function(i,vrname){ + var dtl = getVirtualRouterDetails(vrname); + if(dtl.type == 'embedded'){ + vrType = 'Embedded'; + $('#vRouterTorAgentFields').removeClass('show').addClass('hide'); + } else if(dtl.type == 'tor-agent'){ + vrType = 'TOR Agent'; + $('#ddTorAgentName').data('contrailCombobox').value(vrname); + $('#vRouterTorAgentFields').removeClass('hide').addClass('show'); + $('#txtTorAgentIp').val(dtl.ip); + $('#txtTorAgentIp').attr("disabled", "disabled"); + } else { + vrType = 'TOR Agent'; + $('#ddTsnName').data('contrailCombobox').value(vrname); + $('#vRouterTorAgentFields').removeClass('hide').addClass('show'); + $('#txtTsnIp').val(dtl.ip); + $('#txtTsnIp').attr("disabled", "disabled"); + } +// vRoutersWithType.push({name:vrname,type:type]}); + }); + + $('#ddVirtualRoutersType').data('contrailDropdown').text(vrType); + } + } else { + $('#ddBgpRouter').data('contrailDropdown').value('None'); + $('#ddVirtualRoutersType').data('contrailDropdown').value('None'); + } + $('#addPhysicalRouterWindow').modal('show'); + } + + function getVirtualRouterDetails(vRouterName) { + return (globalVRoutersMap[vRouterName.trim()])? globalVRoutersMap[vRouterName.trim()] : ''; + } + + function createUpdatePhysicalRouter() { + var methodType = 'POST'; + var url = '/api/tenants/config/physical-routers'; + var selectedVRouters = []; + if(mode === 'edit') { + methodType = 'PUT'; + url = '/api/tenants/config/physical-router/' + gblSelRow.uuid + if(gblSelRow.virtual_router != '-'){ + selectedVRouters = gblSelRow.virtual_router.split(','); + } + } + var name = $("#txtPhysicalRouterName").val(); + var vendor = $("#txtVendor").val(); + var mgmtIpAddress = $("#txtMgmtIPAddress").val(); + var dataIpAddress = $("#txtDataIPAddress").val(); + var username = $("#txtUsername").val(); + var password = $("#txtPassword").val(); + var bgpRouter = $("#ddBgpRouter").data('contrailDropdown').text(); + + var vRoutersType = $("#ddVirtualRoutersType").data('contrailDropdown').text(); + var postObject = {}; + + gridPhysicalRouters._dataView.setData([]); + gridPhysicalRouters.showGridMessage('loading'); + + postObject["physical-router"] = {}; + postObject["physical-router"]["fq_name"] = ["default-global-system-config", name]; + postObject["physical-router"]["parent_type"] = "global-system-config"; + postObject["physical-router"]["name"] = name; + postObject["physical-router"]['physical_router_vendor_name'] = vendor; + postObject["physical-router"]["physical_router_management_ip"] = mgmtIpAddress; + postObject["physical-router"]["physical_router_dataplane_ip"] = dataIpAddress; + postObject["physical-router"]['physical_router_user_credentials'] = {}; + postObject["physical-router"]['physical_router_user_credentials']["username"] = username; + postObject["physical-router"]['physical_router_user_credentials']["password"] = password; + if(bgpRouter != 'None'){ + var bgpRouterRefs = [{"to":["default-domain", "default-project" , "ip-fabric", "__default__", bgpRouter]}]; + postObject["physical-router"]["bgp_router_refs"] = bgpRouterRefs; + } else { + postObject["physical-router"]["bgp_router_refs"] = []; + } + + var vns = $("#msVN").data('contrailMultiselect').getSelectedData(); + if(vns.length > 0){ + var vnRefs = []; + for(var i = 0 ;i < vns.length ; i++){ + vnRefs.push({"to":vns[i].data}); + } + postObject["physical-router"]["virtual_network_refs"] = vnRefs; + } else { + postObject["physical-router"]["virtual_network_refs"] = []; + } + + if(vRoutersType != 'None'){ + var virtualRouterRefs = []; + if(vRoutersType == 'Embedded'){ + postObject["physical-router"]['virtual_router_type'] = vRoutersType; + var virtualRouters = []; + postObject["physical-router"]["virtual-routers"] = []; + + virtualRouters.push({"virtual-router" : {"fq_name":["default-global-system-config", name], + "parent_type":"global-system-config", + "name": name, + "virtual_router_ip_address" : mgmtIpAddress, + "virtual_router_type" : ['embedded']}}); + virtualRouterRefs.push({"to":["default-global-system-config",name]}); + + } else {//ToR Agent case + var torcb = $('#ddTorAgentName').data('contrailCombobox'); + var tor = torcb.value(); + var allData = torcb.getAllData(); + var isTorSelectedFromList = false; + var isTorAlreadyFromEdit = false; + $.each(allData,function(i,d){ + if(d.id == tor){ + isTorSelectedFromList = true; + } + }); + $.each(selectedVRouters,function(j,vrouter){ + if(vrouter.trim() == tor){ + isTorAlreadyFromEdit = true; + } + }); + var tsncb = $('#ddTsnName').data('contrailCombobox'); + var tsn = tsncb.value(); + var tsnAllData = tsncb.getAllData(); + var isTsnSelectedFromList = false; + var isTsnAlreadyFromEdit = false; + $.each(tsnAllData,function(i,d){ + if(d.id == tsn){ + isTsnSelectedFromList = true; + } + }); + $.each(selectedVRouters,function(j,vrouter){ + if(vrouter.trim() == tsn){ + isTsnAlreadyFromEdit = true; + } + }); + postObject["physical-router"]['virtual_router_type'] = vRoutersType; + var virtualRouters = []; + postObject["physical-router"]["virtual-routers"] = []; + + var torAgentName = $("#ddTorAgentName").data('contrailCombobox').text(); + var torAgentIp = $("#txtTorAgentIp").val(); + var tsnName = $("#ddTsnName").data('contrailCombobox').text(); + var tsnIp = $("#txtTsnIp").val(); + //TOR Agent + if(!isTorSelectedFromList && !isTorAlreadyFromEdit){ + virtualRouters.push({"virtual-router" : {"fq_name":["default-global-system-config", torAgentName], + "parent_type":"global-system-config", + "name": torAgentName, + "virtual_router_ip_address" : torAgentIp, + "virtual_router_type" : ['tor-agent']}}); + } + virtualRouterRefs.push({"to":["default-global-system-config",torAgentName]}); + //TSN + if(!isTsnSelectedFromList && !isTsnAlreadyFromEdit){ + virtualRouters.push({"virtual-router" : {"fq_name":["default-global-system-config", tsnName], + "parent_type":"global-system-config", + "name": tsnName, + "virtual_router_ip_address" : tsnIp, + "virtual_router_type" : ['tor-service-node']}}); + } + virtualRouterRefs.push({"to":["default-global-system-config",tsnName]}); + } + + postObject["physical-router"]["virtual-routers"] = virtualRouters; + postObject["physical-router"]["virtual_router_refs"] = virtualRouterRefs; + } else { + postObject["physical-router"]["virtual_router_refs"] = []; + } + doAjaxCall(url, methodType, JSON.stringify(postObject), 'successHandlerForPhysicalRouters', 'failureHandlerForCreateEditRouters', null, null); + } + window.failureHandlerForCreateEditRouters = function(error) { + //gridPhysicalRouters.showGridMessage("errorCreateEdit"); + fetchData(); + } + + function clearCreateEditWindow() { + $('#txtPhysicalRouterName').removeAttr('disabled'); + $("#txtPhysicalRouterName").val(''); + $("#txtVendor").val(''); + $("#txtMgmtIPAddress").val(''); + $("#txtDataIPAddress").val(''); + $("#txtUsername").val(''); + $("#txtPassword").val(''); + $("#ddBgpRouter").data('contrailDropdown').value('None'); + $("#msVN").data('contrailMultiselect').value(''); + $("#ddVirtualRoutersType").data('contrailDropdown').value('None'); + $("#ddTorAgentName").data('contrailCombobox').value(''); + $("#ddTsnName").data('contrailCombobox').value(''); + $("#txtTorAgentIp").val(''); + $("#txtTsnIp").val(''); + } + + function fetchData() { + gridPhysicalRouters._dataView.setData([]); + gridPhysicalRouters.showGridMessage('loading'); + doAjaxCall('/api/tenants/config/physical-routers','GET', null, 'successHandlerForPhysicalRouters', 'failureHandlerForPhysicalRouters', null, null); + } + + window.successHandlerForPhysicalRouters = function(result) { + if(result.length > 0) { + var gridDS = []; + for(var i = 0; i < result.length;i++) { + var rowData = result[i]['physical-router']; + var pinterfaces = ifNull(rowData['physical_interfaces'],[]); + var linterfaces = ifNull(rowData['logical_interfaces'],[]); + var linpinterfaces = []; + $.each(pinterfaces,function(i,pInterface){ + var lInterfaces = ifNull(pInterface['logical_interfaces'],[]); + linpinterfaces = linpinterfaces.concat(lInterfaces); + }); + var interfaces = pinterfaces.concat(linterfaces,linpinterfaces); + var virtualRouters = ifNull(rowData['virtual_router_refs'],[]); + var virtualRouterString = ''; + $.each(virtualRouters, function(i,d){ + if(i != 0) + virtualRouterString = virtualRouterString + ', ' + d.to[1] + else + virtualRouterString = d.to[1]; + }); + var bgpRouters = ifNull(rowData['bgp_router_refs'],[]); + var bgpRoutersString = ''; + $.each(bgpRouters, function(i,d){ + if(i != 0) + bgpRoutersString = bgpRoutersString + ', ' + d.to[4] + else + bgpRoutersString = d.to[4]; + }); + var vns = ifNull(rowData['virtual_network_refs'],[]); + var vnsString = []; + $.each(vns, function(i,d){ + vnsString.push(d.to[2]); + }); + + var credentials = rowData['physical_router_user_credentials']; + var username = '-',password = '-'; + if(credentials != null){ + username = credentials['username']; + password = credentials['password']; + } + gridDS.push({ + uuid : rowData.uuid, + name : rowData.name, + vendor : rowData['physical_router_vendor_name'] ? rowData['physical_router_vendor_name'] : '-', + mgmt_ip_address : rowData['physical_router_management_ip'] ? rowData['physical_router_management_ip'] : '-', + data_ip_address : rowData['physical_router_dataplane_ip'] ? rowData['physical_router_dataplane_ip'] : '-', + username : (username == '')? '-' : username, + password : password, + interfaces : interfaces.length, + bgp_routers : (bgpRoutersString == '')? '-' : bgpRoutersString, + virtual_networks : vnsString.length > 0 ? vnsString : '-', + virtual_router : (virtualRouterString == '')? '-' : virtualRouterString + }); + } + + } else { + gridPhysicalRouters.showGridMessage("empty"); + } + gridPhysicalRouters._dataView.setData(gridDS); + } + + window.failureHandlerForPhysicalRouters = function(error) { + //gridPhysicalRouters.showGridMessage("errorGettingData"); + fetchData(); + } + + function fetchVirtualRouters() { + doAjaxCall('/api/tenants/config/virtual-routers','GET', null, 'successHandlerForVirtualRouters', 'failureHandlerForVirtualRouters', null, null); + } + + window.successHandlerForVirtualRouters = function(result) { + var torAgentVrouterDS = []; + var tsnVrouterDS = []; + globalVRoutersMap = {}; + if(result && result.length > 0) { + for(var i = 0; i < result.length;i++) { + var virtualRouter = result[i]['virtual-router']; + var vRouterType = (virtualRouter['virtual_router_type'])? virtualRouter['virtual_router_type'][0] : ''; + var vRouterIP = (virtualRouter['virtual_router_ip_address'])? virtualRouter['virtual_router_ip_address'] : ''; + //build a map with vrouter name and type to be used in createEditWindow + globalVRoutersMap[virtualRouter['name']] = {type:vRouterType,ip:vRouterIP}; + + if(vRouterType == 'tor-agent'){ + //Tor agent can be assigned to only one prouter so dont include them in the list + if(!virtualRouter['physical_router_back_refs'] || virtualRouter['physical_router_back_refs'].length < 1) { + torAgentVrouterDS.push({text : virtualRouter.fq_name[1], value : virtualRouter.virtual_router_ip_address}); + } + } else if(vRouterType == 'tor-service-node'){ + tsnVrouterDS.push({text : virtualRouter.fq_name[1], value : virtualRouter.virtual_router_ip_address}); + } + } + if(torAgentVrouterDS.length < 1) { + torAgentVrouterDS.push({text : 'No ToR Agent found', value: 'Message'}); + } + if(tsnVrouterDS.length < 1) { + tsnVrouterDS.push({text : 'No TSN Agent found', value: 'Message'}); + } + } else { + torAgentVrouterDS.push({text : 'No ToR Agent found', value: 'Message'}); + tsnVrouterDS.push({text : 'No TSN found', value: 'Message'}); + } + var torAgentDD = $('#ddTorAgentName').data('contrailCombobox'); + torAgentDD.setData(torAgentVrouterDS); + var tsnAgentDD = $('#ddTsnName').data('contrailCombobox'); + tsnAgentDD.setData(tsnVrouterDS); + } + + window.failureHandlerForVirtualRouters = function(error) { + gridPhysicalRouters.showGridMessage('errorGettingData'); + } + + function fetchBGPRouters() { + doAjaxCall('api/admin/nodes/bgp','GET', null, 'successHandlerForBGPRouters', 'failureHandlerForBGPRouters', null, null); + } + + window.successHandlerForBGPRouters = function(result) { + var bgpDS = [{text : "None", value : "None"}]; + if(result && result.length > 0) { + for(var i = 0; i < result.length;i++) { + var bgpRouter = result[i]; + bgpDS.push({text : bgpRouter.name, value : bgpRouter.uuid}); + } + + } else { + bgpDS.push({text : 'No BGP Router found', value: 'Message'}); + } + var bgpDD = $('#ddBgpRouter').data('contrailDropdown'); + bgpDD.setData(bgpDS); + } + + window.failureHandlerForBGPRouters = function(error) { + gridPhysicalRouters.showGridMessage('errorGettingData'); + } + + function fetchVNs() { + doAjaxCall('api/tenants/config/virtual-networks','GET', null, 'successHandlerForVNs', 'failureHandlerForVNs', null, null); + } + + window.successHandlerForVNs = function(result) { + var vnDS = []; + + if(result && result['virtual-networks'].length > 0) { + var vns = result['virtual-networks']; + for(var i = 0; i < vns.length;i++) { + var vn = vns[i]; + var fqname = vn.fq_name; + var data = fqname; + var val = vn.uuid; + vnDS.push({text : fqname[2], value : val, data : data}); + } + + } else { + vnDS.push({text : 'No VN found', value: 'Message'}); + } + var msVN = $('#msVN').data('contrailMultiselect'); + msVN.setData(vnDS); + } + + window.failureHandlerForVNs = function(error) { + gridPhysicalRouters.showGridMessage('errorGettingData'); + } + + function validate() { + var name = $('#txtPhysicalRouterName').val().trim(); + if(name === ""){ + showInfoWindow("Enter a Physical Router Name","Input required"); + return false; + } + if($('#txtMgmtIPAddress').val() != '') { + var mgmtIpAddress = $('#txtMgmtIPAddress').val().trim(); + if(!validateIPAddress(mgmtIpAddress)){ + showInfoWindow("Enter a valid Management IP address in xxx.xxx.xxx.xxx format","Input required"); + return false; + } + } + if($('#txtDataIPAddress').val() != '') { + var dataIpAddress = $('#txtDataIPAddress').val().trim(); + if(!validateIPAddress(dataIpAddress)){ + showInfoWindow("Enter a valid Dataplane IP address in xxx.xxx.xxx.xxx format","Input required"); + return false; + } + } + return true; + } + + function destroy() { + var configTemplate = $("#physicalrouters-config-template"); + if(isSet(configTemplate)) { + configTemplate.remove(); + configTemplate = $(); + } + var configDetailTemplate = $("#gridPhysicalRoutersDetailTemplate"); + if(isSet(configDetailTemplate)) { + configDetailTemplate.remove(); + configDetailTemplate = $(); + } + } + + } + \ No newline at end of file diff --git a/webroot/config/physicaldevices/physicalrouters/ui/views/physicalrouters_config.view b/webroot/config/physicaldevices/physicalrouters/ui/views/physicalrouters_config.view new file mode 100644 index 000000000..87324d4a9 --- /dev/null +++ b/webroot/config/physicaldevices/physicalrouters/ui/views/physicalrouters_config.view @@ -0,0 +1,246 @@ + + \ No newline at end of file diff --git a/webroot/config/physicaldevices/virtualrouters/api/parseURL.xml b/webroot/config/physicaldevices/virtualrouters/api/parseURL.xml new file mode 100644 index 000000000..7a93f4131 --- /dev/null +++ b/webroot/config/physicaldevices/virtualrouters/api/parseURL.xml @@ -0,0 +1,47 @@ + + + + parseURLReq + process.mainModule.exports["corePath"] + '/src/serverroot/common/parseURLRequire' + + + virtualroutersconfigapi + ./virtualroutersconfig.api + + + + + /api/tenants/config/virtual-routers-list + get + virtualroutersconfig + virtualroutersconfigapi.getVirtualRoutersList + + + /api/tenants/config/virtual-routers + get + virtualroutersconfig + virtualroutersconfigapi.getVirtualRouters + + + /api/tenants/config/virtual-routers + post + virtualroutersconfig + virtualroutersconfigapi.createVirtualRouters + + + /api/tenants/config/virtual-router/:id + put + virtualroutersconfig + virtualroutersconfigapi.updateVirtualRouters + + + /api/tenants/config/virtual-router/:id + delete + virtualroutersconfig + virtualroutersconfigapi.deleteVirtualRouters + + \ No newline at end of file diff --git a/webroot/config/physicaldevices/virtualrouters/api/virtualroutersconfig.api.js b/webroot/config/physicaldevices/virtualrouters/api/virtualroutersconfig.api.js new file mode 100644 index 000000000..4e484fd76 --- /dev/null +++ b/webroot/config/physicaldevices/virtualrouters/api/virtualroutersconfig.api.js @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + + /** + * @quotasconfig.api.js + * - Handlers for project quotas + * - Interfaces with config api server + */ +var rest = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/rest.api'); +var async = require('async'); +var quotasconfigapi = module.exports; +var logutils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/log.utils'); +var commonUtils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/common.utils'); +var config = require(process.mainModule.exports["corePath"] + + '/config/config.global.js'); +var messages = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/messages'); +var global = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/global'); +var appErrors = require(process.mainModule.exports["corePath"] + + '/src/serverroot/errors/app.errors'); +var util = require('util'); +var url = require('url'); +var configApiServer = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/configServer.api'); +var async = require('async'); + +/** + * @getVirtualRoutersList + * public function + * 1. URL /api/tenants/config/virtual-routers-list + * 2. Gets virtual routers from config api server + */ +function getVirtualRoutersList (request, response, appData) +{ + configApiServer.apiGet('/virtual-routers', appData, + function(error, data) { + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + commonUtils.handleJSONResponse(error, response, data); + } + ); +} + +/** + * @getVirtualRouters + * public function + * 1. URL /api/tenants/config/virtual-routers/ + * 2. Gets virtual routers from config api server + */ +function getVirtualRouters (request, response, appData) +{ + configApiServer.apiGet('/virtual-routers', appData, + function(error, data) { + getVirtualRoutersDetails(error, data, response, appData); + }); +} + +function getVirtualRoutersDetails(error, data, response, appData) +{ + var reqUrl = null; + var dataObjArr = []; + var i = 0, vRoutersLength = 0; + + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + vRoutersLength = data['virtual-routers'].length; + for(i = 0; i < vRoutersLength; i++) { + reqUrl = '/virtual-router/' + data['virtual-routers'][i]['uuid']; + commonUtils.createReqObj(dataObjArr, reqUrl, global.HTTP_REQUEST_GET, + null, null, null, appData); + } + async.map(dataObjArr, + commonUtils.getAPIServerResponse(configApiServer.apiGet, false), + function(error, results) { + if (error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + commonUtils.handleJSONResponse(error, response, results); + } + ) +} + +/** + * @createVirtualRouters + * public function + * 1. URL /api/tenants/config/virtual-routers/ + * 2. creats a virtual router in config api server + */ +function createVirtualRouters (request, response, appData) +{ + var postData = request.body; + configApiServer.apiPost('/virtual-routers', postData, appData, + function(error, data) { + if(error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getVirtualRouters(request, response, appData); + }); +} + +/** + * @updateVirtualRouters + * public function + * 1. URL /api/tenants/config/virtual-router/:id + * 2. updates a virtual router in config api server + */ +function updateVirtualRouters (request, response, appData) +{ + var vRouterID = validateVirtualRouterId(request); + var postData = request.body; + configApiServer.apiPut('/virtual-router/' + vRouterID, postData, appData, + function(error, data) { + if(error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getVirtualRouters(request, response, appData); + }); +} + +/** + * @deleteVirtualRouters + * public function + * 1. URL /api/tenants/config/virtual-router/:id + * 2. deletes a virtual router in config api server + */ +function deleteVirtualRouters (request, response, appData) +{ + var vRouterID = validateVirtualRouterId(request); + var postData = request.body; + configApiServer.apiDelete('/virtual-router/' + vRouterID, appData, + function(error, data) { + if(error) { + commonUtils.handleJSONResponse(error, response, null); + return; + } + getVirtualRouters(request, response, appData); + }); +} + +function validateVirtualRouterId (request) +{ + var vRouterId = null; + if (!(vRouterId = request.param('id').toString())) { + error = new appErrors.RESTServerError('Add Virtual Router id'); + commonUtils.handleJSONResponse(error, response, null); + return; + } + return vRouterId; +} + + /* List all public function here */ + +exports.getVirtualRoutersList= getVirtualRoutersList; +exports.getVirtualRouters = getVirtualRouters; +exports.createVirtualRouters = createVirtualRouters; +exports.updateVirtualRouters = updateVirtualRouters; +exports.deleteVirtualRouters = deleteVirtualRouters; + \ No newline at end of file diff --git a/webroot/config/physicaldevices/virtualrouters/ui/js/virtualrouters_config.js b/webroot/config/physicaldevices/virtualrouters/ui/js/virtualrouters_config.js new file mode 100644 index 000000000..308ff77e7 --- /dev/null +++ b/webroot/config/physicaldevices/virtualrouters/ui/js/virtualrouters_config.js @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + +virtualRoutersConfigObj = new virtualRoutersConfig(); +function virtualRoutersConfig() { + //Variable Definations + var gridVirtualRouters; + + //Method Definations + this.load = load; + this.destroy = destroy; + + function load() { + var configTemplate = Handlebars.compile($("#virtualrouters-config-template").html()); + $(contentContainer).html(''); + $(contentContainer).html(configTemplate); + init(); + } + + function init() { + initComponents(); + initActions(); + fetchData(); + } + + function initComponents() { + //initializing the virtual routers Grid + $("#gridVirtualRouters").contrailGrid({ + header : { + title: { + text : 'Virtual Routers', + //cssClass : 'blue', + //icon : 'icon-list', + //iconCssClass : 'blue' + }, + customControls: ['', + ''] + }, + columnHeader : { + columns : [ + { + id : 'name', + field : 'name', + name : 'Name' + }, + { + id : 'ip_address', + field : 'ip_address', + name : 'IP Address' + }, + { + id : 'type', + field : 'type', + name : 'Type', + formatter: function(r, c, v, cd, dc) { + return formatVirtualRouterType(dc.type); + } + }] + }, + body : { + options : { + checkboxSelectable: { + onNothingChecked: function(e){ + $('#btnDeleteVirtualRouter').addClass('disabled-link'); + }, + onSomethingChecked: function(e){ + $('#btnDeleteVirtualRouter').removeClass('disabled-link'); + } + }, + forceFitColumns: true, + actionCell: [ + { + title: 'Edit', + iconClass: 'icon-edit', + onClick: function(rowIndex){ + virtualRouterEditWindow(rowIndex); + } + }, + { + title: 'Delete', + iconClass: 'icon-trash', + onClick: function(rowIndex){ + showVirtualRouterDelWindow(rowIndex); + } + } + ], + detail : { + template : $("#gridVirtualRoutersDetailTemplate").html() + } + }, + dataSource : { + data : [] + }, + statusMessages: { + loading: { + text: 'Loading Virtual Routers..' + }, + empty: { + text: 'No Virtual Routers.' + }, + errorGettingData: { + type: 'error', + iconClasses: 'icon-warning', + text: 'Error in getting Virtual Routers.' + } + } + } + }); + gridVirtualRouters = $("#gridVirtualRouters").data('contrailGrid'); + + //initializing add record window + $('#addVirtualRouterWindow').modal({backdrop:'static',keyboard:false,show:false}); + $('#addVirtualRouterWindow').find(".modal-header-title").text('Add Virtual Router'); + + //initializing virtual router type multi select + $('#msType').contrailDropdown({ + dataTextField:'text', + dataValueField:'value', + }); + + var msType = $('#msType').data('contrailDropdown'); + var msTypeDS = [{ text : 'None', value : 'none'}, + { text : 'Embedded', value : 'embedded'}, + //{ text : 'TOR Agent', value : 'tor-agent'}, + { text : 'TOR Service Node', value : 'tor-service-node'}, + ]; + msType.setData(msTypeDS); + + $('#confirmMainDelete').modal({backdrop:'static',keyboard:false,show:false}); + $('#confirmMainDelete').find(".modal-header-title").text('Confirm'); + } + + function initActions() { + $('#btnCreateVirtualRouter').click(function() { + $('#addVirtualRouterWindow').find(".modal-header-title").text('Add Virtual Router'); + populateCreateEditWindow('create'); + }); + + $('#btnAddVirtualRouterOk').click(function() { + if(validate()) { + $('#addVirtualRouterWindow').modal('hide'); + createUpdateVirtualRouter(); + } + }); + $('#btnDeleteVirtualRouter').click(function(){ + $('#confirmMainDelete').modal('show'); + }); + $('#btnCnfDelMainPopupOK').click(function(args){ + var selected_rows = gridVirtualRouters.getCheckedRows(); + $('#confirmMainDelete').modal("hide"); + deleteVirtualRouter(selected_rows); + }); + } + + window.showVirtualRouterDelWindow = function(index) { + $.contrailBootstrapModal ( + { + id: 'confirmRemove', + title: 'Remove', + body: '
Confirm Removing record
', + footer: [ + { + title: 'Cancel', + onclick: 'close', + }, + { + id: 'btnRemovePopupOK', + title: 'Confirm', + onclick: function(){ + var selected_row = gridVirtualRouters._dataView.getItem(index); + deleteVirtualRouter([selected_row]); + $('#confirmRemove').modal('hide'); + }, + className: 'btn-primary' + }] + }); + } + + function deleteVirtualRouter(selected_rows) { + $('#btnDeleteVirtualRouter').addClass('disabled-link'); + if(selected_rows && selected_rows.length > 0){ + var deleteAjaxs = []; + for(var i = 0;i < selected_rows.length;i++){ + var sel_row_data = selected_rows[i]; + deleteAjaxs[i] = $.ajax({ + url:'/api/tenants/config/virtual-router/' + sel_row_data['uuid'], + type:'DELETE' + }); + } + $.when.apply($,deleteAjaxs).then( + function(response){ + //all success + fetchData(); + }, + function(){ + //if at least one delete operation fails + var r = arguments; + showInfoWindow(r[0].responseText,r[2]); + fetchData(); + } + ); + } + } + + window.virtualRouterEditWindow = function(index) { + $('#addVirtualRouterWindow').find(".modal-header-title").text('Edit Virtual Router'); + gblSelRow = gridVirtualRouters._dataView.getItem(index); + populateCreateEditWindow('edit'); + } + + function populateCreateEditWindow(m) { + mode = m; + clearCreateEditWindow(); + if(mode === 'edit') { + $('#txtVirtualRouterName').val(gblSelRow.name); + $('#txtVirtualRouterName').attr('disabled','disabled'); + $('#txtIPAddress').val(gblSelRow.ip_address); + if(gblSelRow.actualType == '' || gblSelRow.actualType == 'empty') { + $('#msType').data('contrailDropdown').value('none'); + } else { + $('#msType').data('contrailDropdown').value(gblSelRow.actualType); + } + } + $('#addVirtualRouterWindow').modal('show'); + } + + function createUpdateVirtualRouter() { + var methodType = 'POST'; + var url = '/api/tenants/config/virtual-routers'; + if(mode === 'edit') { + methodType = 'PUT'; + url = '/api/tenants/config/virtual-router/' + gblSelRow.uuid + } + var name = $("#txtVirtualRouterName").val(); + var ipAddress = $("#txtIPAddress").val(); + var type = $("#msType").data('contrailDropdown').value(); + var postObject = {}; + + gridVirtualRouters._dataView.setData([]); + gridVirtualRouters.showGridMessage('loading'); + + postObject["virtual-router"] = {}; + postObject["virtual-router"]["fq_name"] = ["default-global-system-config", name]; + postObject["virtual-router"]["parent_type"] = "global-system-config"; + postObject["virtual-router"]["name"] = name; + postObject["virtual-router"]["virtual_router_ip_address"] = ipAddress; + if(type != 'none' && type != '' && type != 'empty') { + postObject["virtual-router"]["virtual_router_type"] = [type]; + } else { + postObject["virtual-router"]["virtual_router_type"] = []; + } + doAjaxCall(url, methodType, JSON.stringify(postObject), 'successHandlerForVirtualRouters', 'failureHandlerForVirtualRouters', null, null); + } + + function clearCreateEditWindow() { + $('#txtVirtualRouterName').removeAttr('disabled'); + $("#txtVirtualRouterName").val(''); + $("#txtIPAddress").val(''); + var msType = $("#msType").data('contrailDropdown'); + msType.value('none'); + } + + function fetchData() { + gridVirtualRouters._dataView.setData([]); + gridVirtualRouters.showGridMessage('loading'); + doAjaxCall('/api/tenants/config/virtual-routers','GET', null, 'successHandlerForVirtualRouters', 'failureHandlerForVirtualRouters', null, null); + } + + window.successHandlerForVirtualRouters = function(result) { + if(result.length > 0) { + var gridDS = []; + for(var i = 0; i < result.length;i++) { + var rowData = result[i]['virtual-router']; + var pRouters = []; + var pRouterBackRefs = rowData['physical_router_back_refs']; + if(pRouterBackRefs != null && pRouterBackRefs.length > 0) { + var pRouterBackRefsLen = pRouterBackRefs.length; + for(var j = 0; j < pRouterBackRefsLen; j++) { + pRouters.push(pRouterBackRefs[j].to[1]); + } + } + gridDS.push({ + uuid : rowData.uuid, + name : rowData.name, + ip_address : rowData.virtual_router_ip_address, + actualType : rowData.virtual_router_type != null ? rowData.virtual_router_type : '', + type : rowData.virtual_router_type != null && rowData.virtual_router_type.length > 0 ? rowData.virtual_router_type : ['embedded'], + physical_routers : pRouters.length > 0 ? pRouters : '-' + }); + } + + } else { + gridVirtualRouters.showGridMessage("empty"); + } + gridVirtualRouters._dataView.setData(gridDS); + } + + window.failureHandlerForVirtualRouters = function(error) { + //gridVirtualRouters.showGridMessage("errorGettingData"); + fetchData(); + } + + function validate() { + var name = $('#txtVirtualRouterName').val().trim(); + if(name === ""){ + showInfoWindow("Enter a Virtual Router Name","Input required"); + return false; + } + var ipAddress = $('#txtIPAddress').val().trim(); + if(!validateIPAddress(ipAddress)){ + showInfoWindow("Enter a valid IP address in xxx.xxx.xxx.xxx format","Input required"); + return false; + } + + // var typeValues = $('#msType').data('contrailDropdown').value(); + // if(typeValues != null && typeValues != '' && typeValues.length > 1) { + // showInfoWindow("Select a single Virtual Router Type","Input required"); + // return false; + // } + return true; + } + + function destroy() { + var configTemplate = $("#virtualrouters-config-template"); + if(isSet(configTemplate)) { + configTemplate.remove(); + configTemplate = $(); + } + var configDetailTemplate = $("#gridVirtualRoutersDetailTemplate"); + if(isSet(configDetailTemplate)) { + configDetailTemplate.remove(); + configDetailTemplate = $(); + } + } + + } + \ No newline at end of file diff --git a/webroot/config/physicaldevices/virtualrouters/ui/views/virtualrouters_config.view b/webroot/config/physicaldevices/virtualrouters/ui/views/virtualrouters_config.view new file mode 100644 index 000000000..26a490f56 --- /dev/null +++ b/webroot/config/physicaldevices/virtualrouters/ui/views/virtualrouters_config.view @@ -0,0 +1,84 @@ + + \ No newline at end of file diff --git a/webroot/config/port/api/parseURL.xml b/webroot/config/port/api/parseURL.xml new file mode 100644 index 000000000..b6f63fad5 --- /dev/null +++ b/webroot/config/port/api/parseURL.xml @@ -0,0 +1,20 @@ + + + + parseURLReq + process.mainModule.exports["corePath"] + '/src/serverroot/common/parseURLRequire' + + + portConfig + ./portConfig.api + + + /api/tenants/config/create-port + post + portconfig + portConfig.createPort + + + diff --git a/webroot/config/port/api/portConfig.api.js b/webroot/config/port/api/portConfig.api.js new file mode 100644 index 000000000..2f83503e3 --- /dev/null +++ b/webroot/config/port/api/portConfig.api.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + +var commonUtils = require(process.mainModule.exports["corePath"] + + '/src/serverroot/utils/common.utils'); +var configApiServer = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/configServer.api'); +var nwMgr = require(process.mainModule.exports["corePath"] + + '/src/serverroot/common/networkmanager.api'); +var appErrors = require(process.mainModule.exports["corePath"] + + '/src/serverroot/errors/app.errors'); +function createPort (req, res, appData) +{ + var body = req.body; + var vnUUID = body['vnUUID']; + var fixedIP = body['fixedIPs']; + var macAddress = body['macAddress']; + var postData = {}; + postData['port'] = {}; + postData['port']['admin_state_up'] = true; + if (null != macAddress) { + postData['port']['mac_address'] = macAddress; + } + if ((null != fixedIP) && (fixedIP instanceof Array)) { + postData['port']['fixed_ips'] = []; + var fixedIPLen = fixedIP.length; + for (var i = 0; i < fixedIPLen; i++) { + postData['port']['fixed_ips'].push({'ip_address': fixedIP[i]}); + } + } + /* Now get the network ID */ + var vnURL = '/virtual-network/' + vnUUID; + configApiServer.apiGet(vnURL, appData, function(err, vnData) { + if ((null != err) || (null == vnData)) { + var errStr = 'VN UUID not found'; + error = new appErrors.RESTServerError(errStr); + commonUtils.handleJSONResponse(error, res, errStr); + return; + } + postData['port']['network_id'] = vnUUID; + var project = vnData['virtual-network']['fq_name'][1]; + nwMgr.createNetworkPort(req, postData, project, function(err, results) { + if ((null != err) || (null == results)) { + commonUtils.handleJSONResponse(err, res, null); + return; + } + var vmiID = results['port']['id']; + var vmiURL = '/virtual-machine-interface/' + vmiID; + configApiServer.apiGet(vmiURL, appData, function(err, vmiData) { + commonUtils.handleJSONResponse(err, res, vmiData); + }); + }); + }); +} + +exports.createPort = createPort; + diff --git a/webroot/menu.xml b/webroot/menu.xml index f62b7ce9c..d6e732239 100644 --- a/webroot/menu.xml +++ b/webroot/menu.xml @@ -320,6 +320,19 @@ and need to add the iconClass tag wherever we need to show some icons Configure Link Local Services + + + config_pd_virtualRouters + + + /config/physicaldevices/virtualrouters/ui + virtualrouters_config.js + virtualrouters_config.view + virtualRoutersConfigObj + + + Configure Virtual Routers + + + + config_pd + + + member + + + openstack + + + icon-globe + + + + config_pd_physicalRouters + + + /config/physicaldevices/physicalrouters/ui + physicalrouters_config.js + physicalrouters_config.view + physicalRoutersConfigObj + + + Configure Physical Routers + + + + config_pd_interfaces + + + /config/physicaldevices/physicalinterfaces/ui + physicalinterfaces_config.js + physicalinterfaces_config.view + physicalInterfacesConfigObj + + + Configure Interfaces + + + @@ -417,7 +471,7 @@ and need to add the iconClass tag wherever we need to show some icons Security Groups - + @@ -512,6 +566,7 @@ and need to add the iconClass tag wherever we need to show some icons +