Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Commit

Permalink
show pool validation errors on the form
Browse files Browse the repository at this point in the history
While creating/updating a pool,if the server
throws any validation errors for the parameters sent
on the request, the errors will be shown near
to the respective field itself.

In case the error is not specific to any of the fields,
then it will be shown in a popup.

Fixes: #7480
Signed-off-by: Kanagaraj M <kmayilsa@redhat.com>
  • Loading branch information
Kanagaraj M committed Oct 16, 2014
1 parent 94be3dc commit 32062b3
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 16 deletions.
13 changes: 7 additions & 6 deletions manage/app/scripts/controllers/pool-modify.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
];
$scope.id = $routeParams.id;

// re-calculate the pgnum if the replication size changes
// only in new pool
// Refer PoolHelpers.addWatches()
$scope.isEdit = true;

// **cancel**
// Take us back to pool level.
$scope.cancel = function() {
Expand Down Expand Up @@ -121,11 +126,7 @@
return;
}
$log.error('Unexpected response from PoolService.patch', result);
}, ModalHelpers.makeOnError($modal({
show: false
}), function() {
$location.path('/pool');
}));
}, PoolHelpers.errorOnPoolSave($scope, $modal));
}
};

Expand All @@ -140,7 +141,7 @@

$scope.crushrulesets = PoolHelpers.normalizeCrushRulesets(this.crushrulesets);
$scope.up = true;
//helpers.addWatches($scope);
PoolHelpers.addWatches($scope);
}.bind(this));
};
return ['$log', '$q', '$scope', 'PoolService', 'ClusterService', 'CrushService', 'ToolService', '$location', '$routeParams', '$modal', 'RequestTrackingService', PoolModifyController];
Expand Down
9 changes: 6 additions & 3 deletions manage/app/scripts/controllers/pool-new.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
}
];

// re-calculate the pgnum if the replication size changes
// only in new pool
// Refer PoolHelpers.addWatches()
$scope.isEdit = false;

// **cancel**
// click event handler to return up a level.
$scope.cancel = function() {
Expand Down Expand Up @@ -74,9 +79,7 @@
return;
}
$log.error('Unexpected response from PoolService.create', resp);
}, ModalHelpers.makeOnError($modal({
show: false
})));
}, PoolHelpers.errorOnPoolSave($scope, $modal));
};

// Initialize Controller
Expand Down
56 changes: 49 additions & 7 deletions manage/app/scripts/helpers/pool-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@
return;
}
$scope.poolForm.name.$setValidity('duplicate', true);

//Clear the server error if user changes the name
$scope.poolForm.name.$setValidity('server', true);
});
/* jshint camelcase: false */
// Validate the pool size is a number and re-calculate the pgnum
Expand All @@ -164,13 +167,19 @@
$scope.poolForm.size.$error.number = true;
return;
}
var ruleset = $scope.crushrulesets[$scope.pool.crush_ruleset];
var limits = getActiveRule(ruleset, $scope.defaults.mon_max_pool_pg_num, newValue);
$scope.limits = limits;
if (validateMaxMin.call($scope.pool, 'size', newValue, limits.min_size, limits.max_size)) {
$scope.pool.pg_num = calculatePGNum(limits.osd_count, newValue, $scope.defaults.mon_max_pool_pg_num);
$scope.crushrulesets[$scope.pool.crush_ruleset].active_sub_rule = limits.active_rule;

if (!$scope.isEdit) {
var ruleset = $scope.crushrulesets[$scope.pool.crush_ruleset];
var limits = getActiveRule(ruleset, $scope.defaults.mon_max_pool_pg_num, newValue);
$scope.limits = limits;
if (validateMaxMin.call($scope.pool, 'size', newValue, limits.min_size, limits.max_size)) {
$scope.pool.pg_num = calculatePGNum(limits.osd_count, newValue, $scope.defaults.mon_max_pool_pg_num);
$scope.crushrulesets[$scope.pool.crush_ruleset].active_sub_rule = limits.active_rule;
}
}

//Clear the server error if user changes the name
$scope.poolForm.size.$setValidity('server', true);
});
// Validate the pg_num is a number and that it is within the
// min/max for this cluster.
Expand All @@ -182,13 +191,19 @@
$scope.poolForm.pg_num.$error.number = false;
$scope.poolForm.pg_num.$pristine = true;
validateMaxMin.call($scope.pool, 'pg_num', newValue, 1, $scope.defaults.mon_max_pool_pg_num);

//Clear the server error if user changes the name
$scope.poolForm.pg_num.$setValidity('server', true);
});
// If the crushset changes reset the pool size and the active crush rule sub rule
// value to default.
$scope.$watch('pool.crush_ruleset', function(newValue, oldValue) {
$scope.pool.size = $scope.defaults.size;
$scope.crushrulesets[newValue].active_sub_rule = 0;
$scope.crushrulesets[oldValue].active_sub_rule = 0;

//Clear the server error if user changes the name
$scope.poolForm.crush_ruleset.$setValidity('server', true);
});
}

Expand Down Expand Up @@ -216,6 +231,32 @@
});
}

// ** errorOnPoolSave **
// While creating/updating a pool, validation errors can be thrown from the server
// This will map the error to repective fields in the form
// If there is no field errors then an error popup will be shown
function errorOnPoolSave($scope, $model) {
return function(resp) {
var errorInField = false;
var fields = ['name', 'size', 'pg_num', 'crush_ruleset'];
_.each(fields, function(field) {
if (_.has(resp.data, field)) {
$scope.poolForm[field].$setValidity("server", false);
$scope.poolForm[field].$error.server = resp.data[field].join(', ');
errorInField = true;
}
});

// If the reponse doesn't have field specified error
// then show the response in a popup
if (!errorInField) {
ModalHelpers.makeOnError($modal({
show: false
}))();
}
}
}

// **poolDefaults**
// Default pool values.
function poolDefaults() {
Expand All @@ -236,7 +277,8 @@
makeReset: makeReset,
addWatches: addWatches,
defaults: poolDefaults,
normalizeCrushRulesets: normalizeCrushRulesets
normalizeCrushRulesets: normalizeCrushRulesets,
errorOnPoolSave: errorOnPoolSave
};
});
})();
4 changes: 4 additions & 0 deletions manage/app/views/pool-modify.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
class='help-block'>Name is too long (64 characters max)</p>
<p ng-show='poolForm.name.$error.pattern'
class='help-block'>Invalid Characters</p>
<p ng-show='poolForm.name.$error.server' class='help-block'>{{poolForm.name.$error.server}}</p>
</div>
<div class="form-group" ng-class="{ 'has-error': poolForm.size.$invalid && !poolForm.size.$pristine}">
<label class="text-muted" for="size">REPLICAS (SIZE)</label>
<input id="size" type="number" min="{{pool.min_size}}"
name="size" required class="form-control" placeholder="Size" ng-model='pool.size'></input>
<p ng-show='poolForm.size.$error.number' class='help-block'>Invalid Number</p>
<p ng-show='poolForm.size.$error.server' class='help-block'>{{poolForm.size.$error.server}}</p>
</div>
<div class="form-group" ng-class="{ 'has-error': poolForm.pg_num.$invalid && !poolForm.pg_num.$pristine}">
<label class="text-muted" for="pg_num">PLACEMENT GROUPS (PG_NUM)</label>
<input id="pg_num" type="number" name="pg_num"
required class="form-control" ng-model='pool.pg_num' placeholder="Placement Groups"></input>
<p ng-show='poolForm.pg_num.$error.number' class='help-block'>Invalid Number</p>
<p ng-show='poolForm.pg_num.$error.server' class='help-block'>{{poolForm.pg_num.$error.server}}</p>
</div>
<div class="form-group" ng-class="{ 'has-error': poolForm.crush_ruleset.$invalid && !poolForm.crush_ruleset.$pristine}">
<label class="text-muted" for="crush_ruleset">CRUSH RULESET</label>
Expand All @@ -34,6 +37,7 @@
<option ng-repeat='crush in crushrulesets' ng-selected="crush.id == pool.crush_ruleset"
value='{{crush.id}}'>{{crush.id}}: {{crush.rules[crush.active_sub_rule].name}}</option>
</select>
<p ng-show='poolForm.crush_ruleset.$error.server' class='help-block'>{{poolForm.crush_ruleset.$error.server}}</p>
</div>
</form>
</div>
Expand Down
4 changes: 4 additions & 0 deletions manage/app/views/pool-new.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,29 @@
<p ng-show='poolForm.name.$error.pattern'
class='help-block'>Invalid Characters</p>
<p ng-show='poolForm.name.$error.duplicate' class='help-block'>Pool name is already in use</p>
<p ng-show='poolForm.name.$error.server' class='help-block'>{{poolForm.name.$error.server}}</p>
</div>
<div class="form-group" ng-class="{ 'has-error': poolForm.size.$invalid && !poolForm.size.$pristine}">
<label class="text-muted" for="size">REPLICAS (SIZE)</label>
<input id="size" type="number" name="size" required class="form-control"
placeholder="Size" ng-model='pool.size'></input>
<p ng-show='poolForm.size.$error.number' class='help-block'>Invalid Number</p>
<p ng-show='poolForm.size.$error.server' class='help-block'>{{poolForm.size.$error.server}}</p>
</div>
<div class="form-group" ng-class="{ 'has-error': poolForm.pg_num.$invalid && !poolForm.pg_num.$pristine}">
<label class="text-muted" for="pg_num">PLACEMENT GROUPS (PG_NUM)</label>
<input id="pg_num" type="number" name="pg_num"
required class="form-control" ng-model='pool.pg_num' placeholder="Placement Groups"></input>
<p ng-show='poolForm.pg_num.$error.number' class='help-block'>Invalid Number</p>
<p ng-show='poolForm.pg_num.$error.server' class='help-block'>{{poolForm.pg_num.$error.server}}</p>
</div>
<div class="form-group" ng-class="{ 'has-error': poolForm.crush_ruleset.$invalid && !poolForm.crush_ruleset.$pristine}">
<label class="text-muted" for="crush_ruleset">CRUSH RULESET</label>
<select id="crush_ruleset" class="form-control" name="crush_ruleset"
required ng-model='pool.crush_ruleset'>
<option ng-repeat='crush in crushrulesets' value='{{crush.id}}'>{{crush.id}}: {{crush.rules[crush.active_sub_rule].name}}</option>
</select>
<p ng-show='poolForm.crush_ruleset.$error.server' class='help-block'>{{poolForm.crush_ruleset.$error.server}}</p>
</div>
<!-- {{ crushrulesets | json }} -->
</form>
Expand Down

0 comments on commit 32062b3

Please sign in to comment.