mirror of
https://github.com/portainer/portainer.git
synced 2025-08-08 23:35:31 +02:00
feat(storidge): introduce endpoint extensions and proxy Storidge API (#1661)
This commit is contained in:
parent
b5e256c967
commit
eb43579378
41 changed files with 571 additions and 372 deletions
10
app/portainer/rest/extension.js
Normal file
10
app/portainer/rest/extension.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
angular.module('portainer.app')
|
||||
.factory('Extensions', ['$resource', 'EndpointProvider', 'API_ENDPOINT_ENDPOINTS', function Extensions($resource, EndpointProvider, API_ENDPOINT_ENDPOINTS) {
|
||||
'use strict';
|
||||
return $resource(API_ENDPOINT_ENDPOINTS + '/:endpointId/extensions', {
|
||||
endpointId: EndpointProvider.endpointID
|
||||
},
|
||||
{
|
||||
register: { method: 'POST', params: { endpointId: '@endpointId' } }
|
||||
});
|
||||
}]);
|
|
@ -66,6 +66,7 @@ angular.module('portainer.app')
|
|||
TLSSkipVerify: TLSSkipVerify,
|
||||
TLSSkipClientVerify: TLSSkipClientVerify
|
||||
};
|
||||
|
||||
var deferred = $q.defer();
|
||||
Endpoints.create({}, endpoint).$promise
|
||||
.then(function success(data) {
|
||||
|
@ -85,6 +86,7 @@ angular.module('portainer.app')
|
|||
deferred.notify({upload: false});
|
||||
deferred.reject({msg: 'Unable to upload TLS certs', err: err});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
|
17
app/portainer/services/api/extensionService.js
Normal file
17
app/portainer/services/api/extensionService.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
angular.module('portainer.app')
|
||||
.factory('ExtensionService', ['Extensions', function ExtensionServiceFactory(Extensions) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.registerStoridgeExtension = function(endpointId, url) {
|
||||
var payload = {
|
||||
endpointId: endpointId,
|
||||
Type: 1,
|
||||
URL: url
|
||||
};
|
||||
|
||||
return Extensions.register(payload).$promise;
|
||||
};
|
||||
|
||||
return service;
|
||||
}]);
|
|
@ -1,35 +1,71 @@
|
|||
angular.module('portainer.app')
|
||||
.factory('ExtensionManager', ['$q', 'PluginService', 'StoridgeManager', function ExtensionManagerFactory($q, PluginService, StoridgeManager) {
|
||||
.factory('ExtensionManager', ['$q', 'PluginService', 'SystemService', 'ExtensionService',
|
||||
function ExtensionManagerFactory($q, PluginService, SystemService, ExtensionService) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.init = function() {
|
||||
return $q.all(
|
||||
StoridgeManager.init()
|
||||
);
|
||||
};
|
||||
|
||||
service.reset = function() {
|
||||
StoridgeManager.reset();
|
||||
};
|
||||
|
||||
service.extensions = function() {
|
||||
service.initEndpointExtensions = function(endpointId) {
|
||||
var deferred = $q.defer();
|
||||
var extensions = [];
|
||||
|
||||
PluginService.volumePlugins()
|
||||
SystemService.version()
|
||||
.then(function success(data) {
|
||||
var volumePlugins = data;
|
||||
if (_.includes(volumePlugins, 'cio:latest')) {
|
||||
extensions.push('storidge');
|
||||
}
|
||||
var endpointAPIVersion = parseFloat(data.ApiVersion);
|
||||
|
||||
return $q.all([
|
||||
endpointAPIVersion >= 1.25 ? initStoridgeExtension(endpointId): null
|
||||
]);
|
||||
})
|
||||
.finally(function final() {
|
||||
.then(function success(data) {
|
||||
var extensions = data.filter(function filterNull(x) {
|
||||
return x;
|
||||
});
|
||||
deferred.resolve(extensions);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to connect to the Docker environment', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
function initStoridgeExtension(endpointId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
PluginService.volumePlugins()
|
||||
.then(function success(data) {
|
||||
var volumePlugins = data;
|
||||
if (_.includes(volumePlugins, 'cio:latest')) {
|
||||
return registerStoridgeUsingSwarmManagerIP(endpointId);
|
||||
}
|
||||
})
|
||||
.then(function success(data) {
|
||||
deferred.resolve(data);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'An error occured during Storidge extension check', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function registerStoridgeUsingSwarmManagerIP(endpointId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
SystemService.info()
|
||||
.then(function success(data) {
|
||||
var managerIP = data.Swarm.NodeAddr;
|
||||
var storidgeAPIURL = 'tcp://' + managerIP + ':8282';
|
||||
return ExtensionService.registerStoridgeExtension(endpointId, storidgeAPIURL);
|
||||
})
|
||||
.then(function success(data) {
|
||||
deferred.resolve(data);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'An error occured during Storidge extension initialization', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
return service;
|
||||
}]);
|
||||
|
|
|
@ -41,15 +41,6 @@ angular.module('portainer.app')
|
|||
getPaginationLimit: function(key) {
|
||||
return localStorageService.cookie.get('pagination_' + key);
|
||||
},
|
||||
storeStoridgeAPIURL: function(url) {
|
||||
localStorageService.set('STORIDGE_API_URL', url);
|
||||
},
|
||||
getStoridgeAPIURL: function() {
|
||||
return localStorageService.get('STORIDGE_API_URL');
|
||||
},
|
||||
clearStoridgeAPIURL: function() {
|
||||
return localStorageService.remove('STORIDGE_API_URL');
|
||||
},
|
||||
getDataTableOrder: function(key) {
|
||||
return localStorageService.get('datatable_order_' + key);
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
angular.module('portainer.app')
|
||||
.factory('StateManager', ['$q', 'SystemService', 'InfoHelper', 'LocalStorage', 'SettingsService', 'StatusService', 'ExtensionManager', 'APPLICATION_CACHE_VALIDITY', function StateManagerFactory($q, SystemService, InfoHelper, LocalStorage, SettingsService, StatusService, ExtensionManager, APPLICATION_CACHE_VALIDITY) {
|
||||
.factory('StateManager', ['$q', 'SystemService', 'InfoHelper', 'LocalStorage', 'SettingsService', 'StatusService', 'APPLICATION_CACHE_VALIDITY',
|
||||
function StateManagerFactory($q, SystemService, InfoHelper, LocalStorage, SettingsService, StatusService, APPLICATION_CACHE_VALIDITY) {
|
||||
'use strict';
|
||||
|
||||
var manager = {};
|
||||
|
@ -107,8 +108,24 @@ angular.module('portainer.app')
|
|||
return deferred.promise;
|
||||
};
|
||||
|
||||
manager.updateEndpointState = function(loading) {
|
||||
|
||||
function assignExtensions(endpointExtensions) {
|
||||
console.log(JSON.stringify(endpointExtensions, null, 4));
|
||||
var extensions = [];
|
||||
|
||||
for (var i = 0; i < endpointExtensions.length; i++) {
|
||||
var extension = endpointExtensions[i];
|
||||
if (extension.Type === 1) {
|
||||
extensions.push('storidge');
|
||||
}
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
manager.updateEndpointState = function(loading, extensions) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (loading) {
|
||||
state.loading = true;
|
||||
}
|
||||
|
@ -121,10 +138,7 @@ angular.module('portainer.app')
|
|||
var endpointAPIVersion = parseFloat(data.version.ApiVersion);
|
||||
state.endpoint.mode = endpointMode;
|
||||
state.endpoint.apiVersion = endpointAPIVersion;
|
||||
return $q.when(endpointAPIVersion < 1.25 || ExtensionManager.extensions());
|
||||
})
|
||||
.then(function success(data) {
|
||||
state.endpoint.extensions = data instanceof Array ? data : [];
|
||||
state.endpoint.extensions = assignExtensions(extensions);
|
||||
LocalStorage.storeEndpointState(state.endpoint);
|
||||
deferred.resolve();
|
||||
})
|
||||
|
|
|
@ -18,7 +18,7 @@ function ($scope, $state, $transition$, $window, $timeout, $sanitize, Authentica
|
|||
if (!endpointID) {
|
||||
EndpointProvider.setEndpointID(endpoint.Id);
|
||||
}
|
||||
StateManager.updateEndpointState(true)
|
||||
StateManager.updateEndpointState(true, endpoint.Extensions)
|
||||
.then(function success(data) {
|
||||
$state.go('docker.dashboard');
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
angular.module('portainer.app')
|
||||
.controller('EndpointsController', ['$scope', '$state', '$filter', 'EndpointService', 'Notifications',
|
||||
function ($scope, $state, $filter, EndpointService, Notifications) {
|
||||
.controller('EndpointsController', ['$scope', '$state', '$filter', 'EndpointService', 'Notifications', 'ExtensionManager', 'EndpointProvider',
|
||||
function ($scope, $state, $filter, EndpointService, Notifications, ExtensionManager, EndpointProvider) {
|
||||
$scope.state = {
|
||||
uploadInProgress: false,
|
||||
actionInProgress: false
|
||||
|
@ -31,9 +31,22 @@ function ($scope, $state, $filter, EndpointService, Notifications) {
|
|||
var TLSKeyFile = TLSSkipClientVerify ? null : securityData.TLSKey;
|
||||
|
||||
$scope.state.actionInProgress = true;
|
||||
EndpointService.createRemoteEndpoint(name, URL, PublicURL, TLS, TLSSkipVerify, TLSSkipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile).then(function success(data) {
|
||||
Notifications.success('Endpoint created', name);
|
||||
$state.reload();
|
||||
EndpointService.createRemoteEndpoint(name, URL, PublicURL, TLS, TLSSkipVerify, TLSSkipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile)
|
||||
.then(function success(data) {
|
||||
var currentEndpointId = EndpointProvider.endpointID();
|
||||
EndpointProvider.setEndpointID(data.Id);
|
||||
ExtensionManager.initEndpointExtensions(data.Id)
|
||||
.then(function success(data) {
|
||||
Notifications.success('Endpoint created', name);
|
||||
$state.reload();
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to create endpoint');
|
||||
})
|
||||
.finally(function final() {
|
||||
$scope.state.actionInProgress = false;
|
||||
EndpointProvider.setEndpointID(currentEndpointId);
|
||||
});
|
||||
}, function error(err) {
|
||||
$scope.state.uploadInProgress = false;
|
||||
$scope.state.actionInProgress = false;
|
||||
|
|
|
@ -30,9 +30,9 @@ function ($scope, $state, $sanitize, Notifications, Authentication, StateManager
|
|||
if (data.length === 0) {
|
||||
$state.go('portainer.init.endpoint');
|
||||
} else {
|
||||
var endpointID = data[0].Id;
|
||||
EndpointProvider.setEndpointID(endpointID);
|
||||
StateManager.updateEndpointState(false)
|
||||
var endpoint = data[0];
|
||||
EndpointProvider.setEndpointID(endpoint.Id);
|
||||
StateManager.updateEndpointState(false, endpoint.Extensions)
|
||||
.then(function success() {
|
||||
$state.go('docker.dashboard');
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
angular.module('portainer.app')
|
||||
.controller('InitEndpointController', ['$scope', '$state', 'EndpointService', 'StateManager', 'EndpointProvider', 'Notifications',
|
||||
function ($scope, $state, EndpointService, StateManager, EndpointProvider, Notifications) {
|
||||
.controller('InitEndpointController', ['$scope', '$state', 'EndpointService', 'StateManager', 'EndpointProvider', 'Notifications', 'ExtensionManager',
|
||||
function ($scope, $state, EndpointService, StateManager, EndpointProvider, Notifications, ExtensionManager) {
|
||||
|
||||
if (!_.isEmpty($scope.applicationState.endpoint)) {
|
||||
$state.go('docker.dashboard');
|
||||
|
@ -35,7 +35,11 @@ function ($scope, $state, EndpointService, StateManager, EndpointProvider, Notif
|
|||
.then(function success(data) {
|
||||
endpointID = data.Id;
|
||||
EndpointProvider.setEndpointID(endpointID);
|
||||
return StateManager.updateEndpointState(false);
|
||||
return ExtensionManager.initEndpointExtensions(endpointID);
|
||||
})
|
||||
.then(function success(data) {
|
||||
var extensions = data;
|
||||
return StateManager.updateEndpointState(false, extensions);
|
||||
})
|
||||
.then(function success(data) {
|
||||
$state.go('docker.dashboard');
|
||||
|
@ -66,7 +70,11 @@ function ($scope, $state, EndpointService, StateManager, EndpointProvider, Notif
|
|||
.then(function success(data) {
|
||||
endpointID = data.Id;
|
||||
EndpointProvider.setEndpointID(endpointID);
|
||||
return StateManager.updateEndpointState(false);
|
||||
return ExtensionManager.initEndpointExtensions(endpointID);
|
||||
})
|
||||
.then(function success(data) {
|
||||
var extensions = data;
|
||||
return StateManager.updateEndpointState(false, extensions);
|
||||
})
|
||||
.then(function success(data) {
|
||||
$state.go('docker.dashboard');
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
sidebar-toggled-on="toggle"
|
||||
current-state="$state.current.name"
|
||||
></docker-sidebar-content>
|
||||
<li class="sidebar-title" ng-if="applicationState.endpoint.extensions.length > 0 && isAdmin && applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE' && applicationState.endpoint.mode.role === 'MANAGER'">
|
||||
<li class="sidebar-title" ng-if="applicationState.endpoint.extensions.length > 0">
|
||||
<span>Extensions</span>
|
||||
</li>
|
||||
<li class="sidebar-list" ng-if="applicationState.endpoint.extensions.indexOf('storidge') !== -1 && applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE' && applicationState.endpoint.mode.role === 'MANAGER'">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
angular.module('portainer.app')
|
||||
.controller('SidebarController', ['$q', '$scope', '$state', 'Settings', 'EndpointService', 'StateManager', 'EndpointProvider', 'Notifications', 'Authentication', 'UserService', 'ExtensionManager',
|
||||
function ($q, $scope, $state, Settings, EndpointService, StateManager, EndpointProvider, Notifications, Authentication, UserService, ExtensionManager) {
|
||||
.controller('SidebarController', ['$q', '$scope', '$state', 'Settings', 'EndpointService', 'StateManager', 'EndpointProvider', 'Notifications', 'Authentication', 'UserService',
|
||||
function ($q, $scope, $state, Settings, EndpointService, StateManager, EndpointProvider, Notifications, Authentication, UserService) {
|
||||
|
||||
$scope.switchEndpoint = function(endpoint) {
|
||||
var activeEndpointID = EndpointProvider.endpointID();
|
||||
|
@ -8,9 +8,8 @@ function ($q, $scope, $state, Settings, EndpointService, StateManager, EndpointP
|
|||
EndpointProvider.setEndpointID(endpoint.Id);
|
||||
EndpointProvider.setEndpointPublicURL(endpoint.PublicURL);
|
||||
|
||||
StateManager.updateEndpointState(true)
|
||||
StateManager.updateEndpointState(true, endpoint.Extensions)
|
||||
.then(function success() {
|
||||
ExtensionManager.reset();
|
||||
$state.go('docker.dashboard');
|
||||
})
|
||||
.catch(function error(err) {
|
||||
|
@ -47,7 +46,7 @@ function ($q, $scope, $state, Settings, EndpointService, StateManager, EndpointP
|
|||
$scope.displayExternalContributors = StateManager.getState().application.displayExternalContributors;
|
||||
$scope.logo = StateManager.getState().application.logo;
|
||||
$scope.endpoints = [];
|
||||
|
||||
|
||||
EndpointService.endpoints()
|
||||
.then(function success(data) {
|
||||
var endpoints = data;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue