1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

feat(integrations): storidge evolution (#2711)

* feat(storidge): update storidge routes

* feat(storidge): add new fields on profile create/edit

* feat(storidge): add drives list and details view

* feat(storidge): add node details / cordon / uncordon / remove

* feat(storidge): add volume and snapshot details

* feat(storidge): add snapshot creation on volume details

* feat(storidge): add rescan drives button

* refactor(storidge): move add / remove / put in / put ouf maintenance buttons for cluster nodes

* style(storidge): change cluster / node icon color based on status

* feat(storidge): profiles can enable snapshots without interval + interval in minutes

* refactor(storidge): split cluster and node status badge filter

* fix(storidge): error on volume IOPS update

* fix(storidge): snapshot can now be created without comments

* feat(storidge): remove snapshots panels when volume snapshots are disabled

* fix(app): paginatedItemLimit now retrieved for datables extending GenericDatatableController

* fix(storidge): addDrive is called with the good parameters

* fix(storidge): update model and views for Storidge v2695

* refactor(storidge): webpack migration

* fix(storidge): display modifications + fix js errors

* feat(storidge): snapshots, profile and nodes evolution

* fix(storidge): values for InterfaceDriver on profile create/edit

* feat(storidge): v5 update without style (profile / statuses / volume)

* fix(storidge): description tables on the same view have now the same fixed offset

* fix(app): override rdash-ui select style

* Revert "fix(app): override rdash-ui select style"

This reverts commit e724833261.

* feat(storidge): wip on update 6

* feat(storidge): update 6

* feat(storidge): update 6

* feat(storidge): update 6

* feat(storidge): update 7 - node details + cluster views

* fix(storidge): update 7 - profiles creation + volume details

* fix(storidge): update 7 - profile create/edit interface type

* feat(storidge): update 8 - add drive

* feat(storidge): update 8 - UI refactors + cluster availability

* fix(storidge): update 8 - revert cluster availability

* feat(storidge): update 8 - node availability on swarm overview

* feat(storidge): cluster condition badge

* fix(storidge): update 9 - move add storage button + api profile filesystem kv to obj

* feat(storidge): update 9 - disable add drive button when action is in progress

* fix(storidge): update 9 - add drive button will now change only for the concerned drive

* fix(storidge): update 10 - disable remove drive button when removal in progress

* fix(api): update Storidge proxy creation process

* refactor(api): update version number

* feat(extensions): fix an issue with Storidge API URL

* feat(storidge): force the use of a manager node
This commit is contained in:
baron_l 2019-05-24 23:53:10 +02:00 committed by Anthony Lapenna
parent 17765d992e
commit 851607394c
61 changed files with 2338 additions and 146 deletions

View file

@ -63,6 +63,13 @@
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Status' && $ctrl.state.reverseOrder"></i>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('Availability')">
Availability
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Availability' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Availability' && $ctrl.state.reverseOrder"></i>
</a>
</th>
</tr>
</thead>
<tbody>
@ -77,6 +84,7 @@
<td>{{ item.EngineVersion }}</td>
<td ng-if="$ctrl.showIpAddressColumn">{{ item.Addr }}</td>
<td><span class="label label-{{ item.Status | nodestatusbadge }}">{{ item.Status }}</span></td>
<td><span class="label label-{{ item.Availability | dockerNodeAvailabilityBadge }}">{{ item.Availability }}</span></td>
</tr>
<tr ng-if="!$ctrl.dataset">
<td colspan="7" class="text-center text-muted">Loading...</td>

View file

@ -97,6 +97,18 @@ angular.module('portainer.docker')
return 'success';
};
})
.filter('dockerNodeAvailabilityBadge', function () {
'use strict';
return function (text) {
if (text === 'pause') {
return 'warning';
}
else if (text === 'drain') {
return 'danger';
}
return 'success';
};
})
.filter('trimcontainername', function () {
'use strict';
return function (name) {

View file

@ -9,6 +9,7 @@ angular.module('portainer.docker').factory('NodeService', [
service.nodes = nodes;
service.node = node;
service.updateNode = updateNode;
service.getActiveManager = getActiveManager;
function node(id) {
var deferred = $q.defer();
@ -45,6 +46,26 @@ angular.module('portainer.docker').factory('NodeService', [
return Node.update({ id: node.Id, version: node.Version }, node).$promise;
}
function getActiveManager() {
var deferred = $q.defer();
service.nodes()
.then(function success(data) {
for (var i = 0; i < data.length; ++i) {
var node = data[i];
if (node.Role === 'manager' && node.Availability === 'active' && node.Status === 'ready' && node.Addr !== '0.0.0.0') {
deferred.resolve(node);
break;
}
}
})
.catch(function error(err) {
deferred.reject({ msg: 'Unable to retrieve nodes', err: err });
});
return deferred.promise;
}
return service;
}
]);

View file

@ -49,6 +49,31 @@
</div>
</div>
<div class="row" ng-if="isCioDriver">
<div class="col-sm-12">
<volume-storidge-info volume="storidgeVolume">
</volume-storidge-info>
</div>
</div>
<div class="row" ng-if="isCioDriver">
<div class="col-sm-12">
<storidge-snapshot-creation volume-id="storidgeVolume.Vdisk" ng-if="storidgeVolume.SnapshotEnabled">
</storidge-snapshot-creation>
</div>
</div>
<div class="row" ng-if="isCioDriver && storidgeVolume.SnapshotEnabled">
<div class="col-sm-12">
<storidge-snapshots-datatable
title-text="Snapshots" title-icon="fa-camera"
dataset="storidgeSnapshots" table-key="storidgeSnapshots"
order-by="Id"
remove-action="removeSnapshot">
</storidge-snapshots-datatable>
</div>
</div>
<!-- access-control-panel -->
<por-access-control-panel
ng-if="volume && applicationState.application.authentication"

View file

@ -1,6 +1,43 @@
angular.module('portainer.docker')
.controller('VolumeController', ['$scope', '$state', '$transition$', 'VolumeService', 'ContainerService', 'Notifications', 'HttpRequestHelper',
function ($scope, $state, $transition$, VolumeService, ContainerService, Notifications, HttpRequestHelper) {
.controller('VolumeController', ['$scope', '$state', '$transition$', '$q', 'ModalService', 'VolumeService', 'ContainerService', 'Notifications', 'HttpRequestHelper', 'StoridgeVolumeService', 'StoridgeSnapshotService',
function ($scope, $state, $transition$, $q, ModalService, VolumeService, ContainerService, Notifications, HttpRequestHelper, StoridgeVolumeService, StoridgeSnapshotService) {
$scope.storidgeSnapshots = [];
$scope.storidgeVolume = {};
$scope.removeSnapshot = function (selectedItems) {
ModalService.confirm({
title: 'Are you sure?',
message: 'Do you want really want to remove this snapshot?',
buttons: {
confirm: {
label: 'Remove',
className: 'btn-danger'
}
},
callback: function onConfirm(confirmed) {
if(!confirmed) { return; }
var actionCount = selectedItems.length;
angular.forEach(selectedItems, function (item) {
StoridgeSnapshotService.remove(item.Id)
.then(function success() {
Notifications.success('Snapshot successfully removed', item.Id);
var index = $scope.storidgeSnapshots.indexOf(item);
$scope.storidgeSnapshots.splice(index, 1);
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to remove snapshot');
})
.finally(function final() {
--actionCount;
if (actionCount === 0) {
$state.reload();
}
});
});
}
});
};
$scope.removeVolume = function removeVolume() {
VolumeService.remove($scope.volume)
@ -21,19 +58,41 @@ function ($scope, $state, $transition$, VolumeService, ContainerService, Notific
function initView() {
HttpRequestHelper.setPortainerAgentTargetHeader($transition$.params().nodeName);
VolumeService.volume($transition$.params().id)
.then(function success(data) {
var volume = data;
$scope.volume = volume;
var containerFilter = { volume: [volume.Id] };
return ContainerService.containers(1, containerFilter);
$scope.isCioDriver = volume.Driver.includes('cio');
if ($scope.isCioDriver) {
return $q.all({
containers: ContainerService.containers(1, containerFilter),
storidgeVolume: StoridgeVolumeService.volume($transition$.params().id)
});
} else {
return ContainerService.containers(1, containerFilter);
}
})
.then(function success(data) {
var containers = data.map(function(container) {
var dataContainers = $scope.isCioDriver ? data.containers : data;
var containers = dataContainers.map(function(container) {
container.volumeData = getVolumeDataFromContainer(container, $scope.volume.Id);
return container;
});
$scope.containersUsingVolume = containers;
if ($scope.isCioDriver) {
$scope.storidgeVolume = data.storidgeVolume;
if ($scope.storidgeVolume.SnapshotEnabled) {
return StoridgeSnapshotService.snapshots(data.storidgeVolume.Vdisk);
}
}
})
.then(function success(data) {
$scope.storidgeSnapshots = data;
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve volume details');