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
+