From 7c6c9284f27e867cf5ab11ce1a54895fd419858a Mon Sep 17 00:00:00 2001 From: Thomas Krzero Date: Mon, 1 May 2017 12:19:43 +0200 Subject: [PATCH] feat(endpoints) - Access exposed containers on endpoint public URL (#826) --- api/http/endpoint_handler.go | 19 +++++++++++++------ api/portainer.go | 1 + app/components/containers/containers.html | 2 +- .../containers/containersController.js | 5 +++-- app/components/endpoint/endpoint.html | 11 +++++++++++ app/components/endpoint/endpointController.js | 1 + .../endpointInit/endpointInitController.js | 3 ++- app/components/endpoints/endpoints.html | 11 +++++++++++ .../endpoints/endpointsController.js | 7 ++++++- app/components/sidebar/sidebarController.js | 4 ++++ app/services/endpointProvider.js | 11 +++++++++++ app/services/endpointService.js | 4 +++- app/services/localStorage.js | 6 ++++++ 13 files changed, 73 insertions(+), 12 deletions(-) diff --git a/api/http/endpoint_handler.go b/api/http/endpoint_handler.go index 162ceaa76..d72c017e3 100644 --- a/api/http/endpoint_handler.go +++ b/api/http/endpoint_handler.go @@ -108,6 +108,7 @@ func (handler *EndpointHandler) handlePostEndpoints(w http.ResponseWriter, r *ht endpoint := &portainer.Endpoint{ Name: req.Name, URL: req.URL, + PublicURL: req.PublicURL, TLS: req.TLS, AuthorizedUsers: []portainer.UserID{}, } @@ -136,9 +137,10 @@ func (handler *EndpointHandler) handlePostEndpoints(w http.ResponseWriter, r *ht } type postEndpointsRequest struct { - Name string `valid:"required"` - URL string `valid:"required"` - TLS bool + Name string `valid:"required"` + URL string `valid:"required"` + PublicURL string `valid:"-"` + TLS bool } type postEndpointsResponse struct { @@ -262,6 +264,10 @@ func (handler *EndpointHandler) handlePutEndpoint(w http.ResponseWriter, r *http endpoint.URL = req.URL } + if req.PublicURL != "" { + endpoint.PublicURL = req.PublicURL + } + if req.TLS { endpoint.TLS = true caCertPath, _ := handler.FileService.GetPathForTLSFile(endpoint.ID, portainer.TLSFileCA) @@ -296,9 +302,10 @@ func (handler *EndpointHandler) handlePutEndpoint(w http.ResponseWriter, r *http } type putEndpointsRequest struct { - Name string `valid:"-"` - URL string `valid:"-"` - TLS bool `valid:"-"` + Name string `valid:"-"` + URL string `valid:"-"` + PublicURL string `valid:"-"` + TLS bool `valid:"-"` } // handleDeleteEndpoint handles DELETE requests on /endpoints/:id diff --git a/api/portainer.go b/api/portainer.go index 6b742246f..5d6bb280f 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -72,6 +72,7 @@ type ( ID EndpointID `json:"Id"` Name string `json:"Name"` URL string `json:"URL"` + PublicURL string `json:"PublicURL"` TLS bool `json:"TLS"` TLSCACertPath string `json:"TLSCACert,omitempty"` TLSCertPath string `json:"TLSCert,omitempty"` diff --git a/app/components/containers/containers.html b/app/components/containers/containers.html index 5153577ec..2f85dd83e 100644 --- a/app/components/containers/containers.html +++ b/app/components/containers/containers.html @@ -112,7 +112,7 @@ {{ container.IP ? container.IP : '-' }} {{ container.hostIP }} - + {{p.public}}:{{ p.private }} - diff --git a/app/components/containers/containersController.js b/app/components/containers/containersController.js index 25eb90d25..3d11631f2 100644 --- a/app/components/containers/containersController.js +++ b/app/components/containers/containersController.js @@ -1,6 +1,6 @@ angular.module('containers', []) - .controller('ContainersController', ['$q', '$scope', '$filter', 'Container', 'ContainerHelper', 'Info', 'Settings', 'Notifications', 'Config', 'Pagination', 'EntityListService', 'ModalService', 'Authentication', 'ResourceControlService', 'UserService', - function ($q, $scope, $filter, Container, ContainerHelper, Info, Settings, Notifications, Config, Pagination, EntityListService, ModalService, Authentication, ResourceControlService, UserService) { + .controller('ContainersController', ['$q', '$scope', '$filter', 'Container', 'ContainerHelper', 'Info', 'Settings', 'Notifications', 'Config', 'Pagination', 'EntityListService', 'ModalService', 'Authentication', 'ResourceControlService', 'UserService', 'EndpointProvider', + function ($q, $scope, $filter, Container, ContainerHelper, Info, Settings, Notifications, Config, Pagination, EntityListService, ModalService, Authentication, ResourceControlService, UserService, EndpointProvider) { $scope.state = {}; $scope.state.pagination_count = Pagination.getPaginationCount('containers'); $scope.state.displayAll = Settings.displayAll; @@ -12,6 +12,7 @@ angular.module('containers', []) $scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false; $scope.sortType = sortType; }; + $scope.PublicURL = EndpointProvider.endpointPublicURL(); $scope.changePaginationCount = function() { Pagination.setPaginationCount('containers', $scope.state.pagination_count); diff --git a/app/components/endpoint/endpoint.html b/app/components/endpoint/endpoint.html index d1c355961..b5d95a714 100644 --- a/app/components/endpoint/endpoint.html +++ b/app/components/endpoint/endpoint.html @@ -31,6 +31,17 @@ + +
+ +
+ +
+
+
diff --git a/app/components/endpoint/endpointController.js b/app/components/endpoint/endpointController.js index 43a013834..4ef7c0aba 100644 --- a/app/components/endpoint/endpointController.js +++ b/app/components/endpoint/endpointController.js @@ -22,6 +22,7 @@ function ($scope, $state, $stateParams, $filter, EndpointService, Notifications) var endpointParams = { name: $scope.endpoint.Name, URL: $scope.endpoint.URL, + PublicURL: $scope.endpoint.PublicURL, TLS: $scope.endpoint.TLS, TLSCACert: $scope.formValues.TLSCACert !== $scope.endpoint.TLSCACert ? $scope.formValues.TLSCACert : null, TLSCert: $scope.formValues.TLSCert !== $scope.endpoint.TLSCert ? $scope.formValues.TLSCert : null, diff --git a/app/components/endpointInit/endpointInitController.js b/app/components/endpointInit/endpointInitController.js index e2fc30725..7977de3ee 100644 --- a/app/components/endpointInit/endpointInitController.js +++ b/app/components/endpointInit/endpointInitController.js @@ -67,12 +67,13 @@ function ($scope, $state, EndpointService, StateManager, EndpointProvider, Notif $scope.state.error = ''; var name = $scope.formValues.Name; var URL = $scope.formValues.URL; + var PublicURL = URL.split(':')[0]; var TLS = $scope.formValues.TLS; var TLSCAFile = $scope.formValues.TLSCACert; var TLSCertFile = $scope.formValues.TLSCert; var TLSKeyFile = $scope.formValues.TLSKey; - EndpointService.createRemoteEndpoint(name, URL, TLS, TLSCAFile, TLSCertFile, TLSKeyFile) + EndpointService.createRemoteEndpoint(name, URL, PublicURL, TLS, TLSCAFile, TLSCertFile, TLSKeyFile) .then(function success(data) { var endpointID = data.Id; updateEndpointState(endpointID); diff --git a/app/components/endpoints/endpoints.html b/app/components/endpoints/endpoints.html index 695a4aeb2..52755893a 100644 --- a/app/components/endpoints/endpoints.html +++ b/app/components/endpoints/endpoints.html @@ -46,6 +46,17 @@
+ +
+ +
+ +
+
+
diff --git a/app/components/endpoints/endpointsController.js b/app/components/endpoints/endpointsController.js index 7bf2a854a..f9d0082f2 100644 --- a/app/components/endpoints/endpointsController.js +++ b/app/components/endpoints/endpointsController.js @@ -13,6 +13,7 @@ function ($scope, $state, EndpointService, EndpointProvider, Notifications, Pagi $scope.formValues = { Name: '', URL: '', + PublicURL: '', TLS: false, TLSCACert: null, TLSCert: null, @@ -49,11 +50,15 @@ function ($scope, $state, EndpointService, EndpointProvider, Notifications, Pagi $scope.state.error = ''; var name = $scope.formValues.Name; var URL = $scope.formValues.URL; + var PublicURL = $scope.formValues.PublicURL; + if (PublicURL === '') { + PublicURL = URL.split(':')[0]; + } var TLS = $scope.formValues.TLS; var TLSCAFile = $scope.formValues.TLSCACert; var TLSCertFile = $scope.formValues.TLSCert; var TLSKeyFile = $scope.formValues.TLSKey; - EndpointService.createRemoteEndpoint(name, URL, TLS, TLSCAFile, TLSCertFile, TLSKeyFile, false).then(function success(data) { + EndpointService.createRemoteEndpoint(name, URL, PublicURL, TLS, TLSCAFile, TLSCertFile, TLSKeyFile, false).then(function success(data) { Notifications.success("Endpoint created", name); $state.reload(); }, function error(err) { diff --git a/app/components/sidebar/sidebarController.js b/app/components/sidebar/sidebarController.js index 75b91dd14..eef6a0430 100644 --- a/app/components/sidebar/sidebarController.js +++ b/app/components/sidebar/sidebarController.js @@ -11,7 +11,9 @@ function ($scope, $state, Settings, Config, EndpointService, StateManager, Endpo $scope.switchEndpoint = function(endpoint) { var activeEndpointID = EndpointProvider.endpointID(); + var activeEndpointPublicURL = EndpointProvider.endpointPublicURL(); EndpointProvider.setEndpointID(endpoint.Id); + EndpointProvider.setEndpointPublicURL(endpoint.PublicURL); StateManager.updateEndpointState(true) .then(function success() { $state.go('dashboard'); @@ -19,6 +21,7 @@ function ($scope, $state, Settings, Config, EndpointService, StateManager, Endpo .catch(function error(err) { Notifications.error("Failure", err, "Unable to connect to the Docker endpoint"); EndpointProvider.setEndpointID(activeEndpointID); + EndpointProvider.setEndpointPublicURL(activeEndpointPublicURL); StateManager.updateEndpointState(true) .then(function success() {}); }); @@ -32,6 +35,7 @@ function ($scope, $state, Settings, Config, EndpointService, StateManager, Endpo angular.forEach($scope.endpoints, function (endpoint) { if (endpoint.Id === activeEndpointID) { $scope.activeEndpoint = endpoint; + EndpointProvider.setEndpointPublicURL(endpoint.PublicURL); } }); }) diff --git a/app/services/endpointProvider.js b/app/services/endpointProvider.js index e6d43f604..4f1c870a9 100644 --- a/app/services/endpointProvider.js +++ b/app/services/endpointProvider.js @@ -5,9 +5,13 @@ angular.module('portainer.services') var service = {}; service.initialize = function() { var endpointID = LocalStorage.getEndpointID(); + var endpointPublicURL = LocalStorage.getEndpointPublicURL(); if (endpointID) { endpoint.ID = endpointID; } + if (endpointPublicURL) { + endpoint.PublicURL = endpointPublicURL; + } }; service.clean = function() { endpoint = {}; @@ -19,5 +23,12 @@ angular.module('portainer.services') endpoint.ID = id; LocalStorage.storeEndpointID(id); }; + service.endpointPublicURL = function() { + return endpoint.PublicURL; + } + service.setEndpointPublicURL = function(publicURL) { + endpoint.PublicURL = publicURL; + LocalStorage.storeEndpointPublicURL(publicURL); + } return service; }]); diff --git a/app/services/endpointService.js b/app/services/endpointService.js index e9486cd29..0b4e88418 100644 --- a/app/services/endpointService.js +++ b/app/services/endpointService.js @@ -18,6 +18,7 @@ angular.module('portainer.services') service.updateEndpoint = function(id, endpointParams) { var query = { name: endpointParams.name, + PublicURL: endpointParams.PublicURL, TLS: endpointParams.TLS, authorizedUsers: endpointParams.authorizedUsers }; @@ -54,10 +55,11 @@ angular.module('portainer.services') return Endpoints.create({}, endpoint).$promise; }; - service.createRemoteEndpoint = function(name, URL, TLS, TLSCAFile, TLSCertFile, TLSKeyFile) { + service.createRemoteEndpoint = function(name, URL, PublicURL, TLS, TLSCAFile, TLSCertFile, TLSKeyFile) { var endpoint = { Name: name, URL: 'tcp://' + URL, + PublicURL: PublicURL, TLS: TLS }; var deferred = $q.defer(); diff --git a/app/services/localStorage.js b/app/services/localStorage.js index acc6fe378..ae991ddea 100644 --- a/app/services/localStorage.js +++ b/app/services/localStorage.js @@ -8,6 +8,12 @@ angular.module('portainer.services') getEndpointID: function() { return localStorageService.get('ENDPOINT_ID'); }, + storeEndpointPublicURL: function(publicURL) { + localStorageService.set('ENDPOINT_PUBLIC_URL', publicURL); + }, + getEndpointPublicURL: function() { + return localStorageService.get('ENDPOINT_PUBLIC_URL'); + }, storeEndpointState: function(state) { localStorageService.set('ENDPOINT_STATE', state); },