From 3c34fbd8f23be3c028e82bdc851a9230acf0f0ef Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Tue, 14 Jul 2020 23:46:38 +0300 Subject: [PATCH] refactor(router): show endpoint id in url (#3966) * refactor(module): provide basic endpoint id url * fix(stacks): fix route to include endpointId * fix(stacks): fix stacks urls * fix(sidebar): fix urls to docker routes * refactor(app): set endpoint id on change view * refactor(dashboard): revert to old version * refactor(sidebar): revert file * feat(app): wip load endpoint on route change * feat(home): show error * feat(app): load endpoint route * feat(sidebar): show endpoint per provider * refactor(app): revert * refactor(app): clean endpoint startup * feat(edge): check for edge k8s * refactor(endpoints): move all modules under endpoint route * refactor(stacks): move stacks route to docker * refactor(templates): move templates route to docker * refactor(app): check endpoint when entering docker module * fix(app): load endpoint when entering endpoints modules * feat(azure): check endpoint * feat(kubernetes): check endpoint * feat(home): show loading state when loading edge * style(app): revert small changes * refactor(sidebar): remove refernce to endpointId * fix(stacks): fix stacks route * style(docker): sort routes * feat(app): change route to home if endpoint failed * fix(services): guard against empty snapshots * feat(app): show error when failed to load endpoint * feat(app): reload home route when failing * refactor(router): replace resolvers with onEnter --- app/azure/_module.js | 14 +- app/docker/__module.js | 144 ++++++++++++++-- .../dockerSidebarContent.html | 10 +- app/docker/interceptors/infoInterceptor.js | 2 +- app/docker/interceptors/versionInterceptor.js | 2 +- app/docker/views/dashboard/dashboard.html | 2 +- .../views/dashboard/dashboardController.js | 5 +- app/kubernetes/__module.js | 29 ++-- app/portainer/__module.js | 142 ++++------------ .../stacks-datatable/stacksDatatable.html | 4 +- .../template-list/templateList.html | 2 +- app/portainer/services/stateManager.js | 6 +- app/portainer/views/home/homeController.js | 159 ++---------------- .../stacks/create/createStackController.js | 7 +- .../views/stacks/create/createstack.html | 2 +- app/portainer/views/stacks/edit/stack.html | 4 +- .../views/stacks/edit/stackController.js | 8 +- app/portainer/views/stacks/stacks.html | 2 +- app/portainer/views/templates/templates.html | 2 +- .../views/templates/templatesController.js | 15 +- 20 files changed, 245 insertions(+), 316 deletions(-) diff --git a/app/azure/_module.js b/app/azure/_module.js index a11a5aa5e..523fb20e3 100644 --- a/app/azure/_module.js +++ b/app/azure/_module.js @@ -6,8 +6,20 @@ angular.module('portainer.azure', ['portainer.app']).config([ var azure = { name: 'azure', url: '/azure', - parent: 'root', + parent: 'endpoint', abstract: true, + /* ngInject */ + async onEnter($state, endpoint, EndpointProvider, Notifications, StateManager) { + try { + EndpointProvider.setEndpointID(endpoint.Id); + EndpointProvider.setEndpointPublicURL(endpoint.PublicURL); + EndpointProvider.setOfflineModeFromStatus(endpoint.Status); + await StateManager.updateEndpointState(endpoint, []); + } catch (e) { + Notifications.error('Failed loading endpoint', e); + $state.go('portainer.home', {}, { reload: true }); + } + }, }; var containerInstances = { diff --git a/app/docker/__module.js b/app/docker/__module.js index 816877528..1aa2d827b 100644 --- a/app/docker/__module.js +++ b/app/docker/__module.js @@ -5,19 +5,53 @@ angular.module('portainer.docker', ['portainer.app']).config([ var docker = { name: 'docker', - parent: 'root', + parent: 'endpoint', abstract: true, - resolve: { - endpointID: [ - 'EndpointProvider', - '$state', - function (EndpointProvider, $state) { - var id = EndpointProvider.endpointID(); - if (!id) { - return $state.go('portainer.home'); + /* ngInject */ + async onEnter(endpoint, $state, EndpointService, EndpointProvider, LegacyExtensionManager, Notifications, StateManager, SystemService) { + try { + const status = await checkEndpointStatus(endpoint); + + if (endpoint.Type !== 4) { + await updateEndpointStatus(endpoint, status); + } + endpoint.Status = status; + + if (status === 2) { + if (!endpoint.Snapshots[0]) { + throw new Error('Endpoint is unreachable and there is no snapshot available for offline browsing.'); } - }, - ], + if (endpoint.Snapshots[0].Swarm) { + throw new Error('Endpoint is unreachable. Connect to another swarm manager.'); + } + } + + EndpointProvider.setEndpointID(endpoint.Id); + EndpointProvider.setEndpointPublicURL(endpoint.PublicURL); + EndpointProvider.setOfflineModeFromStatus(endpoint.Status); + + const extensions = await LegacyExtensionManager.initEndpointExtensions(endpoint); + await StateManager.updateEndpointState(endpoint, extensions); + } catch (e) { + Notifications.error('Failed loading endpoint', e); + $state.go('portainer.home', {}, { reload: true }); + } + + async function checkEndpointStatus(endpoint) { + try { + await SystemService.ping(endpoint.Id); + return 1; + } catch (e) { + return 2; + } + } + + async function updateEndpointStatus(endpoint, status) { + if (endpoint.Status === status) { + return; + } + await EndpointService.updateEndpoint(endpoint.Id, { Status: status }); + } }, }; @@ -144,6 +178,43 @@ angular.module('portainer.docker', ['portainer.app']).config([ }, }; + const customTemplates = { + name: 'portainer.templates.custom', + url: '/custom', + + views: { + 'content@': { + component: 'customTemplatesView', + }, + }, + }; + + const customTemplatesNew = { + name: 'portainer.templates.custom.new', + url: '/new?fileContent&type', + + views: { + 'content@': { + component: 'createCustomTemplateView', + }, + }, + params: { + fileContent: '', + type: '', + }, + }; + + const customTemplatesEdit = { + name: 'portainer.templates.custom.edit', + url: '/:id', + + views: { + 'content@': { + component: 'editCustomTemplateView', + }, + }, + }; + var dashboard = { name: 'docker.dashboard', url: '/dashboard', @@ -366,6 +437,39 @@ angular.module('portainer.docker', ['portainer.app']).config([ }, }; + var stacks = { + name: 'docker.stacks', + url: '/stacks', + views: { + 'content@': { + templateUrl: '~Portainer/views/stacks/stacks.html', + controller: 'StacksController', + }, + }, + }; + + var stack = { + name: 'docker.stacks.stack', + url: '/:name?id&type&external', + views: { + 'content@': { + templateUrl: '~Portainer/views/stacks/edit/stack.html', + controller: 'StackController', + }, + }, + }; + + var stackCreation = { + name: 'docker.stacks.newstack', + url: '/newstack', + views: { + 'content@': { + templateUrl: '~Portainer/views/stacks/create/createstack.html', + controller: 'CreateStackController', + }, + }, + }; + var swarm = { name: 'docker.swarm', url: '/swarm', @@ -416,6 +520,17 @@ angular.module('portainer.docker', ['portainer.app']).config([ }, }; + var templates = { + name: 'docker.templates', + url: '/templates', + views: { + 'content@': { + templateUrl: '~Portainer/views/templates/templates.html', + controller: 'TemplatesController', + }, + }, + }; + var volumes = { name: 'docker.volumes', url: '/volumes', @@ -471,6 +586,9 @@ angular.module('portainer.docker', ['portainer.app']).config([ $stateRegistryProvider.register(containerInspect); $stateRegistryProvider.register(containerLogs); $stateRegistryProvider.register(containerStats); + $stateRegistryProvider.register(customTemplates); + $stateRegistryProvider.register(customTemplatesNew); + $stateRegistryProvider.register(customTemplatesEdit); $stateRegistryProvider.register(docker); $stateRegistryProvider.register(dashboard); $stateRegistryProvider.register(host); @@ -493,11 +611,15 @@ angular.module('portainer.docker', ['portainer.app']).config([ $stateRegistryProvider.register(service); $stateRegistryProvider.register(serviceCreation); $stateRegistryProvider.register(serviceLogs); + $stateRegistryProvider.register(stacks); + $stateRegistryProvider.register(stack); + $stateRegistryProvider.register(stackCreation); $stateRegistryProvider.register(swarm); $stateRegistryProvider.register(swarmVisualizer); $stateRegistryProvider.register(tasks); $stateRegistryProvider.register(task); $stateRegistryProvider.register(taskLogs); + $stateRegistryProvider.register(templates); $stateRegistryProvider.register(volumes); $stateRegistryProvider.register(volume); $stateRegistryProvider.register(volumeBrowse); diff --git a/app/docker/components/dockerSidebarContent/dockerSidebarContent.html b/app/docker/components/dockerSidebarContent/dockerSidebarContent.html index 118b63fbe..ea8a47095 100644 --- a/app/docker/components/dockerSidebarContent/dockerSidebarContent.html +++ b/app/docker/components/dockerSidebarContent/dockerSidebarContent.html @@ -2,14 +2,14 @@ Dashboard