Skip to content

Commit 2d9fec8

Browse files
author
OpenShift Bot
authored
Merge pull request #1134 from spadgett/pvc-limit-ranges
Merged by openshift-bot
2 parents 3c43069 + 70acb39 commit 2d9fec8

File tree

7 files changed

+183
-46
lines changed

7 files changed

+183
-46
lines changed

app/scripts/directives/oscPersistentVolumeClaim.js

+53-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@
22

33
angular.module("openshiftConsole")
44
.directive("oscPersistentVolumeClaim",
5-
function(DataService,
5+
function($filter,
6+
DataService,
7+
LimitRangesService,
68
ModalsService) {
79
return {
810
restrict: 'E',
911
scope: {
10-
claim: "=model"
12+
claim: "=model",
13+
projectName: "="
1114
},
1215
templateUrl: 'views/directives/osc-persistent-volume-claim.html',
1316
link: function(scope) {
17+
var amountAndUnit = $filter('amountAndUnit');
18+
var usageValue = $filter('usageValue');
19+
1420
scope.storageClasses = [];
1521
scope.claim.unit = 'Gi';
1622
scope.units = [{
@@ -53,9 +59,54 @@ angular.module("openshiftConsole")
5359
ModalsService.showComputeUnitsHelp();
5460
};
5561

62+
var validateLimitRange = function() {
63+
// Use usageValue filter to normalize units for comparison.
64+
var value = scope.claim.amount && usageValue(scope.claim.amount + scope.claim.unit);
65+
var min = _.has(scope, 'limits.min') && usageValue(scope.limits.min);
66+
var max = _.has(scope, 'limits.max') && usageValue(scope.limits.max);
67+
var minValid = true;
68+
var maxValid = true;
69+
70+
// Test against limit range min if defined.
71+
if (value && min) {
72+
minValid = value >= min;
73+
}
74+
75+
// Test against limit range max if defined.
76+
if (value && max) {
77+
maxValid = value <= max;
78+
}
79+
80+
scope.persistentVolumeClaimForm.capacity.$setValidity('limitRangeMin', minValid);
81+
scope.persistentVolumeClaimForm.capacity.$setValidity('limitRangeMax', maxValid);
82+
};
83+
5684
DataService.list({group: 'storage.k8s.io', resource: 'storageclasses'}, {}, function(storageClasses) {
5785
scope.storageClasses = storageClasses.by('metadata.name');
5886
}, {errorNotification: false});
87+
88+
DataService.list('limitranges', { namespace: scope.projectName }, function(limitRangeData) {
89+
var limitRanges = limitRangeData.by('metadata.name');
90+
if (_.isEmpty(limitRanges)) {
91+
return;
92+
}
93+
94+
scope.limits = LimitRangesService.getEffectiveLimitRange(limitRanges, 'storage', 'PersistentVolumeClaim');
95+
// If min === max, set the capacity to the required value and make the field readonly.
96+
var requiredAmountAndUnit;
97+
if (scope.limits.min && scope.limits.max) {
98+
var minUsage = usageValue(scope.limits.min);
99+
var maxUsage = usageValue(scope.limits.max);
100+
if (minUsage === maxUsage) {
101+
requiredAmountAndUnit = amountAndUnit(scope.limits.max);
102+
scope.claim.amount = Number(requiredAmountAndUnit[0]);
103+
scope.claim.unit = requiredAmountAndUnit[1];
104+
scope.capacityReadOnly = true;
105+
}
106+
}
107+
108+
scope.$watchGroup(['claim.amount', 'claim.unit'], validateLimitRange);
109+
});
59110
}
60111
};
61112
});

app/styles/_forms.less

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
.static-form-value-large {
2+
.h3();
3+
margin-top: 3px;
4+
}
5+
16
.copy-to-clipboard input.form-control:read-only {
27
background-color: white;
38
color: @text-color;

app/views/create-persistent-volume-claim.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ <h1>Create Storage</h1>
2121
</div>
2222
<form name="createPersistentVolumeClaimForm" class="mar-top-lg">
2323
<fieldset ng-disabled="disableInputs">
24-
<osc-persistent-volume-claim model="claim"></osc-persistent-volume-claim>
24+
<osc-persistent-volume-claim model="claim" project-name="projectName"></osc-persistent-volume-claim>
2525
<div class="button-group gutter-bottom">
2626
<button type="submit"
2727
class="btn btn-primary btn-lg"

app/views/directives/osc-persistent-volume-claim.html

+53-24
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
</div>
6868

6969
<div class="form-group" >
70-
<label class="required">Access Mode</label><br/>
70+
<label class="required">Access Mode</label>
7171
<div class="radio">
7272

7373
<label class="radio-inline">
@@ -92,21 +92,38 @@
9292
</div>
9393

9494
<!-- capacity -->
95-
<div class="form-group">
95+
<div ng-if="capacityReadOnly" class="form-group mar-bottom-xl">
96+
<label>Size</label>
97+
<div class="static-form-value-large">
98+
{{claim.amount}} {{claim.unit | humanizeUnit : 'storage'}}
99+
<small>(cannot be changed)</small>
100+
</div>
101+
</div>
102+
<div ng-if="!capacityReadOnly" class="form-group">
96103
<fieldset class="form-inline compute-resource">
97-
<label class="required">Size</label>
98-
<div class="resource-size">
99-
<div class="resource-amount" ng-class="{ 'has-error': persistentVolumeClaimForm.capacity.$invalid && persistentVolumeClaimForm.capacity.$touched && !claimDisabled }">
100-
<label class="sr-only">Amount</label>
104+
<label class="required">
105+
Size
106+
<small ng-if="limits.min && limits.max">
107+
{{limits.min | usageWithUnits : 'storage'}} min to {{limits.max | usageWithUnits : 'storage'}} max
108+
</small>
109+
<small ng-if="limits.min && !limits.max">
110+
Min: {{limits.min | usageWithUnits : 'storage'}}
111+
</small>
112+
<small ng-if="limits.max && !limits.min">
113+
Max: {{limits.max | usageWithUnits : 'storage'}}
114+
</small>
115+
</label>
116+
<div class="resource-size" ng-class="{ 'has-error': persistentVolumeClaimForm.capacity.$invalid && persistentVolumeClaimForm.capacity.$touched && !claimDisabled }">
117+
<div class="resource-amount">
118+
<label for="claim-amount" class="sr-only">Amount</label>
101119
<input type="number"
102120
name="capacity"
103-
ng-attr-id="claim-amount"
121+
id="claim-amount"
104122
ng-model="claim.amount"
105-
ng-required="true"
123+
required
106124
min="0"
107-
ng-attr-placeholder="10"
108125
class="form-control"
109-
ng-attr-aria-describedby="claim-capacity-help">
126+
aria-describedby="claim-capacity-help">
110127
</div>
111128
<div class="resource-unit">
112129
<label class="sr-only" >Unit</label>
@@ -120,20 +137,32 @@
120137
</div>
121138
<div id="claim-capacity-help" class="help-block">
122139
Desired storage capacity.
123-
</div>
124-
<div class="has-error" ng-show="persistentVolumeClaimForm.capacity.$error.number && persistentVolumeClaimForm.capacity.$touched && !claimDisabled">
125-
<span class="help-block">
126-
Must be a number.
127-
</span>
128-
</div>
129-
<div class="has-error" ng-show="persistentVolumeClaimForm.capacity.$error.min && persistentVolumeClaimForm.capacity.$touched && !claimDisabled">
130-
<span class="help-block">
131-
Must be a positive number.
132-
</span>
133-
</div>
134-
<div class="learn-more-block mar-top-sm">
135-
<a href="" ng-click="showComputeUnitsHelp()">What are GiB?</a>
136-
</div>
140+
</div>
141+
<div ng-if="persistentVolumeClaimForm.capacity.$touched && !claimDisabled">
142+
<div class="has-error" ng-show="persistentVolumeClaimForm.capacity.$error.number">
143+
<span class="help-block">
144+
Must be a number.
145+
</span>
146+
</div>
147+
<div class="has-error" ng-show="persistentVolumeClaimForm.capacity.$error.min">
148+
<span class="help-block">
149+
Must be a positive number.
150+
</span>
151+
</div>
152+
<div ng-if="persistentVolumeClaimForm.capacity.$error.limitRangeMin" class="has-error">
153+
<span class="help-block">
154+
Can't be less than {{limits.min | usageWithUnits : 'storage'}}.
155+
</span>
156+
</div>
157+
<div ng-if="persistentVolumeClaimForm.capacity.$error.limitRangeMax" class="has-error">
158+
<span class="help-block">
159+
Can't be greater than {{limits.max | usageWithUnits : 'storage'}}.
160+
</span>
161+
</div>
162+
</div>
163+
<div class="learn-more-block mar-top-sm">
164+
<a href="" ng-click="showComputeUnitsHelp()">What are GiB?</a>
165+
</div>
137166
</fieldset>
138167
</div>
139168
<!--advanced options-->

dist/scripts/scripts.js

+29-9
Original file line numberDiff line numberDiff line change
@@ -10063,15 +10063,17 @@ _.set(a, "model.service", c);
1006310063
});
1006410064
}
1006510065
};
10066-
}), angular.module("openshiftConsole").directive("oscPersistentVolumeClaim", [ "DataService", "ModalsService", function(a, b) {
10066+
}), angular.module("openshiftConsole").directive("oscPersistentVolumeClaim", [ "$filter", "DataService", "LimitRangesService", "ModalsService", function(a, b, c, d) {
1006710067
return {
1006810068
restrict:"E",
1006910069
scope:{
10070-
claim:"=model"
10070+
claim:"=model",
10071+
projectName:"="
1007110072
},
1007210073
templateUrl:"views/directives/osc-persistent-volume-claim.html",
10073-
link:function(c) {
10074-
c.storageClasses = [], c.claim.unit = "Gi", c.units = [ {
10074+
link:function(e) {
10075+
var f = a("amountAndUnit"), g = a("usageValue");
10076+
e.storageClasses = [], e.claim.unit = "Gi", e.units = [ {
1007510077
value:"Mi",
1007610078
label:"MiB"
1007710079
}, {
@@ -10089,7 +10091,7 @@ label:"GB"
1008910091
}, {
1009010092
value:"T",
1009110093
label:"TB"
10092-
} ], c.claim.selectedLabels = [], c.groupUnits = function(a) {
10094+
} ], e.claim.selectedLabels = [], e.groupUnits = function(a) {
1009310095
switch (a.value) {
1009410096
case "Mi":
1009510097
case "Gi":
@@ -10102,15 +10104,33 @@ case "T":
1010210104
return "Decimal Units";
1010310105
}
1010410106
return "";
10105-
}, c.showComputeUnitsHelp = function() {
10106-
b.showComputeUnitsHelp();
10107-
}, a.list({
10107+
}, e.showComputeUnitsHelp = function() {
10108+
d.showComputeUnitsHelp();
10109+
};
10110+
var h = function() {
10111+
var a = e.claim.amount && g(e.claim.amount + e.claim.unit), b = _.has(e, "limits.min") && g(e.limits.min), c = _.has(e, "limits.max") && g(e.limits.max), d = !0, f = !0;
10112+
a && b && (d = a >= b), a && c && (f = a <= c), e.persistentVolumeClaimForm.capacity.$setValidity("limitRangeMin", d), e.persistentVolumeClaimForm.capacity.$setValidity("limitRangeMax", f);
10113+
};
10114+
b.list({
1010810115
group:"storage.k8s.io",
1010910116
resource:"storageclasses"
1011010117
}, {}, function(a) {
10111-
c.storageClasses = a.by("metadata.name");
10118+
e.storageClasses = a.by("metadata.name");
1011210119
}, {
1011310120
errorNotification:!1
10121+
}), b.list("limitranges", {
10122+
namespace:e.projectName
10123+
}, function(a) {
10124+
var b = a.by("metadata.name");
10125+
if (!_.isEmpty(b)) {
10126+
e.limits = c.getEffectiveLimitRange(b, "storage", "PersistentVolumeClaim");
10127+
var d;
10128+
if (e.limits.min && e.limits.max) {
10129+
var i = g(e.limits.min), j = g(e.limits.max);
10130+
i === j && (d = f(e.limits.max), e.claim.amount = Number(d[0]), e.claim.unit = d[1], e.capacityReadOnly = !0);
10131+
}
10132+
e.$watchGroup([ "claim.amount", "claim.unit" ], h);
10133+
}
1011410134
});
1011510135
}
1011610136
};

dist/scripts/templates.js

+40-10
Original file line numberDiff line numberDiff line change
@@ -4531,7 +4531,7 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
45314531
"</div>\n" +
45324532
"<form name=\"createPersistentVolumeClaimForm\" class=\"mar-top-lg\">\n" +
45334533
"<fieldset ng-disabled=\"disableInputs\">\n" +
4534-
"<osc-persistent-volume-claim model=\"claim\"></osc-persistent-volume-claim>\n" +
4534+
"<osc-persistent-volume-claim model=\"claim\" project-name=\"projectName\"></osc-persistent-volume-claim>\n" +
45354535
"<div class=\"button-group gutter-bottom\">\n" +
45364536
"<button type=\"submit\" class=\"btn btn-primary btn-lg\" ng-click=\"createPersistentVolumeClaim()\" ng-disabled=\"createPersistentVolumeClaimForm.$invalid || disableInputs\" value=\"\">Create</button>\n" +
45374537
"<a class=\"btn btn-default btn-lg\" href=\"\" back>Cancel</a>\n" +
@@ -7547,7 +7547,7 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
75477547
"</div>\n" +
75487548
"</div>\n" +
75497549
"<div class=\"form-group\">\n" +
7550-
"<label class=\"required\">Access Mode</label><br/>\n" +
7550+
"<label class=\"required\">Access Mode</label>\n" +
75517551
"<div class=\"radio\">\n" +
75527552
"<label class=\"radio-inline\">\n" +
75537553
"<input type=\"radio\" name=\"accessModes\" ng-model=\"claim.accessModes\" value=\"ReadWriteOnce\" aria-describedby=\"access-modes-help\" ng-checked=\"true\">\n" +
@@ -7567,13 +7567,31 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
75677567
"</div>\n" +
75687568
"</div>\n" +
75697569
"\n" +
7570-
"<div class=\"form-group\">\n" +
7570+
"<div ng-if=\"capacityReadOnly\" class=\"form-group mar-bottom-xl\">\n" +
7571+
"<label>Size</label>\n" +
7572+
"<div class=\"static-form-value-large\">\n" +
7573+
"{{claim.amount}} {{claim.unit | humanizeUnit : 'storage'}}\n" +
7574+
"<small>(cannot be changed)</small>\n" +
7575+
"</div>\n" +
7576+
"</div>\n" +
7577+
"<div ng-if=\"!capacityReadOnly\" class=\"form-group\">\n" +
75717578
"<fieldset class=\"form-inline compute-resource\">\n" +
7572-
"<label class=\"required\">Size</label>\n" +
7573-
"<div class=\"resource-size\">\n" +
7574-
"<div class=\"resource-amount\" ng-class=\"{ 'has-error': persistentVolumeClaimForm.capacity.$invalid && persistentVolumeClaimForm.capacity.$touched && !claimDisabled }\">\n" +
7575-
"<label class=\"sr-only\">Amount</label>\n" +
7576-
"<input type=\"number\" name=\"capacity\" ng-attr-id=\"claim-amount\" ng-model=\"claim.amount\" ng-required=\"true\" min=\"0\" ng-attr-placeholder=\"10\" class=\"form-control\" ng-attr-aria-describedby=\"claim-capacity-help\">\n" +
7579+
"<label class=\"required\">\n" +
7580+
"Size\n" +
7581+
"<small ng-if=\"limits.min && limits.max\">\n" +
7582+
"{{limits.min | usageWithUnits : 'storage'}} min to {{limits.max | usageWithUnits : 'storage'}} max\n" +
7583+
"</small>\n" +
7584+
"<small ng-if=\"limits.min && !limits.max\">\n" +
7585+
"Min: {{limits.min | usageWithUnits : 'storage'}}\n" +
7586+
"</small>\n" +
7587+
"<small ng-if=\"limits.max && !limits.min\">\n" +
7588+
"Max: {{limits.max | usageWithUnits : 'storage'}}\n" +
7589+
"</small>\n" +
7590+
"</label>\n" +
7591+
"<div class=\"resource-size\" ng-class=\"{ 'has-error': persistentVolumeClaimForm.capacity.$invalid && persistentVolumeClaimForm.capacity.$touched && !claimDisabled }\">\n" +
7592+
"<div class=\"resource-amount\">\n" +
7593+
"<label for=\"claim-amount\" class=\"sr-only\">Amount</label>\n" +
7594+
"<input type=\"number\" name=\"capacity\" id=\"claim-amount\" ng-model=\"claim.amount\" required min=\"0\" class=\"form-control\" aria-describedby=\"claim-capacity-help\">\n" +
75777595
"</div>\n" +
75787596
"<div class=\"resource-unit\">\n" +
75797597
"<label class=\"sr-only\">Unit</label>\n" +
@@ -7588,16 +7606,28 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function(
75887606
"<div id=\"claim-capacity-help\" class=\"help-block\">\n" +
75897607
"Desired storage capacity.\n" +
75907608
"</div>\n" +
7591-
"<div class=\"has-error\" ng-show=\"persistentVolumeClaimForm.capacity.$error.number && persistentVolumeClaimForm.capacity.$touched && !claimDisabled\">\n" +
7609+
"<div ng-if=\"persistentVolumeClaimForm.capacity.$touched && !claimDisabled\">\n" +
7610+
"<div class=\"has-error\" ng-show=\"persistentVolumeClaimForm.capacity.$error.number\">\n" +
75927611
"<span class=\"help-block\">\n" +
75937612
"Must be a number.\n" +
75947613
"</span>\n" +
75957614
"</div>\n" +
7596-
"<div class=\"has-error\" ng-show=\"persistentVolumeClaimForm.capacity.$error.min && persistentVolumeClaimForm.capacity.$touched && !claimDisabled\">\n" +
7615+
"<div class=\"has-error\" ng-show=\"persistentVolumeClaimForm.capacity.$error.min\">\n" +
75977616
"<span class=\"help-block\">\n" +
75987617
"Must be a positive number.\n" +
75997618
"</span>\n" +
76007619
"</div>\n" +
7620+
"<div ng-if=\"persistentVolumeClaimForm.capacity.$error.limitRangeMin\" class=\"has-error\">\n" +
7621+
"<span class=\"help-block\">\n" +
7622+
"Can't be less than {{limits.min | usageWithUnits : 'storage'}}.\n" +
7623+
"</span>\n" +
7624+
"</div>\n" +
7625+
"<div ng-if=\"persistentVolumeClaimForm.capacity.$error.limitRangeMax\" class=\"has-error\">\n" +
7626+
"<span class=\"help-block\">\n" +
7627+
"Can't be greater than {{limits.max | usageWithUnits : 'storage'}}.\n" +
7628+
"</span>\n" +
7629+
"</div>\n" +
7630+
"</div>\n" +
76017631
"<div class=\"learn-more-block mar-top-sm\">\n" +
76027632
"<a href=\"\" ng-click=\"showComputeUnitsHelp()\">What are GiB?</a>\n" +
76037633
"</div>\n" +

dist/styles/main.css

+2
Original file line numberDiff line numberDiff line change
@@ -3581,6 +3581,8 @@ to{transform:rotate(359deg)}
35813581
.btn-flat-default:focus,.btn-flat-default:hover{background-color:#f7f7f7;border-color:#e7e7e7}
35823582
.btn-remove{color:#333;display:inline-block;font-size:15px;line-height:1;opacity:.65;padding:5px 7px;vertical-align:middle}
35833583
.btn-remove:focus,.btn-remove:hover{color:inherit;opacity:1;text-decoration:none}
3584+
.static-form-value-large{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;margin-bottom:10.5px;font-size:16px;margin-top:3px}
3585+
.static-form-value-large .small,.static-form-value-large small{font-weight:400;line-height:1;color:#9c9c9c;font-size:65%}
35843586
.copy-to-clipboard input.form-control:read-only{background-color:#fff;color:#363636}
35853587
.copy-to-clipboard-multiline{position:relative;width:100%}
35863588
.copy-to-clipboard-multiline a{box-shadow:none;position:absolute;right:0;top:0}

0 commit comments

Comments
 (0)