From ae9da1d1b4f20df488550831454433140c94967a Mon Sep 17 00:00:00 2001 From: jiahuay Date: Thu, 10 Jul 2014 16:13:46 -0700 Subject: [PATCH] Update role assignment and network mapping. Use $q to fix multiple asynchronous ajax calls. Change-Id: Ifc18fcaa0a4ab1c70a91d4f2a134d5e302fb8ff6 --- v2/assets/css/style.css | 26 ++ v2/data/config.json | 63 +-- v2/data/machine_host_columns.json | 49 ++- v2/index.html | 2 + v2/src/app/appDev.js | 65 ++- v2/src/app/services.js | 76 +++- v2/src/app/wizard/global.tpl.html | 152 +++++-- v2/src/app/wizard/network.tpl.html | 176 +++++--- v2/src/app/wizard/network_mapping.tpl.html | 99 ++--- v2/src/app/wizard/role_assignment.tpl.html | 48 ++- v2/src/app/wizard/security.tpl.html | 24 +- v2/src/app/wizard/wizard.js | 442 +++++++++++++++------ v2/vendor/angular-dragdrop/draganddrop.js | 201 ++++++++++ 13 files changed, 1057 insertions(+), 366 deletions(-) create mode 100644 v2/vendor/angular-dragdrop/draganddrop.js diff --git a/v2/assets/css/style.css b/v2/assets/css/style.css index 6381024..78d87f2 100644 --- a/v2/assets/css/style.css +++ b/v2/assets/css/style.css @@ -69,6 +69,32 @@ select { } .partition-chart { padding-top: 30px; +} +.margin-top-minus10 { + margin-top: -10px !important; +} +.drag-enter { + background: none repeat scroll 0 0 #F0F9FF; + border: 2px dashed #BED2DB !important; + box-sizing: border-box; + margin: 5px 0; + min-height: 50px; + padding: 0; +} +.network-draggable { + position: relative; + width: 200px; +} +.network-placeholder { + min-height: 200px; +} +.interface-placeholder { + border: 1px solid #BED2DB; + box-sizing: border-box; + margin: 5px 0; + min-height: 50px; + padding: 10px; +} .btn-clstr { border: none !important; background-color: inherit!important; diff --git a/v2/data/config.json b/v2/data/config.json index 859e0f6..c71c7c4 100644 --- a/v2/data/config.json +++ b/v2/data/config.json @@ -3,33 +3,25 @@ "id": 10, "name": "demo", "adapter_id": 1, - "os_id":1 + "os_id": 1 }, "partition": { + "/swap": { + "size_percentage": 10 + }, + "/boot": { + "size_percentage": 10 + }, "/var": { "size_percentage": 30 }, "/home": { - "size_percentage": 20 - }, - "/tmp": { - "size_percentage": 10 + "size_percentage": 30 }, "/spare": { - "size_percentage": 40 + "size_percentage": 20 } }, - "subnet": [{ - "name": "subnet1", - "subnet": "192.168.10.1", - "netmask": "255.255.255.0", - "subnet_id": 1 - }, { - "name": "subnet2", - "subnet": "172.1.100.1", - "netmask": "255.255.255.0", - "subnet_id": 2 - }], "interface": { "eth0": { "subnet_id": 1, @@ -49,14 +41,16 @@ } }, "general": { - "timezone": "-8.00", + "timezone": "-4.00", "language": "en", - "http_proxy": "", + "http_proxy": [""], + "https_proxy": [""], + "default_no_proxy":[""], "ntp_server": "", - "domain": "compass.com", - "gateway": "172.19.100.1", "dns_servers": [""], - "search_path": ["compass.com"] + "search_path": ["compass.com"], + "domain": "compass.com", + "default_gateway": "172.19.100.1" }, "server_credentials": { "username": "admin", @@ -87,11 +81,11 @@ "username": "ceilometer", "password": "ceilometer" }, - "super": { + "mysql": { "username": "root", "password": "root" }, - "volumn": { + "volume": { "username": "cinder", "password": "cinder" } @@ -125,10 +119,27 @@ "username": "swift", "password": "swift" }, - "volumn": { + "volume": { "username": "cinder", "password": "cinder" } + }, + "network_mapping": { + "management": { + "display": "Management Network", + "mapping_interface": "" + }, + "tenant": { + "display": "Tenant Network", + "mapping_interface": "" + }, + "storage": { + "display": "Storage Network", + "mapping_interface": "" + }, + "public": { + "display": "Public Network", + "mapping_interface": "" + } } - } diff --git a/v2/data/machine_host_columns.json b/v2/data/machine_host_columns.json index e115a68..4fe91c9 100644 --- a/v2/data/machine_host_columns.json +++ b/v2/data/machine_host_columns.json @@ -17,7 +17,7 @@ "visible": true }, { "title": "Hostname", - "field": "hostname", + "field": "name", "visible": true }, { "title": "Clusters", @@ -58,7 +58,7 @@ "visible": false }, { "title": "Hostname", - "field": "hostname", + "field": "name", "visible": true }, { "title": "Clusters", @@ -80,5 +80,50 @@ "title": "State", "field": "state", "visible": false + }], + "review": [{ + "title": "Host MAC Addr", + "field": "mac", + "visible": true + }, { + "title": "Switch IP", + "field": "switch_ip", + "visible": true + }, { + "title": "Port", + "field": "port", + "visible": true + }, { + "title": "VLAN", + "field": "vlan", + "visible": false + }, { + "title": "Hostname", + "field": "name", + "visible": true + }, { + "title": "Clusters", + "field": "clusters", + "visible": false + }, { + "title": "OS", + "field": "os", + "visible": false + }, { + "title": "OS Reinstall", + "field": "os_installed", + "visible": false + }, { + "title": "Adapter", + "field": "adapter", + "visible": false + }, { + "title": "Roles", + "field": "roles", + "visible": true + }, { + "title": "State", + "field": "state", + "visible": false }] } diff --git a/v2/index.html b/v2/index.html index f7e4468..684c61d 100644 --- a/v2/index.html +++ b/v2/index.html @@ -21,8 +21,10 @@ + + diff --git a/v2/src/app/appDev.js b/v2/src/app/appDev.js index dda85cb..e2ef34f 100644 --- a/v2/src/app/appDev.js +++ b/v2/src/app/appDev.js @@ -58,6 +58,38 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, adapters, {}]; }); + $httpBackend.whenGET(/\.*\/adapters\/[1-9][0-9]*/).respond(function(method, url, data) { + console.log(method, url); + var adapter = { + "id": 1, + "name": "openstack", + "display": "OpenStack", + "os_installer": "cobbler", + "package_installer": "chef", + "roles": [{ + "display_name": "Compute", + "name": "os-compute-worker" + }, { + "display_name": "Controller", + "name": "os-controller" + }, { + "display_name": "Network", + "name": "os-network" + }, { + "display_name": "Storage", + "name": "os-block-storage-worker" + }], + "compatible_os": [{ + "name": "CentOs", + "os_id": 1 + }, { + "name": "Ubuntu", + "os_id": 2 + }] + }; + return [200, adapter, {}]; + }); + $httpBackend.whenGET(settings.apiUrlBase + '/machines-hosts').respond(function(method, url, data) { console.log(method, url); var servers = [{ @@ -66,7 +98,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "switch_ip": "172.29.8.40", "vlan": "1", "port": "1", - "hostname": "sv-1", + "name": "sv-1", "clusters": ["cluster1", "cluster2"], "os": "CentOS", "adapter": "OpenStack", @@ -91,7 +123,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "switch_ip": "172.29.8.40", "vlan": "2", "port": "2", - "hostname": "sv-2", + "name": "sv-2", "clusters": ["cluster1"], "os": "CentOS", "adapter": "OpenStack", @@ -175,7 +207,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, config, {}]; }); - $httpBackend.whenGET(/\.*\/clusters\/[1-9][0-9]*\/subnet-config/).respond(function(method, url, data) { + $httpBackend.whenGET(settings.apiUrlBase + '/subnetworks').respond(function(method, url, data) { console.log(method, url); var subnetworks = [{ "subnet_id": 1, @@ -191,7 +223,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, subnetworks, {}]; }); - $httpBackend.whenPOST(/\.*\/clusters\/[1-9][0-9]*\/subnet-config/).respond(function(method, url, data) { + $httpBackend.whenPOST(settings.apiUrlBase + '/subnetworks').respond(function(method, url, data) { console.log(method, url, data); var subnetConfig = JSON.parse(data); @@ -201,7 +233,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, subnetConfig, {}]; }); - $httpBackend.whenPUT(/\.*\/clusters\/[1-9][0-9]*\/subnet-config\/[1-9][0-9]*/).respond(function(method, url, data) { + $httpBackend.whenPUT(/\.*\/subnetworks\/[1-9][0-9]*/).respond(function(method, url, data) { console.log(method, url, data); var subnetConfig = JSON.parse(data); @@ -210,6 +242,8 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, subnetConfig, {}]; }); + // keep routing table for later use + /* $httpBackend.whenPOST(/\.*\/clusters\/[1-9][0-9]*\/routing-table/).respond(function(method, url, data) { console.log(method, url, data); @@ -220,7 +254,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, routingTable, {}]; }); - $httpBackend.whenPUT(/\.*\/clusters\/[1-9][0-9]*\/routing-table\/[1-9][0-9]*/).respond(function(method, url, data) { + $httpBackend.whenPUT(/\.*\/clusters\/[1-9][0-9]*\/routing-table\/[1-9][0-9]/).respond(function(method, url, data) { console.log(method, url, data); var routingTable = JSON.parse(data); @@ -228,6 +262,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { console.log(routingTable); return [200, routingTable, {}]; }); + */ $httpBackend.whenPOST(/\.*\/clusters\/[1-9][0-9]*\/action/).respond(function(method, url, data) { console.log(method, url, data); @@ -243,10 +278,28 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, actionResponse, {}]; }); + $httpBackend.whenPUT(/\.*\/hosts\/[1-9][0-9]*/).respond(function(method, url, data) { + console.log(method, url, data); + var host_config = JSON.parse(data); + return [200, host_config, {}]; + }); + $httpBackend.whenPOST(/\.*\/hosts\/[1-9][0-9]*\/network/).respond(function(method, url, data) { console.log(method, url, data); var network = JSON.parse(data); network.id = Math.floor((Math.random() * 100) + 1); return [200, network, {}]; }); + + $httpBackend.whenPUT(/\.*\/hosts\/[1-9][0-9]*\/network\/[1-9][0-9]/).respond(function(method, url, data) { + console.log(method, url, data); + var network = JSON.parse(data); + return [200, network, {}]; + }); + + $httpBackend.whenPUT(/\.*\/clusters\/[1-9][0-9]*\/hosts\/[1-9][0-9]*\/config/).respond(function(method, url, data) { + console.log(method, url, data); + var config = JSON.parse(data); + return [200, config, {}]; + }); }); diff --git a/v2/src/app/services.js b/v2/src/app/services.js index 50d1fdf..1c78c9d 100644 --- a/v2/src/app/services.js +++ b/v2/src/app/services.js @@ -58,6 +58,10 @@ angular.module('compass.services', []) return $http.get(settings.apiUrlBase + '/adapters'); }; + this.getAdapter = function(id) { + return $http.get(settings.apiUrlBase + '/adapters/' + id); + }; + this.createCluster = function(cluster) { return $http.post(settings.apiUrlBase + '/clusters', angular.toJson(cluster)); }; @@ -70,18 +74,20 @@ angular.module('compass.services', []) return $http.put(settings.apiUrlBase + '/clusters/' + id + '/config', angular.toJson(config)); }; - this.getClusterSubnetConfig = function(id) { - return $http.get(settings.apiUrlBase + '/clusters/' + id + '/subnet-config'); + this.getSubnetConfig = function() { + return $http.get(settings.apiUrlBase + '/subnetworks'); }; - this.postClusterSubnetConfig = function(id, subnet_config) { - return $http.post(settings.apiUrlBase + '/clusters/' + id + '/subnet-config', angular.toJson(subnet_config)); + this.postSubnetConfig = function(subnet_config) { + return $http.post(settings.apiUrlBase + '/subnetworks', angular.toJson(subnet_config)); }; - this.putClusterSubnetConfig = function(id, subnetId, subnet_config) { - return $http.put(settings.apiUrlBase + '/clusters/' + id + '/subnet-config/' + subnetId, angular.toJson(subnet_config)); + this.putSubnetConfig = function(id, subnet_config) { + return $http.put(settings.apiUrlBase + '/subnetworks/' + id, angular.toJson(subnet_config)); }; + // keep routing table for later use + /* this.postRoutingTable = function(id, routing_table) { return $http.post(settings.apiUrlBase + '/clusters/' + id + '/routing-table', angular.toJson(routing_table)); }; @@ -89,6 +95,7 @@ angular.module('compass.services', []) this.putRoutingTable = function(id, routingId, routing_table) { return $http.put(settings.apiUrlBase + '/clusters/' + id + '/routing-table/' + routingId, angular.toJson(routing_table)); }; + */ this.getTimezones = function() { return $http.get(settings.metadataUrlBase + '/timezone.json'); @@ -98,9 +105,21 @@ angular.module('compass.services', []) return $http.post(settings.apiUrlBase + '/clusters/' + id + '/action', angular.toJson(actions)); }; + this.putHost = function(id, config) { + return $http.put(settings.apiUrlBase + '/hosts/' + id, angular.toJson(config)); + }; + this.postHostNetwork = function(id, network) { return $http.post(settings.apiUrlBase + '/hosts/' + id + '/network', angular.toJson(network)); }; + + this.putHostNetwork = function(id, networkId, network) { + return $http.put(settings.apiUrlBase + '/hosts/' + id + '/network/' + networkId, angular.toJson(network)); + }; + + this.updateClusterHostConfig = function(clusterId, hostId, config) { + return $http.put(settings.apiUrlBase + '/hosts/' + clusterId + '/hosts/' + hostId + '/config', angular.toJson(config)); + }; } ]) @@ -121,20 +140,23 @@ angular.module('compass.services', []) wizard.generalConfig = {}; wizard.interfaces = {}; wizard.partition = {}; + wizard.server_credentials = {}; wizard.service_credentials = {}; wizard.management_credentials = {}; + wizard.network_mapping = {}; }; wizard.init(); wizard.preConfig = function(config) { wizard.setClusterInfo(config.cluster); - wizard.setSubnetworks(config.subnet); wizard.setInterfaces(config.interface); wizard.setGeneralConfig(config.general); wizard.setPartition(config.partition); + wizard.setServerCredentials(config.server_credentials); wizard.setServiceCredentials(config.service_credentials); wizard.setManagementCredentials(config.management_credentials); + wizard.setNetworkMapping(config.network_mapping); }; wizard.setClusterInfo = function(cluster) { @@ -142,7 +164,7 @@ angular.module('compass.services', []) }; wizard.getClusterInfo = function() { - return wizard.cluster; + return angular.copy(wizard.cluster); }; wizard.setSteps = function(steps) { @@ -150,7 +172,7 @@ angular.module('compass.services', []) }; wizard.getSteps = function() { - return wizard.steps; + return angular.copy(wizard.steps); }; wizard.setCommitState = function(commitState) { @@ -166,7 +188,7 @@ angular.module('compass.services', []) }; wizard.getAllMachinesHost = function() { - return wizard.allServers; + return angular.copy(wizard.allServers); }; wizard.setServers = function(servers) { @@ -174,7 +196,7 @@ angular.module('compass.services', []) }; wizard.getServers = function() { - return wizard.servers; + return angular.copy(wizard.servers); }; wizard.setAdapter = function(adapter) { //// @@ -182,7 +204,7 @@ angular.module('compass.services', []) }; wizard.getAdapter = function() { ///// - return wizard.adapter; + return angular.copy(wizard.adapter); }; wizard.setGeneralConfig = function(config) { @@ -190,7 +212,7 @@ angular.module('compass.services', []) }; wizard.getGeneralConfig = function() { - return wizard.generalConfig; + return angular.copy(wizard.generalConfig); }; wizard.setSubnetworks = function(subnetworks) { @@ -198,9 +220,11 @@ angular.module('compass.services', []) }; wizard.getSubnetworks = function() { - return wizard.subnetworks; + return angular.copy(wizard.subnetworks); }; + // keey routing table for later use + /* wizard.setRoutingTable = function(routingTb) { wizard.routingtable = routingTb; }; @@ -208,13 +232,14 @@ angular.module('compass.services', []) wizard.getRoutingTable = function() { return wizard.routingtable; }; + */ wizard.setInterfaces = function(interfaces) { wizard.interfaces = interfaces; }; wizard.getInterfaces = function() { - return wizard.interfaces; + return angular.copy(wizard.interfaces); }; wizard.setPartition = function(partition) { @@ -222,15 +247,22 @@ angular.module('compass.services', []) }; wizard.getPartition = function() { - return wizard.partition; + return angular.copy(wizard.partition); }; + wizard.setServerCredentials = function(credentials) { + wizard.server_credentials = credentials; + }; + + wizard.getServerCredentials = function() { + return angular.copy(wizard.server_credentials); + } wizard.setServiceCredentials = function(credentials) { wizard.service_credentials = credentials; }; wizard.getServiceCredentials = function() { - return wizard.service_credentials; + return angular.copy(wizard.service_credentials); }; wizard.setManagementCredentials = function(credentials) { @@ -238,7 +270,15 @@ angular.module('compass.services', []) }; wizard.getManagementCredentials = function() { - return wizard.management_credentials; + return angular.copy(wizard.management_credentials); + }; + + wizard.setNetworkMapping = function(mapping) { + wizard.network_mapping = mapping; + }; + + wizard.getNetworkMapping = function() { + return angular.copy(wizard.network_mapping); }; return wizard; diff --git a/v2/src/app/wizard/global.tpl.html b/v2/src/app/wizard/global.tpl.html index 7ec32f3..11698b2 100644 --- a/v2/src/app/wizard/global.tpl.html +++ b/v2/src/app/wizard/global.tpl.html @@ -22,15 +22,106 @@
- +
- +
- + +
+ +
+
+
+
+
+ +
+ + + + + + + + + + + +
+
+
+
+
+ +
+ + + + + + + + + + + +
+
+
+
+
+ +
+ + + + + + + + + + + +
+
+
+
+
+
@@ -39,13 +130,16 @@
- + @@ -59,13 +153,16 @@
- + @@ -78,7 +175,10 @@
- +
@@ -86,33 +186,16 @@
- +
- -
-
-
-
-
- -
- -
-
-
-
-
- -
- +
+
@@ -167,7 +250,8 @@ - + + - @@ -217,7 +299,7 @@
- + -->
diff --git a/v2/src/app/wizard/network.tpl.html b/v2/src/app/wizard/network.tpl.html index 8616274..c68706e 100644 --- a/v2/src/app/wizard/network.tpl.html +++ b/v2/src/app/wizard/network.tpl.html @@ -25,77 +25,125 @@
- -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
InterfaceSubnetIs Mgmt NetworkAction
- - - - - - -
- {{name}} - - - {{sub.name}} - - - - - - -
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
InterfaceSubnetIs Mgmt NetworkAction
+ + + + - + +
+ {{name}} + + + {{sub.name}} + + + + + + +
+
+
+
-
-
-
-
-
-
- Autofill Panel +
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+
+ +
+ + +
+
+
+ +
+
+
+
+
@@ -122,10 +170,10 @@ - + - + {{server[column.field]}} diff --git a/v2/src/app/wizard/network_mapping.tpl.html b/v2/src/app/wizard/network_mapping.tpl.html index 1519920..160ccc8 100644 --- a/v2/src/app/wizard/network_mapping.tpl.html +++ b/v2/src/app/wizard/network_mapping.tpl.html @@ -1,64 +1,45 @@ -
+
-
- - - - -
-
+
+
+
+

Interfaces

+
+
+
+
+ {{interface_key}} +
-
-
+
+ + {{network_value.display}} +
+
-
{{servers}} - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Host MACSwitch IPPortHostnameManagement NetworkTenant NetworkStorage NetworkPublic Network
- - {{server["mac"]}}{{server["switch_ip"]}}{{server["port"]}}{{server["hostname"]}} - - - - - - - -
+
+
+
+
+
+ +
+
+
+

Networks

+
+ +
+
+
+
+ + {{value.display}} +
+
+
+
+
+
diff --git a/v2/src/app/wizard/role_assignment.tpl.html b/v2/src/app/wizard/role_assignment.tpl.html index 66b5522..d96aa08 100644 --- a/v2/src/app/wizard/role_assignment.tpl.html +++ b/v2/src/app/wizard/role_assignment.tpl.html @@ -1,10 +1,28 @@
+ - + + +
+ + +
@@ -14,7 +32,9 @@ @@ -23,29 +43,29 @@
- +
+ - - - - - - + - - - - +
- + + + {{column.title}} Host MACSwitch IPPortHostname Roles
{{server["mac"]}}{{server["switch_ip"]}}{{server["port"]}}{{server["hostname"]}} + {{server[column.field]}} + {{role.display_name}} diff --git a/v2/src/app/wizard/security.tpl.html b/v2/src/app/wizard/security.tpl.html index 6e38e15..fa95aab 100644 --- a/v2/src/app/wizard/security.tpl.html +++ b/v2/src/app/wizard/security.tpl.html @@ -14,19 +14,19 @@
- +
- +
- +
- +
@@ -36,12 +36,12 @@ - OpenStack Services Credentials + OpenStack Database & Queue Credentials
-
+
-
+
@@ -83,17 +83,19 @@
-
+
- OpenStack Management Console Credentials + OpenStack Keystone User Credentials
-
+
+
+
@@ -136,6 +138,8 @@
+
+
diff --git a/v2/src/app/wizard/wizard.js b/v2/src/app/wizard/wizard.js index 80a6b49..6ba0987 100644 --- a/v2/src/app/wizard/wizard.js +++ b/v2/src/app/wizard/wizard.js @@ -2,7 +2,8 @@ angular.module('compass.wizard', [ 'ui.router', 'ui.bootstrap', 'ngTable', - 'compass.charts' + 'compass.charts', + 'ngDragDrop' ]) .config(function config($stateProvider) { @@ -15,14 +16,12 @@ angular.module('compass.wizard', [ }) .controller('wizardCtrl', function($scope, dataService, wizardFactory, $stateParams) { - if($stateParams.config == "true") { + if ($stateParams.config == "true") { dataService.getWizardPreConfig().success(function(data) { - wizardFactory.preConfig(data); - }); + wizardFactory.preConfig(data); + }); } - $scope.clusterInfo = wizardFactory.getClusterInfo(); - // current step for create-cluster wizard $scope.currentStep = 1; @@ -61,8 +60,6 @@ angular.module('compass.wizard', [ $scope.$watch(function() { return wizardFactory.getCommitState() }, function(newCommitState, oldCommitState) { - - switch (newCommitState.name) { case "sv_selection": case "os_global": @@ -72,10 +69,11 @@ angular.module('compass.wizard', [ case "role_assign": case "network_mapping": if (newCommitState.name == $scope.steps[$scope.currentStep - 1].name && newCommitState.state == "success") { - console.info("### catch success in wizardCtrl ###", newCommitState, oldCommitState); + console.warn("### catch success in wizardCtrl ###", newCommitState, oldCommitState); $scope.next(); } else if (newCommitState.state == "error") { // TODO: error handling / display error message + console.warn("### catch error in wizardCtrl ###", newCommitState, oldCommitState); } break; case "review": @@ -105,11 +103,14 @@ angular.module('compass.wizard', [ }; }); - dataService.getAllMachineHosts().success(function(data) { wizardFactory.setAllMachinesHost(data); }); + dataService.getSubnetConfig().success(function(data) { + wizardFactory.setSubnetworks(data); + }); + }) .controller('svSelectCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams) { @@ -193,22 +194,34 @@ angular.module('compass.wizard', [ }; }) -.controller('globalCtrl', function($scope, wizardFactory, dataService) { +.controller('globalCtrl', function($scope, wizardFactory, dataService, $q) { var cluster = wizardFactory.getClusterInfo(); //For General Section $scope.general = wizardFactory.getGeneralConfig(); - //TODO: bug - should not set dns_servers and search_path to empty - $scope.general["dns_servers"] = [""]; - $scope.general["search_path"] = [""]; + if (!$scope.general["dns_servers"]) { + $scope.general["dns_servers"] = [""]; + } + if (!$scope.general["search_path"]) { + $scope.general["search_path"] = [""]; + } + if (!$scope.general["http_proxy"]) { + $scope.general["http_proxy"] = [""]; + } + if (!$scope.general["https_proxy"]) { + $scope.general["https_proxy"] = [""]; + } + if (!$scope.general["default_no_proxy"]) { + $scope.general["default_no_proxy"] = [""]; + } - $scope.addDNSServer = function() { - $scope.general['dns_servers'].push(""); - }; - $scope.addSearchPath = function() { - $scope.general['search_path'].push(""); + $scope.addValue = function(key) { + $scope.general[key].push(""); + console.log($scope.general); + console.log($scope.general.http_proxy.length) }; + dataService.getTimezones().success(function(data) { $scope.timezones = data; }); @@ -229,6 +242,8 @@ angular.module('compass.wizard', [ }, true); //For Routing Table Section + //keep routing table for later use + /* $scope.routingtable = wizardFactory.getRoutingTable(); $scope.addRoute = function() { $scope.routingtable.push({}); @@ -242,6 +257,7 @@ angular.module('compass.wizard', [ $scope.routingtable.push({}); } }, true); + */ $scope.$watch(function() { return wizardFactory.getCommitState() @@ -255,63 +271,62 @@ angular.module('compass.wizard', [ }); $scope.commit = function() { - $scope.updateClusterConfig(); - $scope.updateSubnet(); - $scope.updateRoutingTable(); - - console.info("$$$$ ", wizardFactory.getSubnetworks(), wizardFactory.getRoutingTable(), wizardFactory.getGeneralConfig()) - - //TODO: should have check here to see if each part is updated successfully - var commitState = { - "name": "os_global", - "state": "success", - "message": "" - }; - wizardFactory.setCommitState(commitState); - }; - - $scope.updateClusterConfig = function() { + var promises = []; var os_global_general = { "os_config": { "general": $scope.general } }; - // put cluster config - dataService.updateClusterConfig(cluster.id, os_global_general).success(function(configData) { - wizardFactory.setGeneralConfig(configData["os_config"]["general"]); + var updateClusterConfig = dataService.updateClusterConfig(cluster.id, os_global_general).then(function(configData) { + wizardFactory.setGeneralConfig(configData.data["os_config"]["general"]); + }, function(response) { + return $q.reject(response); + }); + promises.push(updateClusterConfig); + + var subnetworks = []; + angular.forEach($scope.subnetworks, function(subnet) { + if (subnet.subnet_id === undefined) { + // post subnetworks + var updateSubnetConfig = dataService.postSubnetConfig(subnet).then(function(subnetData) { + subnetworks.push(subnetData.data); + }, function(response) { + return $q.reject(response); + }); + promises.push(updateSubnetConfig); + } else { + // put subnetworks + var updateSubnetConfig = dataService.putSubnetConfig(subnet.subnet_id, subnet).then(function(subnetData) { + subnetworks.push(subnetData.data); + }, function(response) { + return $q.reject(response); + }); + promises.push(updateSubnetConfig); + } + }); + + $q.all(promises).then(function() { + $scope.subnetworks = subnetworks; + wizardFactory.setSubnetworks($scope.subnetworks); + var commitState = { + "name": "os_global", + "state": "success", + "message": "" + }; + wizardFactory.setCommitState(commitState); + }, function(response) { + console.log("promises error", response); + var commitState = { + "name": "os_global", + "state": "error", + "message": response.statusText + }; + wizardFactory.setCommitState(commitState); }); }; - $scope.updateSubnet = function() { - var subnetCount = $scope.subnetworks.length; - var subnetworks = []; - var i = 0; - - angular.forEach($scope.subnetworks, function(subnet) { - if (subnet.subnet_id === undefined) { - // post cluster subnet-config - dataService.postClusterSubnetConfig(cluster.id, subnet).success(function(subnetData) { - subnetworks.push(subnetData); - i++; - if (i == subnetCount) { - $scope.subnetworks = subnetworks; - wizardFactory.setSubnetworks($scope.subnetworks); - } - }) - } else { - // put cluster subnet-config - dataService.putClusterSubnetConfig(cluster.id, subnet.subnet_id, subnet).success(function(subnetData) { - subnetworks.push(subnetData); - i++; - if (i == subnetCount) { - $scope.subnetworks = subnetworks; - wizardFactory.setSubnetworks($scope.subnetworks); - } - }) - } - }) - }; - + // keey routing table for later use + /* $scope.updateRoutingTable = function() { var routingCount = $scope.routingtable.length; var routingTable = []; @@ -340,9 +355,10 @@ angular.module('compass.wizard', [ } }) }; + */ }) -.controller('networkCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams) { +.controller('networkCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, $q) { var cluster = wizardFactory.getClusterInfo(); $scope.subnetworks = wizardFactory.getSubnetworks(); $scope.interfaces = wizardFactory.getInterfaces(); @@ -391,27 +407,29 @@ angular.module('compass.wizard', [ }) }; - $scope.initHostIpByInterface = function(interfaceName) { - if ($scope.servers.network[interfaceName] === undefinded) { - $scope.servers.network[interfaceName] = {}; + $scope.$watch('addInterfacePanel', function(value) { + if (!$scope.addInterfacePanel.isCollapsed) { + $scope.autoFillPanel.isCollapsed = true; } - }; + }, true); + + $scope.$watch('autoFillPanel', function(value) { + if (!$scope.autoFillPanel.isCollapsed) { + $scope.addInterfacePanel.isCollapsed = true; + } + }, true); $scope.$watch(function() { return wizardFactory.getCommitState() }, function(newCommitState, oldCommitState) { - console.info("### catch commit change in networkCtrl ###", newCommitState); - if (newCommitState !== undefined) { if (newCommitState.name == "network" && newCommitState.state == "triggered") { - $scope.commitNetwork(); - } else if (newCommitState.name == "network_mapping" && newCommitState.state == "triggered") { - $scope.commitNetworkMapping(); + $scope.commit(); } } }); - $scope.commitNetwork = function() { + $scope.commit = function() { var addHostsAction = { "add_hosts": { "machines": [] @@ -445,13 +463,23 @@ angular.module('compass.wizard', [ } } } - wizardFactory.setServers($scope.servers); - $scope.serverCount = $scope.servers.length; - var i = 0; - // post host network + var hostnamePromises = []; + var hostNetworkPromises = []; + angular.forEach($scope.servers, function(server) { - $scope.networkCount = Object.keys(server.network).length; + var hostname = { + "name": server["name"] + }; + // update hostname + var updateHostname = dataService.putHost(server.host_id, hostname).then(function(hostData) { + // success callback + }, function(response) { + // error callback + return $q.reject(response); + }); + hostnamePromises.push(updateHostname); + angular.forEach(server.network, function(value, key) { var network = { "interface": key, @@ -459,39 +487,58 @@ angular.module('compass.wizard', [ "subnet_id": $scope.interfaces[key].subnet_id, "is_mgmt": $scope.interfaces[key].is_mgmt }; + if (value.id === undefined) { + // post host network + var updateNetwork = dataService.postHostNetwork(server.host_id, network).then(function(networkData) { + // success callback + console.log("post networkdata", networkData.data); + var interface = networkData.data.interface; + var networkId = networkData.data.id; + server.network[interface].id = networkId; + }, function(response) { + // error callback + return $q.reject(response); + }); + hostNetworkPromises.push(updateNetwork); + } else { + // put host network + var updateNetwork = dataService.putHostNetwork(server.host_id, value.id, network).then(function(networkData) { + // success callback + console.log("put networkdata", networkData.data); + }, function(response) { + // error callback + return $q.reject(response); + }); + hostNetworkPromises.push(updateNetwork); + } + }); + }); - dataService.postHostNetwork(server.host_id, network).success(function(data) { - i++; - if (i == $scope.serverCount * $scope.networkCount) { - wizardFactory.setInterfaces($scope.interfaces); - wizardFactory.setServers($scope.servers); - var commitState = { - "name": "network", - "state": "success", - "message": "" - }; - wizardFactory.setCommitState(commitState); - } - }); - }) + $q.all(hostnamePromises.concat(hostNetworkPromises)).then(function() { + // update hostname and network for all hosts successfully + wizardFactory.setServers($scope.servers); + var commitState = { + "name": "network", + "state": "success", + "message": "" + }; + wizardFactory.setCommitState(commitState); + }, function(response) { + var commitState = { + "name": "network", + "state": "error", + "message": response.statusText + }; + wizardFactory.setCommitState(commitState); }); }); } }; - $scope.commitNetworkMapping = function() { - var commitState = { - "name": "network_mapping", - "state": "success", - "message": "" - }; - wizardFactory.setCommitState(commitState); - }; - $scope.autofill = function() { //TODO: add auto fill alert("Autofill coming soon"); - } + }; }) .controller('partitionCtrl', function($scope, wizardFactory, dataService) { @@ -511,7 +558,6 @@ angular.module('compass.wizard', [ }; $scope.$watch('partition', function() { - console.log("changed") $scope.partitionarray = []; angular.forEach($scope.partition, function(value, key) { $scope.partitionarray.push({ @@ -524,7 +570,6 @@ angular.module('compass.wizard', [ $scope.$watch(function() { return wizardFactory.getCommitState() }, function(newCommitState, oldCommitState) { - console.info("### catch commit change in partitionCtrl ###", newCommitState); if (newCommitState !== undefined) { if (newCommitState.name == "partition" && newCommitState.state == "triggered") { $scope.commit(); @@ -553,13 +598,13 @@ angular.module('compass.wizard', [ .controller('securityCtrl', function($scope, wizardFactory, dataService) { var cluster = wizardFactory.getClusterInfo(); + $scope.server_credentials = wizardFactory.getServerCredentials(); $scope.service_credentials = wizardFactory.getServiceCredentials(); $scope.management_credentials = wizardFactory.getManagementCredentials(); $scope.$watch(function() { return wizardFactory.getCommitState() }, function(newCommitState, oldCommitState) { - console.info("### catch commit change in securityCtrl ###", newCommitState); if (newCommitState !== undefined) { if (newCommitState.name == "security" && newCommitState.state == "triggered") { $scope.commit(); @@ -568,8 +613,19 @@ angular.module('compass.wizard', [ }); $scope.commit = function() { - var partitionData = {}; - dataService.updateClusterConfig(cluster.id, partitionData).success(function(data) { + var securityData = { + "os_config": { + "username": $scope.server_credentials.username, + "password": $scope.server_credentials.password + }, + "package_config": { + "security": { + "service_credentials": $scope.service_credentials, + "console_crendentials": $scope.management_credentials + } + } + }; + dataService.updateClusterConfig(cluster.id, securityData).success(function(data) { var commitState = { "name": "security", "state": "success", @@ -580,11 +636,30 @@ angular.module('compass.wizard', [ }; }) -.controller('roleAssignCtrl', function($scope, wizardFactory, dataService) { +.controller('roleAssignCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, $q) { var cluster = wizardFactory.getClusterInfo(); $scope.servers = wizardFactory.getServers(); - $scope.roles = wizardFactory.getAdapter().roles; + dataService.getAdapter(cluster.adapter_id).success(function(data) { + wizardFactory.setAdapter(data); + $scope.roles = data.roles; + }); + + dataService.getServerColumns().success(function(data) { + $scope.server_columns = data.showless; + }); + + $scope.selectAllServers = function(flag) { + if (flag) { + angular.forEach($scope.servers, function(sv) { + sv.checked = true; + }) + } else { + angular.forEach($scope.servers, function(sv) { + sv.checked = false; + }) + } + }; $scope.removeRole = function(server, role) { var serverIndex = $scope.servers.indexOf(server); @@ -593,28 +668,52 @@ angular.module('compass.wizard', [ }; $scope.assignRole = function(role) { - // get selected servers and assign role to them - var roleExist = false; + var serverChecked = false; for (var i = 0; i < $scope.servers.length; i++) { if ($scope.servers[i].checked) { - for (var j = 0; j < $scope.servers[i].roles.length; j++) { - if (role.name == $scope.servers[i].roles[j].name) { - roleExist = true; + serverChecked = true; + } + } + if (!serverChecked) { + alert("Please select at least one server"); + } else { + // get selected servers and assign role to them + var roleExist = false; + for (var i = 0; i < $scope.servers.length; i++) { + if ($scope.servers[i].checked) { + for (var j = 0; j < $scope.servers[i].roles.length; j++) { + if (role.name == $scope.servers[i].roles[j].name) { + roleExist = true; + } + } + if (!roleExist) { + $scope.servers[i].roles.push(role); + } else { + roleExist = false; } } } - if (!roleExist) { - $scope.servers[i].roles.push(role); - } else { - roleExist = false; - } } }; + $scope.tableParams = new ngTableParams({ + page: 1, // show first page + count: $scope.servers.length + 1 // count per page + }, { + counts: [], // hide count-per-page box + total: $scope.servers.length, // length of data + getData: function($defer, params) { + // use build-in angular filter + var orderedData = params.sorting() ? + $filter('orderBy')($scope.servers, params.orderBy()) : $scope.servers; + + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + } + }); + $scope.$watch(function() { return wizardFactory.getCommitState() }, function(newCommitState, oldCommitState) { - console.info("### catch commit change in networkCtrl ###", newCommitState); if (newCommitState !== undefined) { if (newCommitState.name == "role_assign" && newCommitState.state == "triggered") { $scope.commit(); @@ -623,11 +722,90 @@ angular.module('compass.wizard', [ }); $scope.commit = function() { - var commitState = { - "name": "role_assign", - "state": "success", - "message": "" - }; - wizardFactory.setCommitState(commitState); + var promises = []; + angular.forEach($scope.servers, function(server) { + var roles = []; + angular.forEach(server.roles, function(role) { + roles.push(role.name); + }); + var config = { + "package_config": { + "roles": roles + } + }; + var updateRoles = dataService.updateClusterHostConfig(cluster.id, server.host_id, config).then(function(configData) { + // success callback + }, function(response) { + // error callback + return $q.reject(response); + }); + }); + + $q.all(promises).then(function() { + wizardFactory.setServers($scope.servers); + var commitState = { + "name": "role_assign", + "state": "success", + "message": "" + }; + wizardFactory.setCommitState(commitState); + }, function(response) { + console.log("promises error", response); + var commitState = { + "name": "role_assign", + "state": "error", + "message": response.statusText + }; + wizardFactory.setCommitState(commitState); + }); }; }) + +.controller('networkMappingCtrl', function($scope, wizardFactory, dataService) { + var cluster = wizardFactory.getClusterInfo(); + $scope.interfaces = wizardFactory.getInterfaces(); + $scope.networking = wizardFactory.getNetworkMapping(); + + $scope.pendingInterface = ""; + + $scope.onDrop = function($event, key) { + $scope.pendingInterface = key; + }; + + $scope.dropSuccessHandler = function($event, key, dict) { + dict[key].mapping_interface = $scope.pendingInterface; + }; + + $scope.$watch(function() { + return wizardFactory.getCommitState() + }, function(newCommitState, oldCommitState) { + if (newCommitState !== undefined) { + if (newCommitState.name == "network_mapping" && newCommitState.state == "triggered") { + $scope.commit(); + } + } + }); + + $scope.commit = function() { + var networks = {}; + angular.forEach($scope.networking, function(value, key) { + networks[key] = value.mapping_interface; + }); + var network_mapping = { + "package_config": { + "network_mapping": networks + } + }; + dataService.updateClusterConfig(cluster.id, network_mapping).success(function(data) { + wizardFactory.setNetworkMapping($scope.networking); + var commitState = { + "name": "network_mapping", + "state": "success", + "message": "" + }; + wizardFactory.setCommitState(commitState); + }); + //TODO: error handling + }; +}) + diff --git a/v2/vendor/angular-dragdrop/draganddrop.js b/v2/vendor/angular-dragdrop/draganddrop.js new file mode 100644 index 0000000..7de17da --- /dev/null +++ b/v2/vendor/angular-dragdrop/draganddrop.js @@ -0,0 +1,201 @@ +/** + * Created with IntelliJ IDEA. + * User: Ganaraj.Pr + * Date: 11/10/13 + * Time: 11:27 + * To change this template use File | Settings | File Templates. + */ +if (window.jQuery && (-1 == window.jQuery.event.props.indexOf("dataTransfer"))) { + window.jQuery.event.props.push("dataTransfer"); +} + +angular.module("ngDragDrop",[]) + .directive("uiDraggable", [ + '$parse', + '$rootScope', + function ($parse, $rootScope) { + return function (scope, element, attrs) { + var dragData = "", + isDragHandleUsed = false, + dragHandleClass, + dragHandles, + dragTarget; + + element.attr("draggable", false); + + attrs.$observe("uiDraggable", function (newValue) { + element.attr("draggable", newValue); + }); + + if (attrs.drag) { + scope.$watch(attrs.drag, function (newValue) { + dragData = newValue || ""; + }); + } + + if (angular.isString(attrs.dragHandleClass)) { + isDragHandleUsed = true; + dragHandleClass = attrs.dragHandleClass.trim() || "drag-handle"; + dragHandles = element.find('.' + dragHandleClass).toArray(); + + element.bind("mousedown", function (e) { + dragTarget = e.target; + }); + } + + element.bind("dragstart", function (e) { + var isDragAllowed = !isDragHandleUsed || -1 != dragHandles.indexOf(dragTarget); + + if (isDragAllowed) { + var sendData = angular.toJson(dragData); + var sendChannel = attrs.dragChannel || "defaultchannel"; + var dragImage = attrs.dragImage || null; + if (dragImage) { + var dragImageFn = $parse(attrs.dragImage); + scope.$apply(function() { + var dragImageParameters = dragImageFn(scope, {$event: e}); + if (dragImageParameters && dragImageParameters.image) { + var xOffset = dragImageParameters.xOffset || 0, + yOffset = dragImageParameters.yOffset || 0; + e.dataTransfer.setDragImage(dragImageParameters.image, xOffset, yOffset); + } + }); + } + + e.dataTransfer.setData("text/plain", sendData); + e.dataTransfer.effectAllowed = "copyMove"; + $rootScope.$broadcast("ANGULAR_DRAG_START", sendChannel); + } + else { + e.preventDefault(); + } + }); + + element.bind("dragend", function (e) { + var sendChannel = attrs.dragChannel || "defaultchannel"; + $rootScope.$broadcast("ANGULAR_DRAG_END", sendChannel); + if (e.dataTransfer && e.dataTransfer.dropEffect !== "none") { + if (attrs.onDropSuccess) { + var fn = $parse(attrs.onDropSuccess); + scope.$apply(function () { + fn(scope, {$event: e}); + }); + } + } + }); + + + }; + } + ]) + .directive("uiOnDrop", [ + '$parse', + '$rootScope', + function ($parse, $rootScope) { + return function (scope, element, attr) { + var dragging = 0; //Ref. http://stackoverflow.com/a/10906204 + var dropChannel = "defaultchannel"; + var dragChannel = ""; + var dragEnterClass = attr.dragEnterClass || "on-drag-enter"; + var dragHoverClass = attr.dragHoverClass || "on-drag-hover"; + + function onDragOver(e) { + if (e.preventDefault) { + e.preventDefault(); // Necessary. Allows us to drop. + } + + if (e.stopPropagation) { + e.stopPropagation(); + } + + e.dataTransfer.dropEffect = e.shiftKey ? 'copy' : 'move'; + return false; + } + + function onDragLeave(e) { + dragging--; + if (dragging == 0) { + element.removeClass(dragHoverClass); + } + } + + function onDragEnter(e) { + dragging++; + $rootScope.$broadcast("ANGULAR_HOVER", dropChannel); + element.addClass(dragHoverClass); + } + + function onDrop(e) { + if (e.preventDefault) { + e.preventDefault(); // Necessary. Allows us to drop. + } + if (e.stopPropagation) { + e.stopPropagation(); // Necessary. Allows us to drop. + } + var data = e.dataTransfer.getData("text/plain"); + data = angular.fromJson(data); + var fn = $parse(attr.uiOnDrop); + scope.$apply(function () { + fn(scope, {$data: data, $event: e}); + }); + element.removeClass(dragEnterClass); + } + + function isDragChannelAccepted(dragChannel, dropChannel) { + if (dropChannel === "*") { + return true; + } + + var channelMatchPattern = new RegExp("(\\s|[,])+(" + dragChannel + ")(\\s|[,])+", "i"); + + return channelMatchPattern.test("," + dropChannel + ","); + } + + $rootScope.$on("ANGULAR_DRAG_START", function (event, channel) { + dragChannel = channel; + if (isDragChannelAccepted(dragChannel, dropChannel)) { + + element.bind("dragover", onDragOver); + element.bind("dragenter", onDragEnter); + element.bind("dragleave", onDragLeave); + + element.bind("drop", onDrop); + element.addClass(dragEnterClass); + } + + }); + + + + $rootScope.$on("ANGULAR_DRAG_END", function (e, channel) { + dragChannel = ""; + if (isDragChannelAccepted(channel, dropChannel)) { + + element.unbind("dragover", onDragOver); + element.unbind("dragenter", onDragEnter); + element.unbind("dragleave", onDragLeave); + + element.unbind("drop", onDrop); + element.removeClass(dragHoverClass); + element.removeClass(dragEnterClass); + } + }); + + + $rootScope.$on("ANGULAR_HOVER", function (e, channel) { + if (isDragChannelAccepted(channel, dropChannel)) { + element.removeClass(dragHoverClass); + } + }); + + + attr.$observe('dropChannel', function (value) { + if (value) { + dropChannel = value; + } + }); + + + }; + } + ]);