Improve wizard steps.

Add flavor for creating cluster

Move subnets from OS Global page to Network page

Add find-new-servers on Server Selection page
(Improve find-new-servers code by using directive)

Combine interface and autofill on Network page

Add OS Global section on Review page

Remove swipe on wizard

Simplify wizard step and commit control

Move monitoring part to an individual module

Change-Id: I8422506270c428a7f84679cfbff542235ccc556f
This commit is contained in:
jiahuay 2014-08-18 16:02:35 -07:00
parent 97643bcd14
commit 5f6e0118b0
29 changed files with 1138 additions and 1178 deletions

View File

@ -231,16 +231,9 @@ button[disabled] {
.wizard-steps li.error .title, .wizard-steps li.error .title { .wizard-steps li.error .title, .wizard-steps li.error .title {
color: #2b3d53; color: #2b3d53;
} }
.popup-alert { .wizard-steps li.incomplete:before, li.incomplete .step {
position: fixed; border-color: #d15b47 !important;
z-index: 9; font-weight: bold;
overflow-y: hidden;
}
.popup-alert .message {
color: white;
overflow: hidden;
padding: 10px;
word-wrap: normal;
} }
.padding-left-15 { .padding-left-15 {
padding-left: 15px; padding-left: 15px;
@ -283,6 +276,9 @@ button[disabled] {
line-height: 1.5; line-height: 1.5;
padding: 4px 12px; padding: 4px 12px;
} }
.btn-xs {
padding: 1px 5px !important;
}
.btn-white { .btn-white {
border-width: 1px !important; border-width: 1px !important;
} }
@ -441,10 +437,6 @@ a:active {
background-color: #abbac3 !important; background-color: #abbac3 !important;
border-color: #abbac3 !important; border-color: #abbac3 !important;
} }
.first-prev {
cursor: not-allowed !important;
/* padding: 10px !important; */
}
.btn-light { .btn-light {
cursor: not-allowed !important; cursor: not-allowed !important;
} }
@ -549,15 +541,3 @@ div.center-align {
min-height: 50px; min-height: 50px;
padding: 10px; padding: 10px;
} }
.wizard-steps li.complete:before, .wizard-steps li.complete .step {
/* border-color: #93cbf9 !important;*/}
.a.wizard-steps li.active:before, .wizard-steps li.active .step {
border-color: #80afd4 !important;
color: #87ba21 !important;
transform: scale(1.25) !important;
font-weight: bold;
}
li.incomplete:before, li.incomplete .step {
border-color: #d15b47 !important;
font-weight: bold;
}

View File

@ -20,12 +20,12 @@
"is_promiscuous": false "is_promiscuous": false
}, },
"eth1": { "eth1": {
"subnet_id": 1, "subnet_id": 2,
"is_mgmt": false, "is_mgmt": false,
"is_promiscuous": true "is_promiscuous": true
}, },
"eth2": { "eth2": {
"subnet_id": 2, "subnet_id": 1,
"is_mgmt": false, "is_mgmt": false,
"is_promiscuous": false "is_promiscuous": false
}, },

View File

@ -44,8 +44,10 @@
<script type="text/javascript" src="src/app/wizard/wizard.js"></script> <script type="text/javascript" src="src/app/wizard/wizard.js"></script>
<script type="text/javascript" src="src/app/cluster/cluster.js"></script> <script type="text/javascript" src="src/app/cluster/cluster.js"></script>
<script type="text/javascript" src="src/app/cluster/clusterlist.js"></script> <script type="text/javascript" src="src/app/cluster/clusterlist.js"></script>
<script type="text/javascript" src="src/app/monitoring/monitoring.js"></script>
<script type="text/javascript" src="src/app/server/server.js"></script> <script type="text/javascript" src="src/app/server/server.js"></script>
<script type="text/javascript" src="src/common/charts.js"></script> <script type="text/javascript" src="src/common/charts.js"></script>
<script type="text/javascript" src="src/common/findservers/findservers.js"></script>
</head> </head>
<body ng-app="compass" ng-controller="appController"> <body ng-app="compass" ng-controller="appController">

View File

@ -5,6 +5,7 @@ var app = angular.module('compass', [
'compass.wizard', 'compass.wizard',
'compass.cluster', 'compass.cluster',
'compass.clusterlist', 'compass.clusterlist',
'compass.monitoring',
'compass.server', 'compass.server',
'ui.router', 'ui.router',
'ui.bootstrap', 'ui.bootstrap',

View File

@ -38,10 +38,10 @@ compassAppDev.run(function($httpBackend, settings, $http) {
}], }],
"supported_oses": [{ "supported_oses": [{
"name": "CentOs", "name": "CentOs",
"os_id": 1 "id": 1
}, { }, {
"name": "Ubuntu", "name": "Ubuntu",
"os_id": 2 "id": 2
}] }]
}, { }, {
"id": 2, "id": 2,
@ -61,8 +61,12 @@ compassAppDev.run(function($httpBackend, settings, $http) {
}], }],
"supported_oses": [{ "supported_oses": [{
"name": "CentOs", "name": "CentOs",
"os_id": 1 "id": 1
}] }, {
"name": "Ubuntu",
"id": 2
}],
"flavors": []
}]; }];
return [200, adapters, {}]; return [200, adapters, {}];
}); });
@ -90,10 +94,10 @@ compassAppDev.run(function($httpBackend, settings, $http) {
}], }],
"supported_oses": [{ "supported_oses": [{
"name": "CentOs", "name": "CentOs",
"os_id": 1 "id": 1
}, { }, {
"name": "Ubuntu", "name": "Ubuntu",
"os_id": 2 "id": 2
}] }]
}; };
return [200, adapter, {}]; return [200, adapter, {}];
@ -329,31 +333,31 @@ compassAppDev.run(function($httpBackend, settings, $http) {
var switchId = url.substring(index).split("/")[1]; var switchId = url.substring(index).split("/")[1];
var machines = [{ var machines = [{
"id": Math.floor(Math.random() * 100 + 1), "id": Math.floor(Math.random() * 100 + 1),
"mac": "28.e5.ee.47.14.92", "mac": "28.e5.ee.47.14.11",
"switch_ip": "172.29.8." + switchId, "switch_ip": "172.29.8." + switchId,
"vlan": "1", "vlan": "1",
"port": "11" "port": "11"
}, { }, {
"id": Math.floor(Math.random() * 100 + 1), "id": Math.floor(Math.random() * 100 + 1),
"mac": "28.e5.ee.47.a2.93", "mac": "28.e5.ee.47.a2.22",
"switch_ip": "172.29.8." + switchId, "switch_ip": "172.29.8." + switchId,
"vlan": "2", "vlan": "2",
"port": "12" "port": "12"
}, { }, {
"id": Math.floor(Math.random() * 100 + 1), "id": Math.floor(Math.random() * 100 + 1),
"mac": "28.e5.ee.47.ee.32", "mac": "28.e5.ee.47.ee.33",
"switch_ip": "172.29.8." + switchId, "switch_ip": "172.29.8." + switchId,
"vlan": "2", "vlan": "2",
"port": "13" "port": "13"
}, { }, {
"id": Math.floor(Math.random() * 100 + 1), "id": Math.floor(Math.random() * 100 + 1),
"mac": "28.e5.ee.47.33.66", "mac": "28.e5.ee.47.33.44",
"switch_ip": "172.29.8." + switchId, "switch_ip": "172.29.8." + switchId,
"vlan": "2", "vlan": "2",
"port": "14" "port": "14"
}, { }, {
"id": Math.floor(Math.random() * 100 + 1), "id": Math.floor(Math.random() * 100 + 1),
"mac": "28.e5.ee.47.2c.22", "mac": "28.e5.ee.47.2c.55",
"switch_ip": "172.29.8." + switchId, "switch_ip": "172.29.8." + switchId,
"vlan": "2", "vlan": "2",
"port": "15" "port": "15"
@ -669,11 +673,11 @@ compassAppDev.run(function($httpBackend, settings, $http) {
console.log(method, url); console.log(method, url);
var subnetworks = [{ var subnetworks = [{
"id": 1, "id": 1,
"name": "net1", //"name": "10.172.10.0/24",
"subnet": "10.172.10.0/24" "subnet": "10.172.10.0/24"
}, { }, {
"id": 2, "id": 2,
"name": "net2", //"name": "10.172.20.0/24",
"subnet": "10.172.20.0/24" "subnet": "10.172.20.0/24"
}]; }];
return [200, subnetworks, {}]; return [200, subnetworks, {}];

View File

@ -35,9 +35,7 @@
<label class="col-xs-12 col-sm-3 col-md-3 control-label no-padding-right">Target System</label> <label class="col-xs-12 col-sm-3 col-md-3 control-label no-padding-right">Target System</label>
<div class="col-xs-12 col-sm-5"> <div class="col-xs-12 col-sm-5">
<select name="targetsystem" class="width-100" ng-model="cluster.adapter_id" required> <select ng-options="adapter.display_name for adapter in allAdapters" ng-model="cluster.adapter" ng-change="updateSelectedAdapter()" name="targetsystem" class="width-100" required>
<option value=""></option>
<option ng-repeat="adapter in allAdapters" value="{{adapter.id}}"> {{adapter.display_name}}</option>
</select> </select>
</div> </div>
<div class="help-block col-xs-12 col-sm-reset inline"> Required </div> <div class="help-block col-xs-12 col-sm-reset inline"> Required </div>
@ -47,13 +45,20 @@
<label class="col-xs-12 col-sm-3 control-label no-padding-right">OS</label> <label class="col-xs-12 col-sm-3 control-label no-padding-right">OS</label>
<div class="col-xs-12 col-sm-5"> <div class="col-xs-12 col-sm-5">
<select name="os" class="width-100" ng-model="cluster.os_id" required> <select ng-options="os.name for os in supported_oses" ng-model="cluster.os" name="os" class="width-100" required>
<option value=""></option>
<option ng-repeat="os in supported_oses" value="{{os.os_id}}"> {{os.name}}</option>
</select> </select>
</div> </div>
<div class="help-block col-xs-12 col-sm-reset inline"> Required </div> <div class="help-block col-xs-12 col-sm-reset inline"> Required </div>
</div> </div>
<div class="form-group" ng-hide="flavors.length == 0" ng-class="{'has-error':createClusterForm.flavors.$error.required&& !createClusterForm.flavors.$pristine}">
<label class="col-xs-12 col-sm-3 control-label no-padding-right">Flavor</label>
<div class="col-xs-12 col-sm-5">
<select ng-options="flavor.display_name for flavor in flavors" ng-model="cluster.flavor" name="os" class="width-100">
</select>
</div>
</div>
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View File

@ -61,11 +61,6 @@ angular.module('compass.cluster', [
url: '/log', url: '/log',
templateUrl: 'src/app/cluster/cluster-log.tpl.html', templateUrl: 'src/app/cluster/cluster-log.tpl.html',
authenticate: true authenticate: true
})
.state('cluster.monitoring', {
url: '/monitoring',
templateUrl: 'src/app/cluster/cluster-monitoring.tpl.html',
authenticate: true
}); });
}) })
@ -206,7 +201,13 @@ angular.module('compass.cluster', [
modalInstance.result.then(function(cluster) { modalInstance.result.then(function(cluster) {
$scope.cluster = cluster; $scope.cluster = cluster;
dataService.createCluster(cluster).success(function(data, status) { var postClusterData = {
"name": cluster.name,
"adapter_id": cluster.adapter.id,
"os_id": cluster.os.id,
"flavor_id": cluster.flavor.id
};
dataService.createCluster(postClusterData).success(function(data, status) {
wizardFactory.setClusterInfo(data); wizardFactory.setClusterInfo(data);
angular.forEach($scope.allAdapters, function(adapter) { angular.forEach($scope.allAdapters, function(adapter) {
if (adapter.id == $scope.cluster.adapter_id) { if (adapter.id == $scope.cluster.adapter_id) {
@ -227,116 +228,6 @@ angular.module('compass.cluster', [
} }
]) ])
.controller('monitoringCtrl', ['$scope',
function($scope) {
$scope.options = {
renderer: 'area'
};
$scope.features = {
hover: {
xFormatter: function(x) {
return 't=' + x;
},
yFormatter: function(y) {
return '$' + y;
}
}
};
$scope.series = [{
name: 'Series 1',
color: 'steelblue',
data: [{
x: 0,
y: 23
}, {
x: 1,
y: 15
}, {
x: 2,
y: 79
}, {
x: 3,
y: 31
}, {
x: 4,
y: 60
}]
}, {
name: 'Series 2',
color: 'lightblue',
data: [{
x: 0,
y: 30
}, {
x: 1,
y: 20
}, {
x: 2,
y: 64
}, {
x: 3,
y: 50
}, {
x: 4,
y: 15
}]
}];
$scope.options2 = {
renderer: 'line'
};
$scope.features2 = {
hover: {
xFormatter: function(x) {
return 't=' + x;
},
yFormatter: function(y) {
return '$' + y;
}
}
};
$scope.series2 = [{
name: 'Series 1',
color: 'steelblue',
data: [{
x: 0,
y: 23
}, {
x: 1,
y: 15
}, {
x: 2,
y: 79
}, {
x: 3,
y: 31
}, {
x: 4,
y: 60
}]
}, {
name: 'Series 2',
color: 'lightblue',
data: [{
x: 0,
y: 30
}, {
x: 1,
y: 20
}, {
x: 2,
y: 64
}, {
x: 3,
y: 50
}, {
x: 4,
y: 15
}]
}];
}
])
.controller('configurationCtrl', ['$scope', 'dataService', '$stateParams', '$filter', 'ngTableParams', .controller('configurationCtrl', ['$scope', 'dataService', '$stateParams', '$filter', 'ngTableParams',
function($scope, dataService, $stateParams, $filter, ngTableParams) { function($scope, dataService, $stateParams, $filter, ngTableParams) {
var clusterId = $stateParams.id; var clusterId = $stateParams.id;
@ -384,13 +275,13 @@ var ModalInstanceCtrl = function($scope, $modalInstance, allAdapters, cluster) {
$scope.allAdapters = allAdapters; $scope.allAdapters = allAdapters;
$scope.cluster = cluster; $scope.cluster = cluster;
$scope.$watch('cluster.adapter_id', function() { $scope.updateSelectedAdapter = function() {
angular.forEach($scope.allAdapters, function(adapter) { angular.forEach($scope.allAdapters, function(adapter) {
if (adapter.id == $scope.cluster.adapter_id) { if(adapter.id == $scope.cluster.adapter.id) {
$scope.supported_oses = adapter.supported_oses; $scope.supported_oses = adapter.supported_oses;
} }
}) })
}); };
$scope.ok = function() { $scope.ok = function() {
$scope.result = 'ok'; $scope.result = 'ok';

View File

@ -3,6 +3,4 @@
<div class="page-content"> <div class="page-content">
<div ui-view></div> <div ui-view></div>
</div> </div>
</div> </div>
<!-- might need this part for monitoring-->
<!--<iframe src="{{currentProjectUrl}}" style="width:500px;height:500px;"></iframe>-->

View File

@ -23,6 +23,8 @@ angular.module('compass.login', [
authService.login(credentials).success(function(data) { authService.login(credentials).success(function(data) {
authService.isAuthenticated = true; authService.isAuthenticated = true;
$state.transitionTo("clusterList"); $state.transitionTo("clusterList");
}).error(function(response) {
console.log(response);
}) })
} }
}) })

View File

@ -0,0 +1,126 @@
angular.module('compass.monitoring', [
'ui.router',
'ui.bootstrap',
'compass.charts',
'ngAnimate',
'angular-rickshaw'
])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('cluster.monitoring', {
url: '/monitoring',
templateUrl: 'src/app/monitoring/cluster-monitoring.tpl.html',
authenticate: true
})
})
.controller('monitoringCtrl', ['$scope',
function($scope) {
$scope.options = {
renderer: 'area'
};
$scope.features = {
hover: {
xFormatter: function(x) {
return 't=' + x;
},
yFormatter: function(y) {
return '$' + y;
}
}
};
$scope.series = [{
name: 'Series 1',
color: 'steelblue',
data: [{
x: 0,
y: 23
}, {
x: 1,
y: 15
}, {
x: 2,
y: 79
}, {
x: 3,
y: 31
}, {
x: 4,
y: 60
}]
}, {
name: 'Series 2',
color: 'lightblue',
data: [{
x: 0,
y: 30
}, {
x: 1,
y: 20
}, {
x: 2,
y: 64
}, {
x: 3,
y: 50
}, {
x: 4,
y: 15
}]
}];
$scope.options2 = {
renderer: 'line'
};
$scope.features2 = {
hover: {
xFormatter: function(x) {
return 't=' + x;
},
yFormatter: function(y) {
return '$' + y;
}
}
};
$scope.series2 = [{
name: 'Series 1',
color: 'steelblue',
data: [{
x: 0,
y: 23
}, {
x: 1,
y: 15
}, {
x: 2,
y: 79
}, {
x: 3,
y: 31
}, {
x: 4,
y: 60
}]
}, {
name: 'Series 2',
color: 'lightblue',
data: [{
x: 0,
y: 30
}, {
x: 1,
y: 20
}, {
x: 2,
y: 64
}, {
x: 3,
y: 50
}, {
x: 4,
y: 15
}]
}];
}
])

View File

@ -1,40 +0,0 @@
<script type="text/ng-template" id="addSwitchModal.html">
<div class="modal-header">
<h3 class="modal-title">Add Switch</h3>
</div>
<div class="modal-body">
<form name="addSwitchForm" class="form-horizontal">
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Switch IP</label>
<div class="col-sm-9">
<input type="text" ng-model="newswitch.ip" placeholder="Switch IP" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Version</label>
<div class="col-sm-9">
<select ng-model="newswitch.credentials.version" required>
<option>1</option>
<option>2c</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Community</label>
<div class="col-sm-9">
<input type="password" ng-model="newswitch.credentials.community" placeholder="Community" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Port Filter</label>
<div class="col-sm-9">{{test}}
<input type="text" ng-model="filters.ports" placeholder="Port Filter">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="addSwitch()" ng-disabled="addSwitchForm.$invalid">Add</button>
<button class="btn btn-grey" ng-click="cancel()">Cancel</button>
</div>
</script>

View File

@ -8,7 +8,7 @@
<i class="ace-icon fa fa-times-circle bigger-120 light-grey"></i> <i class="ace-icon fa fa-times-circle bigger-120 light-grey"></i>
</span> </span>
<div class="clearfix"></div> <div class="clearfix"></div>
<div ng-include="'src/app/server/find-new-servers.tpl.html'"></div> <findservers results="foundResults"></findservers>
</div> </div>
</div> </div>
</div> </div>
@ -84,12 +84,12 @@
<table ng-table="tableParams" class="table table-hover table-striped"> <table ng-table="tableParams" class="table table-hover table-striped">
<thead> <thead>
<tr> <tr>
<th> <!--th>
<label> <label>
<input ng-model="selectall" ng-change="selectAllServers(selectall)" type="checkbox" class="ace"> <input ng-model="selectall" ng-change="selectAllServers(selectall)" type="checkbox" class="ace">
<span class="lbl"></span> <span class="lbl"></span>
</label> </label>
</th> </th-->
<th ng-repeat="column in server_columns" ng-show="column.visible" class="sortable" ng-class="{'sort-asc': tableParams.isSortBy(column.field, 'asc'), 'sort-desc': tableParams.isSortBy(column.field, 'desc')}" ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')"> <th ng-repeat="column in server_columns" ng-show="column.visible" class="sortable" ng-class="{'sort-asc': tableParams.isSortBy(column.field, 'asc'), 'sort-desc': tableParams.isSortBy(column.field, 'desc')}" ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
<div>{{column.title}}</div> <div>{{column.title}}</div>
</th> </th>
@ -97,13 +97,13 @@
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="server in $data | filter:search"> <tr ng-repeat="server in $data | filter:search" ng-class="{'success': server.new}">
<td> <!--td>
<label> <label>
<input ng-model="server.selected" type="checkbox" class="ace"> <input ng-model="server.selected" type="checkbox" class="ace">
<span class="lbl"></span> <span class="lbl"></span>
</label> </label>
</td> </td-->
<td ng-repeat="column in server_columns" ng-show="column.visible" sortable="column.field"> <td ng-repeat="column in server_columns" ng-show="column.visible" sortable="column.field">
<span ng-switch on="column.field"> <span ng-switch on="column.field">
<span ng-switch-when="clusters"> <span ng-switch-when="clusters">

View File

@ -2,7 +2,8 @@ angular.module('compass.server', [
'ui.router', 'ui.router',
'ui.bootstrap', 'ui.bootstrap',
'compass.charts', 'compass.charts',
'ngTable', 'compass.findservers',
'ngTable'
]) ])
.config(function config($stateProvider) { .config(function config($stateProvider) {
@ -28,7 +29,7 @@ angular.module('compass.server', [
$scope.hideunselected = ''; $scope.hideunselected = '';
$scope.search = {}; $scope.search = {};
$scope.allservers = machinesHostsData; $scope.allservers = machinesHostsData;
$scope.newFoundServers = []; $scope.foundResults = [];
dataService.getServerColumns().success(function(data) { dataService.getServerColumns().success(function(data) {
$scope.server_columns = data.machines_hosts; $scope.server_columns = data.machines_hosts;
@ -97,186 +98,24 @@ angular.module('compass.server', [
}); });
}; };
$scope.commit = function() { // add newly found servers at the top if allservers array
var selectedServers = []; $scope.$watch('foundResults', function(newResults, oldResults) {
var noSelection = true; if (newResults != oldResults) {
angular.forEach($scope.allservers, function(sv) { for (var i = 0; i < newResults.length; i++) {
if (sv.selected) { var sv = $filter('filter')($scope.allservers, newResults[i].mac, true);
noSelection = false; if (sv.length == 0) {
selectedServers.push(sv); newResults[i].machine_id = newResults[i].id;
delete newResults[i]['id'];
newResults[i].new = true;
$scope.allservers.unshift(newResults[i]);
}
} }
})
if (noSelection) {
alert("Please select at least one server");
wizardFactory.setCommitState({});
} else {
wizardFactory.setServers(selectedServers);
wizardFactory.setAllMachinesHost($scope.allservers);
var commitState = { if ($scope.tableParams) {
"name": "sv_selection", $scope.tableParams.$params.count = $scope.allservers.length;
"state": "success", $scope.tableParams.reload();
"message": "" }
};
wizardFactory.setCommitState(commitState);
} }
}; }, true);
}) })
.controller('findNewServersCtrl', function($scope, dataService, sortingService, $timeout, $modal, $filter, ngTableParams) {
$scope.switches = [];
$scope.newFoundServers = [];
$scope.findingNewServers = false;
var switchTimer;
var fireTimer = true;
dataService.getServerColumns().success(function(data) {
$scope.server_columns = data.machines;
});
var getSwitches = function() {
dataService.getSwitches().success(function(data) {
$scope.switches = data;
})
};
getSwitches();
$scope.selectAllSwitches = function(flag) {
if (flag) {
angular.forEach($scope.switches, function(sv) {
sv.selected = true;
})
} else {
angular.forEach($scope.switches, function(sv) {
sv.selected = false;
})
}
};
$scope.open = function(size) {
var modalInstance = $modal.open({
templateUrl: 'addSwitchModal.html',
controller: addSwitchCtrl
});
modalInstance.result.then(function(newswitch) {
$scope.switches.push(newswitch);
}, function() {
console.info('Modal dismissed at: ' + new Date());
});
};
$scope.findServers = function() {
var swSelection = false;
angular.forEach($scope.switches, function(sw) {
if (sw.selected) {
swSelection = true;
}
});
if (!swSelection) {
alert("Please select at least one switch")
} else {
$scope.findingNewServers = true;
$scope.newFoundServers = [];
angular.forEach($scope.switches, function(sw) {
if (sw.selected) {
sw.result = "";
sw.finished = false;
sw.polling = true;
}
});
}
};
$scope.tableParamsNewServer = new ngTableParams({
page: 1, // show first page
count: $scope.newFoundServers.length, // count per page
}, {
counts: [], // hide count-per-page box
total: $scope.newFoundServers.length, // length of data
getData: function($defer, params) {
var reverse = false;
var orderBy = params.orderBy()[0];
var orderBySort = "";
var orderByColumn = "";
if (orderBy) {
orderByColumn = orderBy.substring(1);
orderBySort = orderBy.substring(0, 1);
if (orderBySort == "+") {
reverse = false;
} else {
reverse = true;
}
}
var orderedData = params.sorting() ?
$filter('orderBy')($scope.newFoundServers, function(item) {
if (orderByColumn == "switch_ip") {
return sortingService.ipAddressPre(item.switch_ip);
} else {
return item[orderByColumn];
}
}, reverse) : $scope.newFoundServers;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
$scope.$watch('switches', function(val) {
var totalResultReady = true;
if ($scope.findingNewServers) {
angular.forEach($scope.switches, function(sw) {
if (sw.selected && !sw.finished) {
if (sw.result == "success") {
$scope.newFoundServers = $scope.newFoundServers.concat(angular.copy(sw.machines));
sw.finished = true;
if ($scope.tableParamsNewServer) {
$scope.tableParamsNewServer.$params.count = $scope.newFoundServers.length;
$scope.tableParamsNewServer.reload();
}
} else if (sw.result == "error") {
sw.finished = true;
} else {
totalResultReady = false;
}
}
});
if (totalResultReady) {
$scope.findingNewServers = false;
}
}
}, true)
})
var addSwitchCtrl = function($scope, $modalInstance, dataService) {
$scope.newswitch = {}
$scope.newswitch.credentials = {};
$scope.filters = {};
$scope.addSwitch = function() {
dataService.postSwitches($scope.newswitch).success(function(switchData) {
if ($scope.filters) {
var filters = {
"filters": $scope.filters
};
dataService.putSwitchFilters(switchData.id, filters).success(function(filterData) {
switchData.filters = filterData.filters;
$scope.newswitch = {};
$scope.filters = {};
$modalInstance.close(switchData);
})
}
})
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
};

View File

@ -17,7 +17,7 @@ angular.module('compass.services', [])
app.stateProvider.state(pst.name, { app.stateProvider.state(pst.name, {
url: pst.url, url: pst.url,
//controller: pst.controller, //controller: pst.controller,
templateUrl: 'src/app/cluster/cluster-' + pst.url.substring(1) + '.tpl.html' templateUrl: 'src/app/monitoring/' + pst.url.substring(1) + '.tpl.html'
}); });
} }
alreadyExist = false; alreadyExist = false;

View File

@ -1,283 +1,201 @@
<div ng-controller="globalCtrl"> <div ng-controller="globalCtrl">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="accordion-style1 panel-group accordion-style2" id="accordion"> <form id="generalForm" class="form-horizontal" role="form">
<accordion close-others="true"> <!-- Use metadata to generate the form. might be used later -->
<accordion-group ng-init="status1.open=true" is-open="status1.open"> <!--<div class="form-group" ng-repeat="(key, data) in os_global_config['general']">
<accordion-heading> <div ng-if="key!='_self'">
<i class="ace-icon fa fa-angle-right" ng-class="{'fa-angle-down': status1.open, 'fa-angle-right': !status1.open}"></i> General <label class="col-sm-4 control-label no-padding-right">{{data.display}}</label>
</accordion-heading> <div class="col-sm-8">
<div class="row"> <input type="text" class="col-xs-10 col-sm-5" placeholder="{{data.display}}" name="{{key}}" popover-title="Help" popover="{{data.description}}" popover-trigger="focus" popover-placement="right">
<div class="col-xs-12"> </div>
<form id="generalForm" class="form-horizontal" role="form"> </div>
<!-- Use metadata to generate the form. might be used later --> </div>-->
<!--<div class="form-group" ng-repeat="(key, data) in os_global_config['general']"> <!--TODO: use json to generate inputs-->
<div ng-if="key!='_self'"> <div class="form-group">
<label class="col-sm-4 control-label no-padding-right">{{data.display}}</label> <div>
<div class="col-sm-8"> <label class="col-sm-4 control-label no-padding-right">
<input type="text" class="col-xs-10 col-sm-5" placeholder="{{data.display}}" name="{{key}}" popover-title="Help" popover="{{data.description}}" popover-trigger="focus" popover-placement="right"> Language
</div> <span class="text-danger">*</span>
</div> </label>
</div>--> <div class="col-sm-8">
<!--TODO: use json to generate inputs--> <select ng-model="general.language" name="language" class="col-xs-10 col-sm-5">
<div class="form-group"> <option value="en">English</option>
<div> <option value="cn">Chinese</option>
<label class="col-sm-4 control-label no-padding-right"> </select>
Language
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<select ng-model="general.language" name="language" class="col-xs-10 col-sm-5">
<option value="en">English</option>
<option value="cn">Chinese</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
Timezone
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<select ng-model="general.timezone" name="timezone" class="col-xs-10 col-sm-5">
<option ng-repeat="tm in timezones" value="{{tm.value}}">{{tm.timezone}}</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
HTTP Proxy
<span class="text-danger opacity-zero">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.http_proxy" type="text" class="col-xs-10 col-sm-5" placeholder="HTTP Proxy" name="http_proxy">
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
HTTPS Proxy
<span class="text-danger opacity-zero">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.https_proxy" type="text" class="col-xs-10 col-sm-5" placeholder="HTTPS Proxy" name="https_proxy">
</div>
</div>
</div>
<div ng-repeat="no_proxy in general.no_proxy track by $index" class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
<span ng-if="$index==0">
No Proxy
<span class="text-danger opacity-zero">*</span>
</span>
</label>
<div class="col-sm-8">
<input ng-model="general.no_proxy[$index]" type="text" class="col-xs-10 col-sm-5" placeholder="No Proxy" name="no_proxy">
<span class="col-xs-2 col-sm-3">
<!--Add Action-->
<span class="action" ng-click="addValue('no_proxy')">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="general.no_proxy.length > 1" class="action" ng-click="general.no_proxy.splice($index,1)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</span>
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
NTP Server
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.ntp_server" type="text" class="col-xs-10 col-sm-5" placeholder="NTP Server" name="ntp_server">
</div>
</div>
</div>
<div ng-repeat="dns_server in general.dns_servers track by $index" class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
<span ng-if="$index==0">
DNS Servers
<span class="text-danger">*</span>
</span>
</label>
<div class="col-sm-8">
<input ng-model="general.dns_servers[$index]" type="text" class="col-xs-10 col-sm-5" placeholder="DNS Server" name="dns_servers">
<span class="col-xs-2 col-sm-3">
<!--Add Action-->
<span class="action" ng-click="addValue('dns_servers')">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="general.dns_servers.length > 1" class="action" ng-click="general.dns_servers.splice($index,1)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</span>
</div>
</div>
</div>
<div ng-repeat="search_path in general.search_path track by $index" class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
<span ng-if="$index==0">
Search Path
<span class="text-danger">*</span>
</span>
</label>
<div class="col-sm-8">
<input ng-model="general.search_path[$index]" type="text" class="col-xs-10 col-sm-5" placeholder="Search Path" name="search_path">
<span class="col-xs-2 col-sm-3">
<!--Add Action-->
<span class="action" ng-click="addValue('search_path')">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="general.search_path.length > 1" class="action" ng-click="general.search_path.splice($index,1)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</span>
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
Domain
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.domain" type="text" class="col-xs-10 col-sm-5" placeholder="Domain" name="domain">
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
Default Gateway
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.default_gateway" type="text" class="col-xs-10 col-sm-5" placeholder="Gateway" name="gateway">
</div>
</div>
</div>
</form>
</div>
</div> </div>
</accordion-group> </div>
</div>
<accordion-group is-open="status2.open"> <div class="form-group">
<accordion-heading> <div>
<i class="ace-icon fa fa-angle-right" ng-class="{'fa-angle-down': status2.open, 'fa-angle-right': !status2.open}"></i> Subnetwork <label class="col-sm-4 control-label no-padding-right">
</accordion-heading> Timezone
<div class="row"> <span class="text-danger">*</span>
<div class="col-lg-2"> </label>
</div> <div class="col-sm-8">
<div class="col-lg-8"> <select ng-model="general.timezone" name="timezone" class="col-xs-10 col-sm-5">
<table class="table table-hover nowrap"> <option ng-repeat="tm in timezones" value="{{tm.value}}">{{tm.timezone}}</option>
<thead> </select>
<tr>
<th>Name</th>
<th>Subnet</th>
<!--th>Netmask</th-->
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sub in subnetworks">
<td>
<input type="text" ng-model="sub.name" placeholder="Name" />
</td>
<td>
<input type="text" ng-model="sub.subnet" placeholder="Subnet" />
</td>
<!--td>
<input type="text" ng-model="sub.netmask" placeholder="Netmask" />
</td-->
<td>
<!--Add Action-->
<span class="action" ng-click="addSubnetwork()">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="subnetworks.length > 1" class="action" ng-click="removeSubnetwork($index)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-lg-2">
</div>
</div> </div>
</div>
</accordion-group> </div>
<div class="form-group">
<!--Keep routing table for later use--> <div>
<!--<accordion-group is-open="status.open"> <label class="col-sm-4 control-label no-padding-right">
<accordion-heading> HTTP Proxy
<i class="ace-icon fa fa-angle-right" ng-class="{'fa-angle-down': status.open, 'fa-angle-right': !status.open}"></i> Routing Table <span class="text-danger opacity-zero">*</span>
</accordion-heading> </label>
<div class="row"> <div class="col-sm-8">
<div class="col-lg-2"> <input ng-model="general.http_proxy" type="text" class="col-xs-10 col-sm-5" placeholder="HTTP Proxy" name="http_proxy">
</div>
<div class="col-lg-8">
<table class="table table-hover nowrap">
<thead>
<tr>
<th>Name</th>
<th>Subnet</th>
<th>Netmask</th>
<th>Gateway</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="route in routingtable">
<td>
<input type="text" ng-model="route.name" placeholder="Name" />
</td>
<td>
<input type="text" ng-model="route.subnet" placeholder="Subnet" />
</td>
<td>
<input type="text" ng-model="route.netmask" placeholder="Netmask" />
</td>
<td>
<input type="text" ng-model="route.gateway" placeholder="Gateway" />
</td>
<td>
<span class="action" ng-click="addRoute()">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<span ng-show="routingtable.length > 1" class="action" ng-click="removeRoute($index)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm-2">
</div>
</div> </div>
</accordion-group>--> </div>
</accordion> </div>
</div> <div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
HTTPS Proxy
<span class="text-danger opacity-zero">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.https_proxy" type="text" class="col-xs-10 col-sm-5" placeholder="HTTPS Proxy" name="https_proxy">
</div>
</div>
</div>
<div ng-repeat="no_proxy in general.no_proxy track by $index" class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
<span ng-if="$index==0">
No Proxy
<span class="text-danger opacity-zero">*</span>
</span>
</label>
<div class="col-sm-8">
<input ng-model="general.no_proxy[$index]" type="text" class="col-xs-10 col-sm-5" placeholder="No Proxy" name="no_proxy">
<span class="col-xs-2 col-sm-3">
<!--Add Action-->
<span class="action" ng-click="addValue('no_proxy')">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="general.no_proxy.length > 1" class="action" ng-click="general.no_proxy.splice($index,1)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</span>
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
NTP Server
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.ntp_server" type="text" class="col-xs-10 col-sm-5" placeholder="NTP Server" name="ntp_server">
</div>
</div>
</div>
<div ng-repeat="dns_server in general.dns_servers track by $index" class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
<span ng-if="$index==0">
DNS Servers
<span class="text-danger">*</span>
</span>
</label>
<div class="col-sm-8">
<input ng-model="general.dns_servers[$index]" type="text" class="col-xs-10 col-sm-5" placeholder="DNS Server" name="dns_servers">
<span class="col-xs-2 col-sm-3">
<!--Add Action-->
<span class="action" ng-click="addValue('dns_servers')">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="general.dns_servers.length > 1" class="action" ng-click="general.dns_servers.splice($index,1)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</span>
</div>
</div>
</div>
<div ng-repeat="search_path in general.search_path track by $index" class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
<span ng-if="$index==0">
Search Path
<span class="text-danger">*</span>
</span>
</label>
<div class="col-sm-8">
<input ng-model="general.search_path[$index]" type="text" class="col-xs-10 col-sm-5" placeholder="Search Path" name="search_path">
<span class="col-xs-2 col-sm-3">
<!--Add Action-->
<span class="action" ng-click="addValue('search_path')">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<!--Remove Action-->
<span ng-show="general.search_path.length > 1" class="action" ng-click="general.search_path.splice($index,1)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</span>
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
Domain
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.domain" type="text" class="col-xs-10 col-sm-5" placeholder="Domain" name="domain">
</div>
</div>
</div>
<div class="form-group">
<div>
<label class="col-sm-4 control-label no-padding-right">
Default Gateway
<span class="text-danger">*</span>
</label>
<div class="col-sm-8">
<input ng-model="general.default_gateway" type="text" class="col-xs-10 col-sm-5" placeholder="Gateway" name="gateway">
</div>
</div>
</div>
</form>
<!--table class="table table-hover nowrap">
<thead>
<tr>
<th>Name</th>
<th>Subnet</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sub in subnetworks">
<td>
<input type="text" ng-model="sub.name" placeholder="Name" />
</td>
<td>
<input type="text" ng-model="sub.subnet" placeholder="Subnet" />
</td>
<td>
<span class="action" ng-click="addSubnetwork()">
<i class="fa fa-plus-circle bigger-140 blue"></i>
</span>
<span ng-show="subnetworks.length > 1" class="action" ng-click="removeSubnetwork($index)">
<i class="fa fa-minus-circle bigger-140 blue"></i>
</span>
</td>
</tr>
</tbody>
</table!-->
</div> </div>
</div> </div>
</div> </div>

View File

@ -6,15 +6,19 @@
</span> </span>
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="row"> <div class="row">
<div class="col-lg-6 col-md-6 col-sm-6"> <div class="col-sm-12">
<h4>Interfaces Management</h4> <h4>
Autofill IP Address for Each Interface
<button class="btn btn-sm btn-info pull-right" ng-click="openAddSubnetModal()">Add Subnet</button>
</h4>
<table class="table table-hover nowrap"> <table class="table table-hover nowrap">
<thead> <thead>
<tr> <tr>
<th>Interface</th> <th>Interface</th>
<th>Subnet</th>
<th>Is Mgmt Network</th> <th>Is Mgmt Network</th>
<th>Promisc</th> <th>Promisc Mode</th>
<th>Subnet</th>
<th>Autofill Rules</th>
<th>Action</th> <th>Action</th>
</tr> </tr>
</thead> </thead>
@ -23,29 +27,25 @@
<td> <td>
<input class="input-small" type="text" ng-model="newInterface.name" placeholder="Interface" required /> <input class="input-small" type="text" ng-model="newInterface.name" placeholder="Interface" required />
</td> </td>
<td></td>
<td></td>
<td> <td>
<select ng-model="newInterface.subnet_id" class="max-width-200"> <select ng-model="newInterface.subnet_id" class="max-width-200">
<option ng-repeat="sub in subnetworks" value="{{sub.id}}"> <option ng-repeat="sub in subnetworks" value="{{sub.id}}">
{{sub.name}} {{sub.subnet}}
</option> </option>
</select> </select>
</td> </td>
<td>-</td> <td></td>
<td>-</td>
<td> <td>
<span ng-click="addInterface(newInterface)" class="action"> <span ng-click="addInterface(newInterface)" class="action">
<i class="fa fa-plus-circle bigger-140 blue"></i> <i class="fa fa-plus-circle bigger-140 blue"></i>
</span> </span>
</td> </td>
</tr> </tr>
<tr ng-repeat="(name, value) in interfaces"> <tr ng-repeat="(interface_name, value) in interfaces track by $index">
<td> <td>
{{name}} {{interface_name}}
</td>
<td>
<span ng-repeat="sub in subnetworks">
<span ng-if="sub.id == value.subnet_id">{{sub.name}}</span>
</span>
</td> </td>
<td> <td>
<label> <label>
@ -59,55 +59,51 @@
<span class="lbl"></span> <span class="lbl"></span>
</label> </label>
</td> </td>
<td>
<select ng-model="value.subnet_id" class="max-width-200">
<option ng-repeat="sub in subnetworks" value="{{sub.id}}" ng-selected="sub.id == value.subnet_id">
{{sub.subnet}}
</option>
</select>
</td>
<td>
<input id="{{interface_name}}-ipstart" type="text" class="input-medium" placeholder="IP Start">
<select id="{{interface_name}}-increase-num">
<option value="1">Increase by 1</option>
<option value="2">Increase by 2</option>
<option value="3">Increase by 3</option>
<option value="4">Increase by 4</option>
<option value="5">Increase by 5</option>
</select>
</td>
<td> <td>
<!--Remove Action--> <!--Remove Action-->
<span class="action" ng-click="deleteInterface(name)"> <span class="action" ng-click="deleteInterface(interface_name)">
<i class="fa fa-minus-circle bigger-140 blue"></i> <i class="fa fa-minus-circle bigger-140 blue"></i>
</span> </span>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div class="space-10"></div> <div class="space-10"></div>
</div> <hr>
<div class="col-lg-6 col-md-6 col-sm-6 autofill-section">
<h4>Autofill</h4>
<form role="form" class="form-horizontal ng-pristine ng-valid" id="autoForm">
<div class="form-group">
<div>
<label class="col-sm-3 control-label no-padding-right">
Hostname
</label>
<div class="col-sm-9">
<select id="hostname-rule" class="input-medium ng-pristine ng-valid">
<option value="host">Host</option>
<option value="switch_ip">Switch IP</option>
</select>
</div>
</div>
</div>
<div ng-repeat="(name, value) in interfaces" class="form-group">
<label class="col-sm-3 control-label no-padding-right">
{{name}}&nbsp;IP
</label>
<div class="col-sm-9">
<input id="{{name}}-ipstart" type="text" class="input-medium" placeholder="IP Start">
<select id="{{name}}-increase-num">
<option value="1">Increase by 1</option>
<option value="2">Increase by 2</option>
<option value="3">Increase by 3</option>
<option value="4">Increase by 4</option>
<option value="5">Increase by 5</option>
</select>
</div>
</div>
<div class="col-sm-offset-4">
<button ng-click="autofill()" class="btn btn-sm btn-primary">
Fill Values
</button>
</div>
</form>
<div class="space-10"></div> <div class="space-10"></div>
<h4>Autofill Hostname</h4>
<select id="hostname-rule" class="input-large">
<option value="">Please select a pattern</option>
<option value="host">Host</option>
<option value="switch_ip">Switch IP</option>
</select>
<div class="space-10"></div>
<div class="center">
<button ng-click="autofill()" class="btn btn-sm btn-primary">
Fill Values
</button>
</div>
</div> </div>
</div> </div>
<div class="space-10"></div> <div class="space-10"></div>
@ -214,4 +210,52 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div>
<script type="text/ng-template" id="addSubnetModal.html">
< div class = "modal-header" >
< h3 class = "modal-title" >
Subnetwork < /h3>
</div >
< div class = "modal-body" >
< alert ng - repeat = "alert in alerts"
type = "danger"
close = "closeAlert()" > {
{
alert.message
}
} < /alert>
<table class="table table-hover nowrap">
<thead>
<tr>
<th>Subnet</th >
< th > Actions < /th>
</tr >
< /thead>
<tbody>
<tr ng-repeat="sub in subnetworks">
<td>
<input type="text" ng-model="sub.subnet" placeholder="Subnet" / >
< /td>
<td>
<span class="action" ng-click="addSubnetwork()">
<i class="fa fa-plus-circle bigger-140 blue"></i >
< /span>
<span ng-show="subnetworks.length > 1" class="action" ng-click="removeSubnetwork($index)">
<i class="fa fa-minus-circle bigger-140 blue"></i >
< /span>
</td >
< /tr>
</tbody >
< /table>
</div >
< div class = "modal-footer" >
< button class = "btn btn-primary"
ng - click = "ok()" > OK < /button>
<button class="btn btn-grey" ng-click="cancel()">Cancel</button >
< /div>
</script>
</div>
</div> </div>

View File

@ -168,48 +168,48 @@
<div class="widget-main no-padding"> <div class="widget-main no-padding">
<div ng-include="currentTab"></div> <div ng-include="currentTab"></div>
<script type="text/ng-template" id="service.tpl.html"> <script type="text/ng-template" id="service.tpl.html">
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
<th> Service </th> <th>Service</th>
<th>Username</th > <th>Username</th>
<th> Password </th> <th>Password</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="(key, value) in service_credentials"> <tr ng-repeat="(key, value) in service_credentials">
<td>{{key}}</td> <td>{{key}}</td>
<td> {{value.username}}</td> <td>{{value.username}}</td>
<td>{{value.password}}</td > <td>{{value.password}}</td >
</tr> </tr>
</tbody > </tbody>
</table> </table>
</script> </script>
<script type="text/ng-template" id="console.tpl.html"> <script type="text/ng-template" id="console.tpl.html">
<table class="table table-striped" > <table class="table table-striped">
<thead> <thead>
<tr> <tr>
<th> Service </th> <th>Service</th>
<th>Username</th > <th>Username</th>
<th> Password </th> <th>Password</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="(key, value) in management_credentials"> <tr ng-repeat="(key, value) in management_credentials">
<td>{{key}}</td> <td>{{key}}</td >
<td>{{value.username}}</td> <td>{{value.username}}</td>
<td>{{value.password}}</td> <td>{{value.password}}</td>
</tr> </tr>
</tbody > </tbody>
</table> </table>
</script> </script>
<script type="text/ng-template" id="server.tpl.html"> <script type="text/ng-template" id="server.tpl.html">
<h6> <h6>
<strong> Username: </strong> <strong>Username:</strong>
{{server_credentials.username}} {{server_credentials.username}}
</h6> </h6>
<h6> <h6>
<strong> Password: </strong> <strong>Password:</strong>
{{server_credentials.password}} {{server_credentials.password}}
</h6> </h6>
</script> </script>
@ -218,5 +218,34 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-6">
<div class="widget-box transparent margin-top-minus10">
<div class="widget-header widget-header-flat">
<h4 class="widget-title lighter">
<i class="ace-icon fa fa-globe"></i>
OS Global Configurations
</h4>
<div class="widget-toolbar">
<a class="action" ng-click="isPartitionCollapsed = !isPartitionCollapsed">
<i class="ace-icon fa fa-chevron-up" ng-class="{'fa-chevron-up': !isPartitionCollapsed, 'fa-chevron-down': isPartitionCollapsed}"></i>
</a>
</div>
</div>
<div class="widget-body">
<div class="widget-body-inner" style="display: block;">
<div class="widget-main no-padding" collapse="isPartitionCollapsed">
<table class="table table-striped">
<tbody>
<tr ng-repeat="(key, value) in global_config">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -26,7 +26,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label no-padding-right">Confirm Password</label> <label class="col-sm-4 control-label no-padding-right">Confirm Password</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input type="password" class="col-xs-10 col-sm-5" placeholder="Confirm Password" value="{{server_credentials.password}}"> <input type="password" class="col-xs-10 col-sm-5" placeholder="Confirm Password">
</div> </div>
</div> </div>
</form> </form>

View File

@ -1,4 +1,15 @@
<div ng-controller="svSelectCtrl"> <div ng-controller="svSelectCtrl">
<div class="row">
<div collapse="findNewServersPanel.isCollapsed">
<div class="dashed-panel">
<span class="action pull-right" ng-click="findNewServersPanel.isCollapsed = true;">
<i class="ace-icon fa fa-times-circle bigger-120 light-grey"></i>
</span>
<div class="clearfix"></div>
<findservers results="foundResults"></findservers>
</div>
</div>
</div>
<div class="row"> <div class="row">
<div class="pull-left"> <div class="pull-left">
<!--Search Input--> <!--Search Input-->
@ -25,6 +36,12 @@
</div> </div>
</div> </div>
<div class="pull-right"> <div class="pull-right">
<button class="btn btn-info" ng-click="findNewServersPanel.isCollapsed = !findNewServersPanel.isCollapsed" ng-init="findNewServersPanel.isCollapsed = true;">
Discover Servers&nbsp;&nbsp;
<i class="ace-icon fa fa-plus" ng-class="{'fa-minus': !findNewServersPanel.isCollapsed}"></i>
</button>
</div>
<div class="pull-right side-padding-20">
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input ng-model="hideunselected" ng-change="hideUnselected()" type="checkbox" class="ace"> <input ng-model="hideunselected" ng-change="hideUnselected()" type="checkbox" class="ace">
@ -54,7 +71,7 @@
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="server in $data | filter:search"> <tr ng-repeat="server in $data | filter:search" ng-class="{'success': server.new}">
<td> <td>
<label> <label>
<input ng-model="server.selected" type="checkbox" class="ace"> <input ng-model="server.selected" type="checkbox" class="ace">

View File

@ -3,6 +3,7 @@ angular.module('compass.wizard', [
'ui.bootstrap', 'ui.bootstrap',
'ngTable', 'ngTable',
'compass.charts', 'compass.charts',
'compass.findservers',
'ngDragDrop', 'ngDragDrop',
'ngTouch', 'ngTouch',
'angularSpinner' 'angularSpinner'
@ -30,217 +31,208 @@ angular.module('compass.wizard', [
deferred.resolve(data); deferred.resolve(data);
}); });
return deferred.promise; return deferred.promise;
},
wizardStepsData: function($q, dataService) {
var deferred = $q.defer();
dataService.getWizardSteps().success(function(data) {
deferred.resolve(data);
});
return deferred.promise;
} }
} }
}); });
}) })
.controller('wizardCtrl', function($scope, dataService, wizardFactory, $stateParams, $state, clusterData, machinesHostsData, usSpinnerService) { .controller('wizardCtrl', function($scope, dataService, wizardFactory, $stateParams, $state, $modal, clusterData, machinesHostsData, wizardStepsData, usSpinnerService) {
$scope.clusterId = $stateParams.id; $scope.clusterId = $stateParams.id;
$scope.cluster = clusterData; $scope.cluster = clusterData;
wizardFactory.setClusterInfo($scope.cluster); wizardFactory.setClusterInfo($scope.cluster);
wizardFactory.setAllMachinesHost(machinesHostsData); wizardFactory.setAllMachinesHost(machinesHostsData);
// get pre-config data for wizard
if ($stateParams.config == "true") { if ($stateParams.config == "true") {
dataService.getWizardPreConfig().success(function(data) { dataService.getWizardPreConfig().success(function(data) {
wizardFactory.preConfig(data); wizardFactory.preConfig(data);
//$scope.cluster = wizardFactory.getClusterInfo();
}); });
} }
$scope.currentStep = 1; $scope.currentStep = 1;
$scope.pendingStep = 1;
$scope.maxStep = 1; $scope.maxStep = 1;
$scope.pendingStep = 1;
// Functions used only in HTML // get the create-cluster-wizard steps for os, ts or os_and_ts
$scope.steps = wizardStepsData["os_and_ts"];
wizardFactory.setSteps($scope.steps);
// start loading spinner
$scope.startSpin = function() { $scope.startSpin = function() {
usSpinnerService.spin('spinner-1'); usSpinnerService.spin('spinner-1');
} };
// stop loading spinner
$scope.stopSpin = function() { $scope.stopSpin = function() {
usSpinnerService.stop('spinner-1'); usSpinnerService.stop('spinner-1');
} };
$scope.testSpinClick = function() {
//usSpinnerService.stop('spinner-1');
usSpinnerService.spin('spinner-1');
}
// get the wizard steps for create-cluster // Watch commit state change
dataService.getWizardSteps().success(function(data) { $scope.$watch(function() {
// get the wizard steps for os, ts or os_and_ts return wizardFactory.getCommitState()
$scope.steps = data["os_and_ts"]; }, function(newCommitState, oldCommitState) {
wizardFactory.setSteps($scope.steps); if (newCommitState != oldCommitState && newCommitState.name == $scope.steps[$scope.currentStep - 1].name) {
$scope.$watch('pendingStep', function(newStep, oldStep) { if (newCommitState.state == "success") {
if (newStep != oldStep) { console.warn("### catch success in wizardCtrl ###", newCommitState, oldCommitState);
if ($scope.pendingStep <= $scope.maxStep + 1) { if (newCommitState.name == "review") {
if ((($scope.pendingStep == 6 || $scope.pendingStep == 7) && $scope.steps[2].state == "incomplete") || (($scope.pendingStep == 7 || $scope.pendingStep == 8) && $scope.steps[5].state == "incomplete") || ($scope.pendingStep == 8 && $scope.steps[6].state == "incomplete")) { $state.go("cluster.overview", {
usSpinnerService.stop('spinner-1'); 'id': $scope.cluster.id
alert("Please make sure pre-requisite steps are complete."); });
previousStepsComplete = false; }
$scope.pendingStep = $scope.currentStep;
return; $scope.stepControl();
} else {
var previousStepsComplete = true; if ($scope.currentStep > $scope.maxStep) {
//usSpinnerService.spin('spinner-1'); $scope.maxStep = $scope.currentStep;
if (previousStepsComplete == true) { }
if (oldStep != 8) {
var commitState = { } else if (newCommitState.state == "error") {
"name": $scope.steps[oldStep - 1].name, console.warn("### catch error in wizardCtrl ###", newCommitState, oldCommitState);
"state": "triggered", $scope.openErrMessageModal(newCommitState.message);
"message": ""
}; }
wizardFactory.setCommitState(commitState); }
} else { });
$scope.updateStepProgress($scope.pendingStep, $scope.currentStep);
$scope.currentStep = $scope.pendingStep; $scope.stepControl = function() {
//usSpinnerService.stop('spinner-1'); if ($scope.pendingStep <= $scope.maxStep + 1) {
} var previousStepsIncomplete = false;
} for (var i = 0; i < $scope.pendingStep - 1; i++) {
} if ($scope.steps[i].state == "incomplete") {
} else { previousStepsIncomplete = true;
usSpinnerService.stop('spinner-1'); break;
alert("Please complete previous steps first");
$scope.pendingStep = $scope.currentStep;
} }
} }
}); if (previousStepsIncomplete) {
var message = {
"message": "Please make sure pre-requisite steps are complete."
};
alert(message.message);
} else {
$scope.updateStepProgress($scope.pendingStep, $scope.currentStep);
$scope.currentStep = $scope.pendingStep;
}
} else {
var message = {
"message": "Please complete previous steps first"
};
alert(message.message);
$scope.pendingStep = $scope.currentStep;
}
}
// go to next step // Updates CSS Classes on Step state change
$scope.stepForward = function() { $scope.updateStepProgress = function(newStep, oldStep) {
// trigger commit for current step $scope.steps[newStep - 1].state = "active";
$scope.steps[oldStep - 1].state = "complete";
if (newStep == 1) {
if ($scope.maxStep > 2) {
$scope.steps[2].state = "incomplete";
}
if ($scope.maxStep > 5) {
$scope.steps[5].state = "incomplete";
}
if ($scope.maxStep > 6) {
$scope.steps[6].state = "incomplete";
}
}
if (newStep == 3) {
if ($scope.maxStep > 5) {
$scope.steps[5].state = "incomplete";
}
if ($scope.maxStep > 6) {
$scope.steps[6].state = "incomplete";
}
}
if (oldStep == 8) {
$scope.steps[7].state = "";
}
};
$scope.triggerCommit = function(stepId) {
if ($scope.steps[stepId - 1].name != "review") {
var commitState = { var commitState = {
"name": $scope.steps[$scope.currentStep - 1].name, "name": $scope.steps[stepId - 1].name,
"state": "triggered",
"message": {}
};
wizardFactory.setCommitState(commitState);
} else {
$scope.stepControl();
$scope.updateStepProgress($scope.pendingStep, 8);
//$scope.updateStepProgress($scope.pendingStep, stepId);
}
};
$scope.deploy = function() {
var wizard_complete = true;
for (var i = 0; i < $scope.steps.length - 1; i++) {
if ($scope.steps[i].state != "complete") {
wizard_complete = false;
break;
}
}
if (wizard_complete) {
var commitState = {
"name": "review",
"state": "triggered", "state": "triggered",
"message": "" "message": ""
}; };
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
}; }
};
// Watch commit state change $scope.stepForward = function() {
$scope.$watch(function() { $scope.triggerCommit($scope.currentStep);
return wizardFactory.getCommitState() $scope.pendingStep = $scope.currentStep + 1;;
}, function(newCommitState, oldCommitState) {
if ((newCommitState != oldCommitState) && (newCommitState.name == $scope.steps[$scope.currentStep - 1].name)) {
if (newCommitState.state == "success") {
console.warn("### catch success in wizardCtrl ###", newCommitState, oldCommitState);
$scope.alert = "";
if (newCommitState.name == "review") {
$state.go("cluster.overview", {
'id': $scope.cluster.id
});
}
$scope.updateStepProgress($scope.pendingStep, $scope.currentStep);
$scope.currentStep = $scope.pendingStep;
if ($scope.currentStep > $scope.maxStep) {
$scope.maxStep = $scope.currentStep;
}
//usSpinnerService.stop('spinner-1');
} else if (newCommitState.state == "error") {
$scope.pendingStep = $scope.currentStep;
// TODO: error handling / display error message
console.warn("### catch error in wizardCtrl ###", newCommitState, oldCommitState);
$scope.alerts = [];
$scope.alerts.push(newCommitState.message);
usSpinnerService.stop('spinner-1');
} };
}
})
// go to previous step
$scope.stepBackward = function() {
$scope.triggerCommit($scope.currentStep);
$scope.pendingStep = $scope.currentStep - 1;
};
// Updates CSS Classes on Step state change // go to step by stepId
$scope.updateStepProgress = function(newStep, oldStep) { $scope.skipForward = function(stepId) {
$scope.steps[newStep - 1].state = "active"; if ($scope.currentStep != stepId) {
$scope.steps[oldStep - 1].state = "complete";
if (newStep == 1) {
if ($scope.maxStep > 2) {
$scope.steps[2].state = "incomplete";
}
if ($scope.maxStep > 5) {
$scope.steps[5].state = "incomplete";
}
if ($scope.maxStep > 6) {
$scope.steps[6].state = "incomplete";
}
}
if (newStep == 3) {
if ($scope.maxStep > 5) {
$scope.steps[5].state = "incomplete";
}
if ($scope.maxStep > 6) {
$scope.steps[6].state = "incomplete";
}
}
if (newStep == 6) {
if ($scope.maxStep > 6) {
$scope.steps[6].state = "incomplete";
}
}
if (oldStep == 8) {
$scope.steps[7].state = "";
}
};
$scope.stepForward = function() {
if ($scope.currentStep == $scope.steps.length) {
usSpinnerService.stop('spinner-1');
}
if ($scope.currentStep != $scope.steps.length) {
if ($scope.pendingStep < $scope.steps.length)
$scope.pendingStep = $scope.pendingStep + 1;
}
};
// go to previous step
$scope.stepBackward = function() {
if ($scope.currentStep == 1) {
usSpinnerService.stop('spinner-1');
}
if ($scope.pendingStep > 1) {
$scope.pendingStep = $scope.pendingStep - 1;
}
};
// go to step by stepId
$scope.skipForward = function(stepId) {
$scope.pendingStep = stepId; $scope.pendingStep = stepId;
if ($scope.pendingStep == $scope.currentStep) { $scope.triggerCommit($scope.currentStep);
usSpinnerService.stop('spinner-1'); }
} };
}; $scope.openErrMessageModal = function(message) {
var modalInstance = $modal.open({
$scope.deploy = function() { templateUrl: "messagemodal.html",
var wizard_complete = true; controller: wizardModalInstanceCtrl,
for (var i = 0; i < $scope.steps.length; i++) resolve: {
if ($scope.steps[i].state == "incomplete") { warning: function() {
wizard_complete = false; return message;
} }
if (wizard_complete == true) {
var commitState = {
"name": $scope.steps[$scope.currentStep - 1].name,
"state": "triggered",
"message": ""
};
wizardFactory.setCommitState(commitState);
} }
}; });
modalInstance.result.then(function() {
});
}, function() {
console.log("modal dismissed")
})
};
dataService.getSubnetConfig().success(function(data) { dataService.getSubnetConfig().success(function(data) {
wizardFactory.setSubnetworks(data); wizardFactory.setSubnetworks(data);
}); });
}) })
.controller('svSelectCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService, usSpinnerService) { .controller('svSelectCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService) {
$scope.hideunselected = ''; $scope.hideunselected = '';
$scope.search = {}; $scope.search = {};
@ -248,11 +240,9 @@ angular.module('compass.wizard', [
$scope.allservers = wizardFactory.getAllMachinesHost(); $scope.allservers = wizardFactory.getAllMachinesHost();
usSpinnerService.stop('spinner-1');
$scope.tableParams = new ngTableParams({ $scope.tableParams = new ngTableParams({
page: 1, // show first page page: 1, // show first page
count: $scope.allservers.length // count per page count: $scope.allservers.length // count per page
}, { }, {
counts: [], // hide count-per-page box counts: [], // hide count-per-page box
total: $scope.allservers.length, // length of data total: $scope.allservers.length, // length of data
@ -330,11 +320,13 @@ angular.module('compass.wizard', [
} }
}) })
if (noSelection) { if (noSelection) {
alert("Please select at least one server"); var message = {
"message": "Please select at least one server"
}
var commitState = { var commitState = {
"name": "sv_selection", "name": "sv_selection",
"state": "error", "state": "error",
"message": "" "message": message
}; };
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
} else { } else {
@ -348,12 +340,32 @@ angular.module('compass.wizard', [
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
} }
}; };
// add newly found servers at the top if allservers array
$scope.$watch('foundResults', function(newResults, oldResults) {
if (newResults != oldResults) {
for (var i = 0; i < newResults.length; i++) {
var sv = $filter('filter')($scope.allservers, newResults[i].mac, true);
if (sv.length == 0) {
newResults[i].machine_id = newResults[i].id;
delete newResults[i]['id'];
newResults[i].new = true;
$scope.allservers.unshift(newResults[i]);
}
}
if ($scope.tableParams) {
$scope.tableParams.$params.count = $scope.allservers.length;
$scope.tableParams.reload();
}
}
}, true);
}) })
.controller('globalCtrl', function($scope, wizardFactory, dataService, $q, usSpinnerService) { .controller('globalCtrl', function($scope, wizardFactory, dataService, $q) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
//For General Section
$scope.general = wizardFactory.getGeneralConfig(); $scope.general = wizardFactory.getGeneralConfig();
if (!$scope.general["dns_servers"]) { if (!$scope.general["dns_servers"]) {
@ -366,8 +378,6 @@ angular.module('compass.wizard', [
$scope.general["no_proxy"] = [""]; $scope.general["no_proxy"] = [""];
} }
usSpinnerService.stop('spinner-1');
$scope.addValue = function(key) { $scope.addValue = function(key) {
$scope.general[key].push(""); $scope.general[key].push("");
}; };
@ -376,21 +386,6 @@ angular.module('compass.wizard', [
$scope.timezones = data; $scope.timezones = data;
}); });
//For Subnetworks Section
$scope.subnetworks = wizardFactory.getSubnetworks();
$scope.addSubnetwork = function() {
$scope.subnetworks.push({});
console.log($scope.subnetworks);
};
$scope.removeSubnetwork = function(index) {
$scope.subnetworks.splice(index, 1)
};
$scope.$watch('subnetworks', function() {
if ($scope.subnetworks.length == 0) {
$scope.subnetworks.push({});
}
}, true);
//For Routing Table Section //For Routing Table Section
//keep routing table for later use //keep routing table for later use
/* /*
@ -420,56 +415,27 @@ angular.module('compass.wizard', [
} }
}); });
$scope.commit = function() { $scope.commit = function() {
var promises = [];
var os_global_general = { var os_global_general = {
"os_config": { "os_config": {
"general": $scope.general "general": $scope.general
} }
}; };
var updateClusterConfig = dataService.updateClusterConfig(cluster.id, os_global_general).then(function(configData) { dataService.updateClusterConfig(cluster.id, os_global_general).success(function(configData) {
wizardFactory.setGeneralConfig(configData.data["os_config"]["general"]); wizardFactory.setGeneralConfig($scope.general);
}, function(response) {
return $q.reject(response);
});
promises.push(updateClusterConfig);
var subnetworks = [];
angular.forEach($scope.subnetworks, function(subnet) {
if (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.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 = { var commitState = {
"name": "os_global", "name": "os_global",
"state": "success", "state": "success",
"message": "" "message": ""
}; };
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
}, function(response) { }).error(function(response) {
console.log("promises error", response);
var commitState = { var commitState = {
"name": "os_global", "name": "os_global",
"state": "error", "state": "error",
"message": response.data "message": response
}; };
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
}); });
@ -508,7 +474,7 @@ angular.module('compass.wizard', [
*/ */
}) })
.controller('networkCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService, $q, usSpinnerService) { .controller('networkCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService, $q, $modal) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
$scope.subnetworks = wizardFactory.getSubnetworks(); $scope.subnetworks = wizardFactory.getSubnetworks();
$scope.interfaces = wizardFactory.getInterfaces(); $scope.interfaces = wizardFactory.getInterfaces();
@ -518,11 +484,9 @@ angular.module('compass.wizard', [
$scope.server_columns = data.showless; $scope.server_columns = data.showless;
}); });
usSpinnerService.stop('spinner-1');
$scope.tableParams = new ngTableParams({ $scope.tableParams = new ngTableParams({
page: 1, // show first page page: 1, // show first page
count: $scope.servers.length // count per page count: $scope.servers.length + 1 // count per page
}, { }, {
counts: [], // hide count-per-page box counts: [], // hide count-per-page box
total: $scope.servers.length, // length of data total: $scope.servers.length, // length of data
@ -566,7 +530,7 @@ angular.module('compass.wizard', [
}) })
if (!isExist) { if (!isExist) {
$scope.interfaces[newInterface.name] = { $scope.interfaces[newInterface.name] = {
"subnet_id": newInterface.subnet_id, "subnet_id": parseInt(newInterface.subnet_id),
"is_mgmt": false "is_mgmt": false
} }
} }
@ -608,7 +572,6 @@ angular.module('compass.wizard', [
"reinstall_os": server.reinstallos "reinstall_os": server.reinstallos
}); });
} }
usSpinnerService.stop('spinner-1');
}); });
var interfaceCount = Object.keys($scope.interfaces).length; var interfaceCount = Object.keys($scope.interfaces).length;
@ -647,7 +610,7 @@ angular.module('compass.wizard', [
var network = { var network = {
"interface": key, "interface": key,
"ip": value.ip, "ip": value.ip,
"subnet_id": $scope.interfaces[key].subnet_id, "subnet_id": parseInt($scope.interfaces[key].subnet_id),
"is_mgmt": $scope.interfaces[key].is_mgmt, "is_mgmt": $scope.interfaces[key].is_mgmt,
"is_promiscuous": $scope.interfaces[key].is_promiscuous "is_promiscuous": $scope.interfaces[key].is_promiscuous
}; };
@ -699,19 +662,35 @@ angular.module('compass.wizard', [
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
}, function(response) { }, function(response) {
wizardFactory.setServers($scope.servers); wizardFactory.setServers($scope.servers);
console.info($scope.servers)
var commitState = { var commitState = {
"name": "network", "name": "network",
"state": "error", "state": "error",
"message": response.statusText "message": response.data
}; };
console.info(response); console.info(response.data);
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
}); });
}); });
} }
}; };
$scope.openAddSubnetModal = function() {
var modalInstance = $modal.open({
templateUrl: "addSubnetModal.html",
controller: addSubnetModalInstanceCtrl,
resolve: {
subnets: function() {
return $scope.subnetworks;
}
}
});
modalInstance.result.then(function(subnets) {
$scope.subnetworks = subnets;
}, function() {
console.log("modal dismissed")
})
};
$scope.autofill = function() { $scope.autofill = function() {
// Autofill IP for each interface // Autofill IP for each interface
angular.forEach($scope.interfaces, function(value, key) { angular.forEach($scope.interfaces, function(value, key) {
@ -725,19 +704,21 @@ angular.module('compass.wizard', [
}; };
$scope.fillHostname = function(rule) { $scope.fillHostname = function(rule) {
switch (rule) { if (rule) {
case "host": switch (rule) {
var server_index = 1; case "host":
angular.forEach($scope.servers, function(server) { var server_index = 1;
server.name = "host-" + server_index; angular.forEach($scope.servers, function(server) {
server_index++; server.name = "host-" + server_index;
}) server_index++;
break; })
case "switch_ip": break;
angular.forEach($scope.servers, function(server) { case "switch_ip":
server.name = server.switch_ip.replace(/\./g, "-") + "-p" + server.port; angular.forEach($scope.servers, function(server) {
}) server.name = server.switch_ip.replace(/\./g, "-") + "-p" + server.port;
break; })
break;
}
} }
}; };
@ -774,7 +755,7 @@ angular.module('compass.wizard', [
} }
}) })
.controller('partitionCtrl', function($scope, wizardFactory, dataService, usSpinnerService) { .controller('partitionCtrl', function($scope, wizardFactory, dataService) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
$scope.partition = wizardFactory.getPartition(); $scope.partition = wizardFactory.getPartition();
@ -816,8 +797,6 @@ angular.module('compass.wizard', [
} }
}); });
usSpinnerService.stop('spinner-1');
$scope.commit = function() { $scope.commit = function() {
var os_partition = { var os_partition = {
"os_config": { "os_config": {
@ -843,7 +822,7 @@ angular.module('compass.wizard', [
}; };
}) })
.controller('securityCtrl', function($scope, wizardFactory, dataService, usSpinnerService) { .controller('securityCtrl', function($scope, wizardFactory, dataService) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
$scope.server_credentials = wizardFactory.getServerCredentials(); $scope.server_credentials = wizardFactory.getServerCredentials();
$scope.service_credentials = wizardFactory.getServiceCredentials(); $scope.service_credentials = wizardFactory.getServiceCredentials();
@ -978,10 +957,9 @@ angular.module('compass.wizard', [
wizardFactory.setCommitState(commitState); wizardFactory.setCommitState(commitState);
}); });
}; };
usSpinnerService.stop('spinner-1');
}) })
.controller('roleAssignCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService, $q, usSpinnerService) { .controller('roleAssignCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService, $q) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
$scope.servers = wizardFactory.getServers(); $scope.servers = wizardFactory.getServers();
@ -994,8 +972,6 @@ angular.module('compass.wizard', [
$scope.server_columns = data.showless; $scope.server_columns = data.showless;
}); });
usSpinnerService.stop('spinner-1');
$scope.selectAllServers = function(flag) { $scope.selectAllServers = function(flag) {
if (flag) { if (flag) {
angular.forEach($scope.servers, function(sv) { angular.forEach($scope.servers, function(sv) {
@ -1079,7 +1055,7 @@ angular.module('compass.wizard', [
}, true); }, true);
$scope.tableParams = new ngTableParams({ $scope.tableParams = new ngTableParams({
page: 1, // show first page page: 1, // show first page
count: $scope.servers.length // count per page count: $scope.servers.length + 1 // count per page
}, { }, {
counts: [], // hide count-per-page box counts: [], // hide count-per-page box
total: $scope.servers.length, // length of data total: $scope.servers.length, // length of data
@ -1179,13 +1155,11 @@ angular.module('compass.wizard', [
}; };
}) })
.controller('networkMappingCtrl', function($scope, wizardFactory, dataService, usSpinnerService) { .controller('networkMappingCtrl', function($scope, wizardFactory, dataService) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
$scope.interfaces = wizardFactory.getInterfaces(); $scope.interfaces = wizardFactory.getInterfaces();
$scope.networking = wizardFactory.getNetworkMapping(); $scope.networking = wizardFactory.getNetworkMapping();
usSpinnerService.stop('spinner-1');
$scope.pendingInterface = ""; $scope.pendingInterface = "";
$scope.onDrop = function($event, key) { $scope.onDrop = function($event, key) {
@ -1256,7 +1230,7 @@ angular.module('compass.wizard', [
}; };
}) })
.controller('reviewCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService, usSpinnerService) { .controller('reviewCtrl', function($scope, wizardFactory, dataService, $filter, ngTableParams, sortingService) {
var cluster = wizardFactory.getClusterInfo(); var cluster = wizardFactory.getClusterInfo();
$scope.servers = wizardFactory.getServers(); $scope.servers = wizardFactory.getServers();
$scope.interfaces = wizardFactory.getInterfaces(); $scope.interfaces = wizardFactory.getInterfaces();
@ -1265,13 +1239,12 @@ angular.module('compass.wizard', [
$scope.server_credentials = wizardFactory.getServerCredentials(); $scope.server_credentials = wizardFactory.getServerCredentials();
$scope.service_credentials = wizardFactory.getServiceCredentials(); $scope.service_credentials = wizardFactory.getServiceCredentials();
$scope.management_credentials = wizardFactory.getManagementCredentials(); $scope.management_credentials = wizardFactory.getManagementCredentials();
$scope.global_config = wizardFactory.getGeneralConfig();
dataService.getServerColumns().success(function(data) { dataService.getServerColumns().success(function(data) {
$scope.server_columns = data.review; $scope.server_columns = data.review;
}); });
usSpinnerService.stop('spinner-1');
$scope.tabs = [{ $scope.tabs = [{
title: 'Database & Queue', title: 'Database & Queue',
url: 'service.tpl.html' url: 'service.tpl.html'
@ -1295,7 +1268,7 @@ angular.module('compass.wizard', [
$scope.tableParams = new ngTableParams({ $scope.tableParams = new ngTableParams({
page: 1, // show first page page: 1, // show first page
count: $scope.servers.length // count per page count: $scope.servers.length + 1// count per page
}, { }, {
counts: [], // hide count-per-page box counts: [], // hide count-per-page box
total: $scope.servers.length, // length of data total: $scope.servers.length, // length of data
@ -1370,4 +1343,75 @@ angular.module('compass.wizard', [
}) })
//TODO: error handling //TODO: error handling
}; };
}) });
var wizardModalInstanceCtrl = function($scope, $modalInstance, warning) {
$scope.warning = warning;
$scope.ok = function() {
$modalInstance.close();
};
};
var addSubnetModalInstanceCtrl = function($scope, $modalInstance, $q, subnets, dataService) {
$scope.subnetworks = subnets;
$scope.ok = function() {
var subnetworks = [];
var promises = [];
angular.forEach($scope.subnetworks, function(subnet) {
if (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.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;
$modalInstance.close($scope.subnetworks);
}, function(response) {
console.log("promises error", response);
$scope.alerts = [];
$scope.alerts.push({
"message": response
});
});
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
$scope.closeAlert = function() {
$scope.alerts = [];
};
$scope.addSubnetwork = function() {
$scope.subnetworks.push({});
console.log($scope.subnetworks);
};
$scope.removeSubnetwork = function(index) {
$scope.subnetworks.splice(index, 1)
};
$scope.$watch('subnetworks', function() {
if ($scope.subnetworks.length == 0) {
$scope.subnetworks.push({});
}
}, true);
};

View File

@ -1,6 +1,6 @@
<div class="main-content"> <div class="main-content">
<div class="page-content" ng-swipe-right="startSpin(); stepForward()" ng-swipe-left="startSpin(); stepBackward()"> <!--div class="page-content" ng-swipe-right="stepForward()" ng-swipe-left="stepBackward()"-->
<div class="page-content">
<div class="page-header"> <div class="page-header">
<h1>Create Cluster Wizard</h1> <h1>Create Cluster Wizard</h1>
<span us-spinner="{radius:30, length: 20, lines:13, width:10}" spinner-key="spinner-1"></span> <span us-spinner="{radius:30, length: 20, lines:13, width:10}" spinner-key="spinner-1"></span>
@ -8,7 +8,7 @@
<div id="create-cluster-wizard"> <div id="create-cluster-wizard">
<ul class="wizard-steps"> <ul class="wizard-steps">
<li ng-repeat="step in steps" class="{{step.state}}" ng-click="startSpin(); skipForward(step.id)"> <li ng-repeat="step in steps" class="{{step.state}}" ng-click="skipForward(step.id)">
<span class="step">{{step.id}}</span> <span class="step">{{step.id}}</span>
<span class="title">{{step.title}}</span> <span class="title">{{step.title}}</span>
</li> </li>
@ -33,53 +33,45 @@
<div class="space-10"></div> <div class="space-10"></div>
<div class="wizard-actions"> <div class="wizard-actions">
<div class="inline" ng-class="{'first-prev' : currentStep == 1}"> <button ng-click="stepBackward()" ng-disabled="currentStep == 1" class="btn btn-grey btn-prev-spacing" ng-class="{'btn-light' : currentStep == 1}">
<button ng-click="stepBackward()" ng-disabled="currentStep==1" class="btn btn-grey btn-prev-spacing" ng-class="{'btn-light' : currentStep == 1}"> <i class="ace-icon fa fa-arrow-left"></i>
<i class="ace-icon fa fa-arrow-left"></i> Prev
Prev </button>
</button>
</div> <span ng-if="currentStep < steps.length">
<button ng-click="stepForward()" class="btn btn-success btn-next"> <button ng-click="stepForward()" class="btn btn-success btn-next">
<span ng-if="currentStep<steps.length">
Next Next
<i class="ace-icon fa fa-arrow-right icon-on-right"></i> <i class="ace-icon fa fa-arrow-right icon-on-right"></i>
</span> </button>
<span ng-if="currentStep==steps.length">Deploy</span> </span>
</button>
<span ng-if="currentStep == steps.length">
<button ng-click="deploy()" class="btn btn-success btn-next">
<span>Deploy</span>
</button>
</span>
</div> </div>
</div> </div>
<div ng-repeat="alert in alerts" class="popup-alert">
<div class="gritter-item-wrapper gritter-error gritter-center">
<div class="gritter-top"></div>
<div class="gritter-item message">
<div class="gritter-close action pull-right" ng-click="alerts.splice($index, 1)"></div>
<div class="clearfix"></div>
<div class="gritter-without-image">
<p>
<span ng-if="!alert.message">Error</span>
<span ng-if="alert.message">{{alert.message}}</span>
</p>
</div>
<div class="clearfix"></div>
</div>
<div class="gritter-bottom">
</div>
</div>
<span ng-if="currentStep<steps.length">
<button ng-click="startSpin(); stepForward()" class="btn btn-success btn-next">
Next
<i class="ace-icon fa fa-arrow-right icon-on-right"></i>
</button>
</span>
<span ng-if="currentStep==steps.length">
<button ng-click="deploy()" class="btn btn-success btn-next">
<span>Deploy</span>
</button>
</span>
</div>
</div> </div>
</div> </div>
<div>
<script type="text/ng-template" id="messagemodal.html">
<div class="modal-header">
<h3 class="modal-title">
<i class="ace-icon fa fa-exclamation-triangle orange"></i>
Warning
</h3>
</div>
<div class="modal-body">
<span ng-if="warning.message">
{{warning.message}}
</span>
<span ng-if="warning.message === undefined">
Error occured.
</span>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
</div>
</script>
</div>

View File

@ -78,6 +78,7 @@ angular.module('compass.charts', [])
clusterstate: '=', clusterstate: '=',
progressdata: '@' progressdata: '@'
}, },
templateUrl: "src/common/progressbar.tpl.html",
link: function(scope, element, attrs) { link: function(scope, element, attrs) {
var hostId = scope.hostid; var hostId = scope.hostid;
var clusterId = scope.clusterid; var clusterId = scope.clusterid;
@ -114,77 +115,7 @@ angular.module('compass.charts', [])
fireTimer = false; fireTimer = false;
$timeout.cancel(progressTimer); $timeout.cancel(progressTimer);
}); });
},
templateUrl: "src/common/progressbar.tpl.html"
}
})
.directive('switchrow', function(dataService, $timeout) {
return {
restrict: 'A',
scope: {
polling: '=',
switchinfo: '=',
result: '=',
machines: '='
},
link: function(scope, element, attrs) {
var checkSwitchTimer;
var checkSwitchCount = 0;
//var pollingTriggered = scope.polling;
var fireTimer = true;
var getMachines = function() {
dataService.getSwitchMachines(scope.switchinfo.id).success(function(data) {
scope.polling = false;
scope.result = "success";
scope.machines = data;
}).error(function(data) {
scope.polling = false;
scope.result = "error";
})
};
// check switch state 15 times with the interval of 2 sec
var checkSwitchState = function() {
checkSwitchCount++;
dataService.getSwitchById(scope.switchinfo.id).success(function(data) {
if (data.state == "under_monitoring") {
getMachines();
} else if(data.state === "initialized" || data.state === "repolling")
if (fireTimer && checkSwitchCount < 15) {
checkSwitchTimer = $timeout(checkSwitchState, 2000);
} else {
scope.polling = false;
scope.result = "error";
}
else {
scope.polling = false;
scope.result = "error";
}
})
};
scope.$watch('polling', function(newval, oldval) {
if(newval != oldval) {
if (newval == true) {
checkSwitchCount = 0;
fireTimer = true;
var findingAction = {
"find_machines": null
};
dataService.postSwitchAction(scope.switchinfo.id, findingAction).success(function(data) {
checkSwitchState();
})
}
}
})
element.bind('$destroy', function() {
fireTimer = false;
$timeout.cancel(checkSwitchTimer);
});
} }
} }
}) })

View File

@ -1,17 +1,63 @@
<div class="row" ng-controller="findNewServersCtrl"> <div class="row">
<div class="col-lg-5 col-md-5"> <div class="col-lg-6 col-md-6">
<h4>
Add Switches
</h4>
<div>
Enter the IP address for the network switches on which the servers are connected.
</div>
<div class="space-10"></div>
<div>
<form name="addSwitchForm" class="form-horizontal">
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Switch IP</label>
<div class="col-sm-9">
<input type="text" ng-model="newswitch.ip" placeholder="Switch IP" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Version</label>
<div class="col-sm-9">
<select ng-model="newswitch.credentials.version" required>
<option>1</option>
<option>2c</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Community</label>
<div class="col-sm-9">
<input type="password" ng-model="newswitch.credentials.community" placeholder="Community" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Port Filter</label>
<div class="col-sm-9">
<input type="text" ng-model="filters.ports" placeholder="Port Filter">
</div>
</div>
</form>
<div class="clearfix">
<div class="col-md-offset-3 col-md-9">
<button class="btn btn-primary" ng-click="addSwitch()" ng-disabled="addSwitchForm.$invalid">Add</button>
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-md-6">
<h4> <h4>
Discover available servers Discover available servers
</h4> </h4>
<!--span class="help-button pull-left" popover-trigger="mouseenter" popover-placement="right" popover-title="Help" popover="Enter the IP address for the network switches on which the servers are connected. Select as many switches as needed and then click Find Servers.">?</span> <div>
<div class="clearfix"></div--> Select as many switches as needed and then click Find Servers.
</div>
<div class="space-10"></div> <div class="space-10"></div>
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th> <th>
<label> <label>
<input ng-model="selectall" ng-change="selectAllSwitches(selectall)" type="checkbox" class="ace" ng-disabled="findingNewServers"> <input ng-model="selectall" ng-change="selectAllSwitches(selectall)" type="checkbox" class="ace" ng-disabled="isFindingNewServers">
<span class="lbl"></span> <span class="lbl"></span>
</label> </label>
</th> </th>
@ -28,7 +74,7 @@
<tr ng-repeat="switch in switches" switchrow polling="switch.polling" machines="switch.machines" result="switch.result" switchinfo="switch"> <tr ng-repeat="switch in switches" switchrow polling="switch.polling" machines="switch.machines" result="switch.result" switchinfo="switch">
<td> <td>
<label> <label>
<input type="checkbox" class="ace" ng-model="switch.selected" ng-disabled="findingNewServers && switch.selected && !switch.finished"> <input type="checkbox" class="ace" ng-model="switch.selected" ng-disabled="isFindingNewServers && switch.selected && !switch.finished">
<span class="lbl"></span> <span class="lbl"></span>
</label> </label>
</td> </td>
@ -39,7 +85,7 @@
<span ng-if="switch.result == 'error'"> <span ng-if="switch.result == 'error'">
<i class="ace-icon fa fa-frown-o bigger-125 red"></i> <i class="ace-icon fa fa-frown-o bigger-125 red"></i>
</span> </span>
<span ng-if="findingNewServers && switch.selected && !switch.finished"> <span ng-if="isFindingNewServers && switch.selected && !switch.finished">
<i class="ace-icon fa fa-spinner fa-spin bigger-125 orange"></i> <i class="ace-icon fa fa-spinner fa-spin bigger-125 orange"></i>
</span> </span>
</td> </td>
@ -53,47 +99,10 @@
</table> </table>
<div class="space-10"></div> <div class="space-10"></div>
<div class="center"> <div class="center">
<button class="btn btn-sm btn-success" ng-click="open()">
<span>
Add Switch
</span>
</button>
<button class="btn btn-sm btn-primary" ng-click="findServers()"> <button class="btn btn-sm btn-primary" ng-click="findServers()">
Discover Servers Discover Servers
</button> </button>
</div> </div>
<div ng-include="'src/app/server/add-switch-modal.tpl.html'"></div>
<div class="space-20"></div> <div class="space-20"></div>
</div> </div>
<div class="col-lg-7 col-md-7">
<h4>
Discover Results
<input class="pull-right" type="text" placeholder="Search" ng-model="search_new_server">
</h4>
<div class="space-10"></div>
<div class="table-responsive new-servers-result">
<table ng-table="tableParamsNewServer" class="table table-striped">
<thead>
<tr>
<th ng-repeat="column in server_columns" ng-show="column.visible" class="sortable" ng-class="{'sort-asc': tableParamsNewServer.isSortBy(column.field, 'asc'), 'sort-desc': tableParamsNewServer.isSortBy(column.field, 'desc')}" ng-click="tableParamsNewServer.sorting(column.field, tableParamsNewServer.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
<div>{{column.title}}</div>
</th>
</tr>
</thead>
<tbody>
<tr ng-show="tableParamsNewServer.data.length==0">
<td colspan="6" class="center">No results for selected switches</td>
</tr>
<tr ng-repeat="sv in $data | filter:search_new_server">
<td ng-repeat="column in server_columns" ng-show="column.visible">
<span>
{{sv[column.field]}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div> </div>

View File

@ -0,0 +1,168 @@
angular.module('compass.findservers', [])
.directive('switchrow', function(dataService, $timeout) {
return {
restrict: 'A',
scope: {
polling: '=',
switchinfo: '=',
result: '=',
machines: '='
},
link: function(scope, element, attrs) {
var checkSwitchTimer;
var checkSwitchCount = 0;
//var pollingTriggered = scope.polling;
var fireTimer = true;
var getMachines = function() {
dataService.getSwitchMachines(scope.switchinfo.id).success(function(data) {
scope.polling = false;
scope.result = "success";
scope.machines = data;
}).error(function(data) {
scope.polling = false;
scope.result = "error";
})
};
// check switch state 15 times with the interval of 2 sec
var checkSwitchState = function() {
checkSwitchCount++;
dataService.getSwitchById(scope.switchinfo.id).success(function(data) {
if (data.state == "under_monitoring") {
getMachines();
} else if(data.state === "initialized" || data.state === "repolling")
if (fireTimer && checkSwitchCount < 15) {
checkSwitchTimer = $timeout(checkSwitchState, 2000);
} else {
scope.polling = false;
scope.result = "error";
}
else {
scope.polling = false;
scope.result = "error";
}
})
};
scope.$watch('polling', function(newval, oldval) {
if(newval != oldval) {
if (newval == true) {
checkSwitchCount = 0;
fireTimer = true;
var findingAction = {
"find_machines": null
};
dataService.postSwitchAction(scope.switchinfo.id, findingAction).success(function(data) {
checkSwitchState();
})
}
}
})
element.bind('$destroy', function() {
fireTimer = false;
$timeout.cancel(checkSwitchTimer);
});
}
}
})
.directive('findservers', function(dataService, $modal) {
return {
restrict: 'E',
scope: {
newFoundServers: '=results'
},
templateUrl: "src/common/findservers/find-new-servers.tpl.html",
link: function(scope, element, attrs) {
scope.switches = [];
scope.newFoundServers = [];
scope.isFindingNewServers = false;
dataService.getSwitches().success(function(data) {
scope.switches = data;
});
scope.selectAllSwitches = function(flag) {
if (flag) {
angular.forEach(scope.switches, function(sv) {
sv.selected = true;
})
} else {
angular.forEach(scope.switches, function(sv) {
sv.selected = false;
})
}
};
scope.findServers = function() {
var swSelection = false;
angular.forEach(scope.switches, function(sw) {
if (sw.selected) {
swSelection = true;
}
});
if (!swSelection) {
alert("Please select at least one switch");
} else {
scope.isFindingNewServers = true;
scope.newFoundServers = [];
angular.forEach(scope.switches, function(sw) {
if (sw.selected) {
sw.result = "";
sw.finished = false;
sw.polling = true;
}
});
}
};
scope.$watch('switches', function(val) {
var totalResultReady = true;
if (scope.isFindingNewServers) {
angular.forEach(scope.switches, function(sw) {
if (sw.selected && !sw.finished) {
if (sw.result == "success") {
scope.newFoundServers = scope.newFoundServers.concat(angular.copy(sw.machines));
sw.finished = true;
} else if (sw.result == "error") {
sw.finished = true;
} else {
totalResultReady = false;
}
}
});
if (totalResultReady) {
scope.isFindingNewServers = false;
}
}
}, true);
scope.newswitch = {}
scope.newswitch.credentials = {};
scope.filters = {};
scope.addSwitch = function() {
dataService.postSwitches(scope.newswitch).success(function(switchData) {
if (scope.filters) {
var filters = {
"filters": scope.filters
};
dataService.putSwitchFilters(switchData.id, filters).success(function(filterData) {
switchData.filters = filterData.filters;
scope.newswitch = {};
scope.filters = {};
scope.switches.push(switchData);
})
}
})
};
}
};
})