diff --git a/v2/src/app/appDev.js b/v2/src/app/appDev.js index bdfe737..58b291e 100644 --- a/v2/src/app/appDev.js +++ b/v2/src/app/appDev.js @@ -90,6 +90,12 @@ compassAppDev.run(function($httpBackend, settings, $http) { "id": 3, "template": "multinodes.tmpl", "name": "multinodes" + }, { + "roles": [], + "display_name": "Multi-node Cluster with HA", + "id": 3, + "template": "ha.tmpl", + "name": "HA-multinodes" }], "name": "openstack_icehouse", "distributed_system_id": 1, diff --git a/v2/src/app/services.js b/v2/src/app/services.js index 9d3cac8..dd1626b 100644 --- a/v2/src/app/services.js +++ b/v2/src/app/services.js @@ -1,4 +1,4 @@ -define(['angular','uiBootstrap'], function(ng, uiBootstrap) { +define(['angular', 'uiBootstrap'], function(ng, uiBootstrap) { var servicesModule = angular.module('compass.services', ['ui.bootstrap']); // stateService is used for dynamically add/edit state /* .service('stateService', ['$state', @@ -34,7 +34,7 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { return $http.post(settings.apiUrlBase + '/users/login', angular.toJson(user)); }; - this.logout = function(){ + this.logout = function() { return $http.post(settings.apiUrlBase + '/users/logout', null); } @@ -246,11 +246,11 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { }; this.monitorMetricsTagName = function(id, selectedMetrics) { - var metrics = '{"metrics":[{"tags":{},"name":"'+selectedMetrics+'"}],"cache_time":0,"start_absolute":0}'; - return $http.post(settings.monitoringUrlBase + '/clusters/'+ id +'/datapointtags',metrics); + var metrics = '{"metrics":[{"tags":{},"name":"' + selectedMetrics + '"}],"cache_time":0,"start_absolute":0}'; + return $http.post(settings.monitoringUrlBase + '/clusters/' + id + '/datapointtags', metrics); }; - this.monitorMetricsQuery = function(clusterId,query) { - return $http.post(settings.monitoringUrlBase + '/clusters/'+clusterId+'/datapoints',query); + this.monitorMetricsQuery = function(clusterId, query) { + return $http.post(settings.monitoringUrlBase + '/clusters/' + clusterId + '/datapoints', query); }; this.monitorMetricsTree = function() { @@ -382,8 +382,7 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { }; metrics.setEndRelative = function(new_end_relative) { - if(new_end_relative) - { + if (new_end_relative) { console.log(new_end_relative) metrics.end_relative.value = new_end_relative.value; metrics.end_relative.unit = new_end_relative.unit; @@ -461,8 +460,7 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { return metrics.displayData.length - 1; }; metrics.updateDisplayData = function(data) { - if(data.errors) - { + if (data.errors) { alert(data.errors[0]); return -1; } @@ -505,6 +503,8 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { wizard.console_credentials = {}; wizard.network_mapping = {}; wizard.ceph_config = {}; + wizard.neutron_config = {}; + wizard.ha_config = {}; }; wizard.init(); @@ -513,6 +513,9 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { //wizard.setClusterInfo(config.cluster); wizard.setInterfaces(config.interface); wizard.setGeneralConfig(config.general); + + // wizard.setNeutronConfig(config.neutron_config); + wizard.setPartition(config.partition); wizard.setServerCredentials(config.server_credentials); wizard.setServiceCredentials(config.service_credentials); @@ -521,6 +524,13 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { if (config.ceph_config) { wizard.setCephConfig(config.ceph_config); } + if (config.neutron_config) { + wizard.setNeutronConfig(config.neutron_config); + } + + if (config.ha_config) { + wizard.setHighAvailabilityConfig(config.ha_config) + } }; wizard.setClusterInfo = function(cluster) { @@ -653,19 +663,33 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { return angular.copy(wizard.ceph_config); }; + wizard.setNeutronConfig = function(neutronConfig) { + wizard.neutron_config = neutronConfig; + } + + wizard.getNeutronConfig = function() { + return angular.copy(wizard.neutron_config); + } + wizard.setHighAvailabilityConfig = function(haConfig) { + wizard.ha_config = haConfig; + } + wizard.getHighAvailabilityConfig = function() { + return angular.copy(wizard.ha_config); + } + return wizard; } ]); - servicesModule.service('authService', ['$http', 'dataService','rememberMe', - function($http, dataService,rememberMe) { + servicesModule.service('authService', ['$http', 'dataService', 'rememberMe', + function($http, dataService, rememberMe) { this.isAuthenticated = false; this.setLogin = function(remember) { this.isAuthenticated = true; - rememberMe.setCookies("isAuthenticated","true",0.0833,Boolean(remember)); + rememberMe.setCookies("isAuthenticated", "true", 0.0833, Boolean(remember)); }; - this.setLogout = function(){ + this.setLogout = function() { this.isAuthenticated = false; rememberMe.setCookies("isAuthenticated", "false", -30); } @@ -675,24 +699,24 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { }; this.logout = function() { - return dataService.logout(); - }; + return dataService.logout(); + }; } ]); - servicesModule.service('modalService',function($modal){ - this.show = function(message){ + servicesModule.service('modalService', function($modal) { + this.show = function(message) { return $modal.open({ templateUrl: 'messagemodal.html', controller: 'errorHandlingModalController', - resolve:{ - message: function(){ + resolve: { + message: function() { return message; } } }); } }); - servicesModule.factory('authenticationInterceptor', ['$q', '$location','$injector', + servicesModule.factory('authenticationInterceptor', ['$q', '$location', '$injector', function($q, $location, $injector) { return { response: function(response) { @@ -702,13 +726,11 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { if (rejection.status == 401) { console.log("Response Error 401", rejection); $location.path('/login'); - } - else{ - if(rejection.config.url && rejection.config.url != "/api/users/login") - { + } else { + if (rejection.config.url && rejection.config.url != "/api/users/login") { var modal = $injector.get("modalService"); modal.show(rejection); - } + } } return $q.reject(rejection); @@ -737,11 +759,10 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1); - if (c.indexOf(name) != -1) - { + if (c.indexOf(name) != -1) { console.log("inside") return c.substring(name.length, c.length); - } + } } return ""; diff --git a/v2/src/app/wizard/global.tpl.html b/v2/src/app/wizard/global.tpl.html index cc1ccba..038d1c3 100644 --- a/v2/src/app/wizard/global.tpl.html +++ b/v2/src/app/wizard/global.tpl.html @@ -42,7 +42,6 @@
@@ -65,7 +64,7 @@
diff --git a/v2/src/app/wizard/package_config.tpl.html b/v2/src/app/wizard/package_config.tpl.html index f6378a4..40a82d2 100644 --- a/v2/src/app/wizard/package_config.tpl.html +++ b/v2/src/app/wizard/package_config.tpl.html @@ -157,7 +157,7 @@
-
+
+ + + Neutron Configuration + + +
+
+ + +
+
+ +
+ +
+
+
+
+
+ +
+ + + + + + + + + + + + e.g. 1:1000 + +
+
+
+ +
+
+ +
+ + + + + + + + + + + + e.g. physnet1:2700:2999 + +
+
+
+ +
+
+ +
+ + + + + + + + + + + + e.g. physnet1:br-eth1 + + +
+
+
+ + +
+
+
+ + + + High Availability Configuration + +
+
+
+ +
+ +
+ +
+ + Invalid IP Address + +
+
+
+
+
+
+
+
-
\ No newline at end of file +
diff --git a/v2/src/app/wizard/wizard.js b/v2/src/app/wizard/wizard.js index a32af65..24b89dc 100644 --- a/v2/src/app/wizard/wizard.js +++ b/v2/src/app/wizard/wizard.js @@ -69,14 +69,12 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne $scope.adapters = adaptersData; - angular.forEach($scope.adapters, function(adapter) { - if (adapter.id == $scope.cluster.adapter_id) { - $scope.currentAdapterName = adapter.name; - } - }); + $scope.currentAdapterName = $scope.cluster.adapter_name; + $scope.currentFlavor = $scope.cluster.flavor.name; // get pre-config data for wizard and set wizard steps based on different adapters var oldConfig = clusterConfigData; + $scope.steps = []; if ($stateParams.config == "true") { dataService.getWizardPreConfig().success(function(data) { @@ -108,7 +106,6 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne if (preConfigData) { wizardFactory.preConfig(preConfigData); - if (oldConfig.os_config) { if (oldConfig.os_config.general) { wizardFactory.setGeneralConfig(oldConfig.os_config.general); @@ -135,6 +132,12 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne if (oldConfig.package_config.ceph_config) { wizardFactory.setCephConfig(oldConfig.package_config.ceph_config); } + if (oldConfig.package_config.neutron_config) { + wizardFactory.setNeutronConfig(oldConfig.package_config.neutron_config); + } + if (oldConfig.package_config.ha_config) { + wizardFactory.setNeutronConfig(oldConfig.package_config.ha_config); + } } } }); @@ -528,11 +531,14 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne }); wizardModule.controller('globalCtrl', function($scope, wizardFactory, dataService, $q) { + + var cluster = wizardFactory.getClusterInfo(); $scope.general = wizardFactory.getGeneralConfig(); $scope.server_credentials = wizardFactory.getServerCredentials(); + if (!$scope.general["dns_servers"]) { $scope.general["dns_servers"] = [""]; } @@ -580,6 +586,8 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne } }); + + $scope.commit = function(sendRequest) { if (!sendRequest) { var commitState = { @@ -600,6 +608,7 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne } } }; + if ($scope.generalForm.$valid) { dataService.updateClusterConfig(cluster.id, osGlobalConfig).success(function(configData) { wizardFactory.setGeneralConfig($scope.general); @@ -1241,6 +1250,38 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne $scope.service_credentials = angular.copy($scope.originalServiceData); } + //High Availability Config + $scope.haAccordion = {}; + $scope.ha_config = wizardFactory.getHighAvailabilityConfig(); + + if (!$scope.ha_config["ha_proxy"]) { + $scope.ha_config["ha_proxy"] = {}; + $scope.ha_config["ha_proxy"]["vip"] = [""]; + } + + //Neutron Config + $scope.neutronAccordion = {}; + $scope.neutron_config = wizardFactory.getNeutronConfig(); + + $scope.addValue = function(key) { + $scope.neutron_config.openvswitch[key].push(""); + }; + + if (!$scope.neutron_config["openvswitch"]) { + $scope.neutron_config["openvswitch"] = {}; + $scope.neutron_config["openvswitch"]["tunnel_id_ranges"] = [""]; + $scope.neutron_config["openvswitch"]["network_vlan_ranges"] = [""]; + $scope.neutron_config["openvswitch"]["bridge_mappings"] = [""]; + } + // else { + // if (!$scope.neutronConfig["openvswitch"]["tunnel_id_ranges"]) $scope.neutronConfig["openvswitch"]["tunnel_id_ranges"] = [""]; + // if (!$scope.neutronConfig["openvswitch"]["network_vlan_ranges"]) $scope.neutronConfig["openvswitch"]["network_vlan_ranges"] = [""]; + // if (!$scope.neutronConfig["openvswitch"]["bridge_mapping"]) $scope.neutronConfig["openvswitch"]["bridge_mapping"] = [""]; + // if (!$scope.neutronConfig["openvswitch"]["tenant_network_type"]) $scope.neutronConfig["openvswitch"]["tenant_network_type"] = [""]; + // } + + // console.log($scope.neutronConfig); + // Ceph Config $scope.cephAccordion = {}; /*$scope.cephConfig = { @@ -1250,6 +1291,24 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne };*/ $scope.cephConfig = wizardFactory.getCephConfig(); + + + // $scope.$watch(function() { + // return wizardFactory.getCommitState() + // }, function(newCommitState, oldCommitState) { + + // if (newCommitState !== undefined) { + // if (newCommitState.state == "triggered") { + // $scope.commit(newCommitState.sendRequest); + // } + // } + // }); + + + + $scope.form = {}; + + $scope.commit = function(sendRequest) { if (!sendRequest) { var commitState = { @@ -1269,28 +1328,92 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne } } }; - if ($scope.currentAdapterName == "ceph_openstack_icehouse") { - targetSysConfigData["package_config"]["ceph_config"] = $scope.cephConfig; + + if ($scope.currentAdapterName == "ceph_openstack_icehouse" || $scope.currentAdapterName == "openstack_icehouse") { + + if ($scope.currentAdapterName == "ceph_openstack_icehouse") { + targetSysConfigData["package_config"]["ceph_config"] = $scope.cephConfig; + } + + if ($scope.currentAdapterName == "openstack_icehouse" && $scope.currentFlavor == "HA-multinodes") { + targetSysConfigData["package_config"]["ha_proxy"] = {}; + targetSysConfigData["package_config"]["ha_proxy"]["vip"] = $scope.ha_config.ha_proxy.vip; + + } + + targetSysConfigData["package_config"]["neutron_config"] = {}; + targetSysConfigData["package_config"]["neutron_config"]["openvswitch"] = {}; + + if ($scope.neutron_config.openvswitch.tenant_network_type == "gre") { + targetSysConfigData["package_config"]["neutron_config"]["openvswitch"]["tenant_network_type"] = "gre"; + targetSysConfigData["package_config"]["neutron_config"]["openvswitch"]["tunnel_id_ranges"] = $scope.neutron_config.openvswitch.tunnel_id_ranges; + } + if ($scope.neutron_config.openvswitch.tenant_network_type == "vlan") { + targetSysConfigData["package_config"]["neutron_config"]["openvswitch"]["tenant_network_type"] = "vlan"; + targetSysConfigData["package_config"]["neutron_config"]["openvswitch"]["network_vlan_ranges"] = $scope.neutron_config.openvswitch.network_vlan_ranges; + targetSysConfigData["package_config"]["neutron_config"]["openvswitch"]["bridge_mappings"] = $scope.neutron_config.openvswitch.bridge_mappings; + } } + if ($scope.currentAdapterName == "ceph_firefly") { targetSysConfigData["package_config"] = {}; targetSysConfigData["package_config"]["ceph_config"] = $scope.cephConfig; } - dataService.updateClusterConfig(cluster.id, targetSysConfigData).success(function(data) { - var commitState = { - "name": "package_config", - "state": "success", - "message": "" - }; - wizardFactory.setCommitState(commitState); - }).error(function(response) { - var commitState = { - "name": "package_config", - "state": "error", - "message": response - }; - wizardFactory.setCommitState(commitState); + + $scope.areValid = true; + $scope.notValidformName = ""; + + angular.forEach($scope.form, function(formdt, key) { + if ($scope.form[key].$valid == false) { + $scope.areValid = false; + $scope.notValidformName = key; + } }); + + + if ($scope.areValid) { + + dataService.updateClusterConfig(cluster.id, targetSysConfigData).success(function(data) { + + wizardFactory.setNeutronConfig($scope.neutron_config); + wizardFactory.setHighAvailabilityConfig($scope.ha_config); + + var commitState = { + "name": "package_config", + "state": "success", + "message": "" + }; + wizardFactory.setCommitState(commitState); + }).error(function(response) { + var commitState = { + "name": "package_config", + "state": "error", + "message": response + }; + wizardFactory.setCommitState(commitState); + }); + + } else { + var message = {}; + if ($scope.form[$scope.notValidformName].$error.required) { + message = { + "message": "The required(*) fields are empty!" + }; + } else if ($scope.form[$scope.notValidformName].$error.pattern) { + message = { + "message": "The required(*) fields are not in correct patterns!" + }; + } + + var commitState = { + "name": "package_config", + "state": "invalid", + "message": message + }; + wizardFactory.setCommitState(commitState); + } + + }; }); @@ -1964,4 +2087,4 @@ define(['uiRouter', 'angularTable', 'angularDragDrop', 'angularTouch', 'ngSpinne }, true); }; -}); \ No newline at end of file +});