horizon/openstack_dashboard/static/app/core/images/steps/create-volume/create-volume.controller.js

235 lines
7.3 KiB
JavaScript

/**
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
angular
.module('horizon.app.core.images')
.constant('BYTE_TO_GIB', 9.3132e-10)
.controller('horizon.app.core.images.steps.CreateVolumeController', CreateVolumeController);
CreateVolumeController.$inject = [
'$scope',
'$filter',
'horizon.app.core.openstack-service-api.cinder',
'horizon.app.core.openstack-service-api.nova',
'horizon.framework.widgets.charts.quotaChartDefaults',
'horizon.app.core.images.validationRules',
'BYTE_TO_GIB'
];
/**
* @ngdoc controller
* @name horizon.app.core.images.steps.CreateVolumeController
* @param {Object} $scope
* @param {Object} $filter
* @param {Object} cinder
* @param {Object} nova
* @param {Object} quotaChartDefaults
* @param {Object} validationRules
* @description
* This controller is use for creating an image.
* @return {undefined} No return value
*/
function CreateVolumeController(
$scope,
$filter,
cinder,
nova,
quotaChartDefaults,
validationRules,
BYTE_TO_GIB
) {
var ctrl = this;
ctrl.volumeType = {};
ctrl.volumeTypes = [];
ctrl.availabilityZones = [];
ctrl.image = $scope.image;
ctrl.sourceImage = getSourceImage(ctrl.image);
ctrl.validationRules = validationRules;
ctrl.maxTotalVolumeGigabytes = 100;
ctrl.totalGigabytesUsed = 0;
ctrl.maxTotalVolumes = 1;
ctrl.totalVolumesUsed = 0;
var numberOfVolumesToAdd = 1;
// bind for local access and also hand back up to the wizard controller
// stepModels will be passed to the create volume action submit()
$scope.stepModels.volumeForm = ctrl.volume = {
size: Math.ceil(Math.max(ctrl.image.min_disk, ctrl.image.size * BYTE_TO_GIB)) || 1,
name: ctrl.image.name,
description: '',
volume_type: '',
availability_zone: '',
metadata: {},
image_id: ctrl.image.id,
snapshot_id: null,
source_volid: null
};
ctrl.storageQuota = {
title: gettext('Volume and Snapshot Quota (GiB)'),
maxLimit: ctrl.maxTotalVolumeGigabytes,
label: getPercentUsed(ctrl.volume.size, ctrl.maxTotalVolumeGigabytes),
data: [
{
label: quotaChartDefaults.usageLabel,
value: ctrl.totalGigabytesUsed,
colorClass: quotaChartDefaults.usageColorClass
},
{
label: quotaChartDefaults.addedLabel,
value: ctrl.volume.size,
colorClass: quotaChartDefaults.addedColorClass
},
{
label: quotaChartDefaults.remainingLabel,
value: ctrl.maxTotalVolumeGigabytes - ctrl.volume.size,
colorClass: quotaChartDefaults.remainingColorClass
}
]
};
ctrl.volumeQuota = {
title: gettext('Volume Quota'),
maxLimit: ctrl.maxTotalVolumes,
label: getPercentUsed(ctrl.totalVolumesUsed, ctrl.maxTotalVolumes),
data: [
{
label: quotaChartDefaults.usageLabel,
value: ctrl.totalVolumesUsed,
colorClass: quotaChartDefaults.usageColorClass
},
{
label: quotaChartDefaults.addedLabel,
value: numberOfVolumesToAdd,
colorClass: quotaChartDefaults.addedColorClass
},
{
label: quotaChartDefaults.remainingLabel,
value: ctrl.maxTotalVolumes - ctrl.totalVolumesUsed,
colorClass: quotaChartDefaults.remainingColorClass
}
]
};
var capacityWatcher = $scope.$watch(
function() {
return ctrl.volume.size;
},
updateStorageGraph
);
var volumeWatcher = $scope.$watch(
function() {
return ctrl.volume;
},
volumeChangeEvent,
true
);
$scope.$on('$destroy', deregisterWatchers);
init();
function init() {
cinder.getVolumeTypes().success(onGetVolumeTypes);
cinder.getAbsoluteLimits().success(onGetAbsoluteLimits);
cinder.getAvailabilityZones().success(onGetAvailabilityZones);
}
function onGetVolumeTypes(response) {
ctrl.volumeTypes = response.items;
cinder.getDefaultVolumeType().success(onGetDefaultVolumeType);
}
function onGetDefaultVolumeType(response) {
ctrl.volumeTypes.forEach(function(volumeType) {
if (volumeType.name === response.name) {
ctrl.volumeType = volumeType;
}
});
}
function onGetAvailabilityZones(response) {
ctrl.availabilityZones = response.items.map(justNames);
if (ctrl.availabilityZones.length > 0) {
ctrl.volume.availability_zone = ctrl.availabilityZones[0];
}
function justNames(item) {
return item.zoneName;
}
}
function onGetAbsoluteLimits(response) {
ctrl.maxTotalVolumeGigabytes = response.maxTotalVolumeGigabytes;
ctrl.totalGigabytesUsed = response.totalGigabytesUsed;
updateStorageGraph();
ctrl.totalVolumesUsed = response.totalVolumesUsed;
ctrl.maxTotalVolumes = response.maxTotalVolumes;
updateInstanceGraph();
}
function updateStorageGraph() {
if (ctrl.volume.size >= 0) {
var totalGigabytesAllocated = ctrl.volume.size + ctrl.totalGigabytesUsed;
ctrl.storageQuota.data[0].value = ctrl.totalGigabytesUsed;
ctrl.storageQuota.data[1].value = ctrl.volume.size;
ctrl.storageQuota.data[2].value =
Math.max(ctrl.maxTotalVolumeGigabytes - totalGigabytesAllocated, 0);
ctrl.storageQuota.label =
getPercentUsed(totalGigabytesAllocated,ctrl.maxTotalVolumeGigabytes);
ctrl.storageQuota.maxLimit = ctrl.maxTotalVolumeGigabytes;
ctrl.storageQuota.overMax = totalGigabytesAllocated > ctrl.storageQuota.maxLimit;
ctrl.storageQuota = angular.extend({}, ctrl.storageQuota);
$scope.volumeForm.$setValidity('volumeSize', !ctrl.storageQuota.overMax);
}
}
function updateInstanceGraph() {
ctrl.volumeQuota.data[0].value = ctrl.totalVolumesUsed;
ctrl.volumeQuota.data[2].value =
Math.max(ctrl.maxTotalVolumes - ctrl.totalVolumesUsed - numberOfVolumesToAdd, 0);
ctrl.volumeQuota.label = getPercentUsed(ctrl.totalVolumesUsed + numberOfVolumesToAdd,
ctrl.maxTotalVolumes);
ctrl.volumeQuota.maxLimit = ctrl.maxTotalVolumes;
ctrl.volumeQuota.overMax = ctrl.totalVolumesUsed === ctrl.volumeQuota.maxLimit;
ctrl.volumeQuota = angular.extend({}, ctrl.volumeQuota);
}
function getPercentUsed(used, total) {
return Math.round(used / total * 100) + '%';
}
function getSourceImage(image) {
return image.name + ' (' + $filter('bytes')(image.size) + ')';
}
function volumeChangeEvent() {
ctrl.volume.volume_type = ctrl.volumeType.name || '';
}
function deregisterWatchers() {
capacityWatcher();
volumeWatcher();
}
}
})();