From 82064152ecc5af66410e87bb6853ffd1ac6e4149 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Wed, 5 Aug 2020 13:23:19 +0300 Subject: [PATCH] feat(registries): remove registry extension (#4155) * feat(registries): remove client extension code * feat(registry): remove server registry code * refactor(registry): remove extension related code * feat(extensions): remove registry extension type --- api/exec/extension.go | 5 +- api/http/handler/registries/handler.go | 4 - api/http/handler/registries/proxy.go | 85 ---- .../registries/proxy_management_gitlab.go | 68 --- api/http/proxy/factory/factory.go | 3 +- api/portainer.go | 2 +- .../porImageRegistryController.js | 2 +- app/docker/helpers/imageHelper.js | 2 +- app/extensions/_module.js | 2 +- app/extensions/registry-management/_module.js | 55 --- .../registryRepositoriesDatatable.html | 76 ---- .../registryRepositoriesDatatable.js | 14 - ...registryRepositoriesDatatableController.js | 41 -- .../registriesRepositoryTagsDatatable.html | 108 ----- .../registriesRepositoryTagsDatatable.js | 17 - ...stryRepositoriesTagsDatatableController.js | 37 -- .../helpers/localRegistryHelper.js | 35 -- .../models/registryImageDetails.js | 14 - .../models/registryImageLayer.js | 8 - .../models/repositoryTag.js | 22 - .../registry-management/rest/catalog.js | 34 -- .../rest/manifestJquery.js | 90 ---- .../registry-management/rest/tags.js | 20 - .../rest/transform/linkGetResponse.js | 13 - .../services/genericAsyncGenerator.js | 34 -- .../services/registryServiceSelector.js | 84 ---- .../services/registryV2Service.js | 310 ------------- .../configure/configureRegistryController.js | 75 ---- .../views/configure/configureregistry.html | 170 ------- .../progression-modal/progressionModal.html | 11 - .../progression-modal/progressionModal.js | 6 - .../repositories/edit/registryRepository.html | 134 ------ .../edit/registryRepositoryController.js | 423 ------------------ .../repositories/registryRepositories.html | 45 -- .../registryRepositoriesController.js | 68 --- .../tag/registryRepositoryTag.html | 177 -------- .../tag/registryRepositoryTagController.js | 56 --- .../registriesDatatable.html | 15 - .../registriesDatatable.js | 1 - .../registry-form-gitlab.html | 4 - .../models/gitlabRegistry.js | 0 app/portainer/models/registry.js | 2 +- .../models/registryRepository.js | 0 .../models/registryTypes.js | 0 .../rest/gitlab.js | 2 +- .../rest/transform/gitlabResponseGetLink.js | 0 app/portainer/services/api/registryService.js | 2 +- .../services/registryGitlabService.js | 2 +- .../create/createRegistryController.js | 6 +- .../views/registries/registries.html | 1 - .../views/registries/registriesController.js | 5 +- 51 files changed, 13 insertions(+), 2377 deletions(-) delete mode 100644 api/http/handler/registries/proxy.go delete mode 100644 api/http/handler/registries/proxy_management_gitlab.go delete mode 100644 app/extensions/registry-management/_module.js delete mode 100644 app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html delete mode 100644 app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.js delete mode 100644 app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatableController.js delete mode 100644 app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.html delete mode 100644 app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.js delete mode 100644 app/extensions/registry-management/components/registries-repository-tags-datatable/registryRepositoriesTagsDatatableController.js delete mode 100644 app/extensions/registry-management/helpers/localRegistryHelper.js delete mode 100644 app/extensions/registry-management/models/registryImageDetails.js delete mode 100644 app/extensions/registry-management/models/registryImageLayer.js delete mode 100644 app/extensions/registry-management/models/repositoryTag.js delete mode 100644 app/extensions/registry-management/rest/catalog.js delete mode 100644 app/extensions/registry-management/rest/manifestJquery.js delete mode 100644 app/extensions/registry-management/rest/tags.js delete mode 100644 app/extensions/registry-management/rest/transform/linkGetResponse.js delete mode 100644 app/extensions/registry-management/services/genericAsyncGenerator.js delete mode 100644 app/extensions/registry-management/services/registryServiceSelector.js delete mode 100644 app/extensions/registry-management/services/registryV2Service.js delete mode 100644 app/extensions/registry-management/views/configure/configureRegistryController.js delete mode 100644 app/extensions/registry-management/views/configure/configureregistry.html delete mode 100644 app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.html delete mode 100644 app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.js delete mode 100644 app/extensions/registry-management/views/repositories/edit/registryRepository.html delete mode 100644 app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js delete mode 100644 app/extensions/registry-management/views/repositories/registryRepositories.html delete mode 100644 app/extensions/registry-management/views/repositories/registryRepositoriesController.js delete mode 100644 app/extensions/registry-management/views/repositories/tag/registryRepositoryTag.html delete mode 100644 app/extensions/registry-management/views/repositories/tag/registryRepositoryTagController.js rename app/{extensions/registry-management => portainer}/models/gitlabRegistry.js (100%) rename app/{extensions/registry-management => portainer}/models/registryRepository.js (100%) rename app/{extensions/registry-management => portainer}/models/registryTypes.js (100%) rename app/{extensions/registry-management => portainer}/rest/gitlab.js (92%) rename app/{extensions/registry-management => portainer}/rest/transform/gitlabResponseGetLink.js (100%) rename app/{extensions/registry-management => portainer}/services/registryGitlabService.js (96%) diff --git a/api/exec/extension.go b/api/exec/extension.go index 036cfc01a..049bf9851 100644 --- a/api/exec/extension.go +++ b/api/exec/extension.go @@ -26,8 +26,7 @@ var extensionDownloadBaseURL = portainer.AssetsServerURL + "/extensions/" var extensionVersionRegexp = regexp.MustCompile(`\d+(\.\d+)+`) var extensionBinaryMap = map[portainer.ExtensionID]string{ - portainer.RegistryManagementExtension: "extension-registry-management", - portainer.RBACExtension: "extension-rbac", + portainer.RBACExtension: "extension-rbac", } // ExtensionManager represents a service used to @@ -111,8 +110,6 @@ func (manager *ExtensionManager) InstallExtension(extension *portainer.Extension } switch extension.ID { - case portainer.RegistryManagementExtension: - extension.Name = "Registry Manager" case portainer.RBACExtension: extension.Name = "Role-Based Access Control" } diff --git a/api/http/handler/registries/handler.go b/api/http/handler/registries/handler.go index 74a933586..035385346 100644 --- a/api/http/handler/registries/handler.go +++ b/api/http/handler/registries/handler.go @@ -43,10 +43,6 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler { bouncer.AdminAccess(httperror.LoggerHandler(h.registryConfigure))).Methods(http.MethodPost) h.Handle("/registries/{id}", bouncer.AdminAccess(httperror.LoggerHandler(h.registryDelete))).Methods(http.MethodDelete) - h.PathPrefix("/registries/{id}/v2").Handler( - bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.proxyRequestsToRegistryAPI))) - h.PathPrefix("/registries/{id}/proxies/gitlab").Handler( - bouncer.RestrictedAccess(httperror.LoggerHandler(h.proxyRequestsToGitlabAPIWithRegistry))) h.PathPrefix("/registries/proxies/gitlab").Handler( bouncer.AdminAccess(httperror.LoggerHandler(h.proxyRequestsToGitlabAPIWithoutRegistry))) return h diff --git a/api/http/handler/registries/proxy.go b/api/http/handler/registries/proxy.go deleted file mode 100644 index d452e8e66..000000000 --- a/api/http/handler/registries/proxy.go +++ /dev/null @@ -1,85 +0,0 @@ -package registries - -import ( - "encoding/json" - "net/http" - "strconv" - - httperror "github.com/portainer/libhttp/error" - "github.com/portainer/libhttp/request" - "github.com/portainer/portainer/api" - bolterrors "github.com/portainer/portainer/api/bolt/errors" - "github.com/portainer/portainer/api/http/errors" -) - -// request on /api/registries/:id/v2 -func (handler *Handler) proxyRequestsToRegistryAPI(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - registryID, err := request.RetrieveNumericRouteVariableValue(r, "id") - if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} - } - - registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) - if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} - } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} - } - - err = handler.requestBouncer.RegistryAccess(r, registry) - if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", errors.ErrEndpointAccessDenied} - } - - extension, err := handler.DataStore.Extension().Extension(portainer.RegistryManagementExtension) - if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{http.StatusNotFound, "Registry management extension is not enabled", err} - } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err} - } - - var proxy http.Handler - proxy = handler.ProxyManager.GetExtensionProxy(portainer.RegistryManagementExtension) - if proxy == nil { - proxy, err = handler.ProxyManager.CreateExtensionProxy(portainer.RegistryManagementExtension) - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create extension proxy for registry manager", err} - } - } - - managementConfiguration := registry.ManagementConfiguration - if managementConfiguration == nil { - managementConfiguration = createDefaultManagementConfiguration(registry) - } - - encodedConfiguration, err := json.Marshal(managementConfiguration) - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to encode management configuration", err} - } - - id := strconv.Itoa(int(registryID)) - r.Header.Set("X-RegistryManagement-Key", id) - r.Header.Set("X-RegistryManagement-URI", registry.URL) - r.Header.Set("X-RegistryManagement-Config", string(encodedConfiguration)) - r.Header.Set("X-PortainerExtension-License", extension.License.LicenseKey) - - http.StripPrefix("/registries/"+id, proxy).ServeHTTP(w, r) - return nil -} - -func createDefaultManagementConfiguration(registry *portainer.Registry) *portainer.RegistryManagementConfiguration { - config := &portainer.RegistryManagementConfiguration{ - Type: registry.Type, - TLSConfig: portainer.TLSConfiguration{ - TLS: false, - }, - } - - if registry.Authentication { - config.Authentication = true - config.Username = registry.Username - config.Password = registry.Password - } - - return config -} diff --git a/api/http/handler/registries/proxy_management_gitlab.go b/api/http/handler/registries/proxy_management_gitlab.go deleted file mode 100644 index 6a8656c38..000000000 --- a/api/http/handler/registries/proxy_management_gitlab.go +++ /dev/null @@ -1,68 +0,0 @@ -package registries - -import ( - "encoding/json" - "net/http" - "strconv" - - httperror "github.com/portainer/libhttp/error" - "github.com/portainer/libhttp/request" - "github.com/portainer/portainer/api" - bolterrors "github.com/portainer/portainer/api/bolt/errors" - "github.com/portainer/portainer/api/http/errors" -) - -// request on /api/registries/{id}/proxies/gitlab -func (handler *Handler) proxyRequestsToGitlabAPIWithRegistry(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - registryID, err := request.RetrieveNumericRouteVariableValue(r, "id") - if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} - } - - registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) - if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} - } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} - } - - err = handler.requestBouncer.RegistryAccess(r, registry) - if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", errors.ErrEndpointAccessDenied} - } - - extension, err := handler.DataStore.Extension().Extension(portainer.RegistryManagementExtension) - if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{http.StatusNotFound, "Registry management extension is not enabled", err} - } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err} - } - - var proxy http.Handler - proxy = handler.ProxyManager.GetExtensionProxy(portainer.RegistryManagementExtension) - if proxy == nil { - proxy, err = handler.ProxyManager.CreateExtensionProxy(portainer.RegistryManagementExtension) - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create extension proxy for registry manager", err} - } - } - - config := &portainer.RegistryManagementConfiguration{ - Type: portainer.GitlabRegistry, - Password: registry.Password, - } - - encodedConfiguration, err := json.Marshal(config) - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to encode management configuration", err} - } - - id := strconv.Itoa(int(registryID)) - r.Header.Set("X-RegistryManagement-Key", id+"-gitlab") - r.Header.Set("X-RegistryManagement-URI", registry.Gitlab.InstanceURL) - r.Header.Set("X-RegistryManagement-Config", string(encodedConfiguration)) - r.Header.Set("X-PortainerExtension-License", extension.License.LicenseKey) - - http.StripPrefix("/registries/"+id+"/proxies/gitlab", proxy).ServeHTTP(w, r) - return nil -} diff --git a/api/http/proxy/factory/factory.go b/api/http/proxy/factory/factory.go index 3068a8cea..5beaba1f6 100644 --- a/api/http/proxy/factory/factory.go +++ b/api/http/proxy/factory/factory.go @@ -17,8 +17,7 @@ import ( const azureAPIBaseURL = "https://management.azure.com" var extensionPorts = map[portainer.ExtensionID]string{ - portainer.RegistryManagementExtension: "7001", - portainer.RBACExtension: "7003", + portainer.RBACExtension: "7003", } type ( diff --git a/api/portainer.go b/api/portainer.go index b87666e17..367061816 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -1255,7 +1255,7 @@ const ( const ( _ ExtensionID = iota - // RegistryManagementExtension represents the registry management extension + // RegistryManagementExtension represents the registry management extension (removed) RegistryManagementExtension // OAuthAuthenticationExtension represents the OAuth authentication extension (Deprecated) OAuthAuthenticationExtension diff --git a/app/docker/components/imageRegistry/porImageRegistryController.js b/app/docker/components/imageRegistry/porImageRegistryController.js index f16902c9d..2c2ff5e53 100644 --- a/app/docker/components/imageRegistry/porImageRegistryController.js +++ b/app/docker/components/imageRegistry/porImageRegistryController.js @@ -1,7 +1,7 @@ import angular from 'angular'; import _ from 'lodash-es'; import { DockerHubViewModel } from 'Portainer/models/dockerhub'; -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; +import { RegistryTypes } from '@/portainer/models/registryTypes'; class porImageRegistryController { /* @ngInject */ diff --git a/app/docker/helpers/imageHelper.js b/app/docker/helpers/imageHelper.js index ea28976de..ff149b939 100644 --- a/app/docker/helpers/imageHelper.js +++ b/app/docker/helpers/imageHelper.js @@ -1,5 +1,5 @@ import _ from 'lodash-es'; -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; +import { RegistryTypes } from '@/portainer/models/registryTypes'; angular.module('portainer.docker').factory('ImageHelper', [ function ImageHelperFactory() { diff --git a/app/extensions/_module.js b/app/extensions/_module.js index 47dfa09a3..9afe56617 100644 --- a/app/extensions/_module.js +++ b/app/extensions/_module.js @@ -1 +1 @@ -angular.module('portainer.extensions', ['portainer.extensions.registrymanagement', 'portainer.extensions.rbac']); +angular.module('portainer.extensions', ['portainer.extensions.rbac']); diff --git a/app/extensions/registry-management/_module.js b/app/extensions/registry-management/_module.js deleted file mode 100644 index b471aee44..000000000 --- a/app/extensions/registry-management/_module.js +++ /dev/null @@ -1,55 +0,0 @@ -angular.module('portainer.extensions.registrymanagement', []).config([ - '$stateRegistryProvider', - function ($stateRegistryProvider) { - 'use strict'; - - var registryConfiguration = { - name: 'portainer.registries.registry.configure', - url: '/configure', - views: { - 'content@': { - templateUrl: './views/configure/configureregistry.html', - controller: 'ConfigureRegistryController', - }, - }, - }; - - var registryRepositories = { - name: 'portainer.registries.registry.repositories', - url: '/repositories', - views: { - 'content@': { - templateUrl: './views/repositories/registryRepositories.html', - controller: 'RegistryRepositoriesController', - }, - }, - }; - - var registryRepositoryTags = { - name: 'portainer.registries.registry.repository', - url: '/:repository', - views: { - 'content@': { - templateUrl: './views/repositories/edit/registryRepository.html', - controller: 'RegistryRepositoryController', - }, - }, - }; - var registryRepositoryTag = { - name: 'portainer.registries.registry.repository.tag', - url: '/:tag', - views: { - 'content@': { - templateUrl: './views/repositories/tag/registryRepositoryTag.html', - controller: 'RegistryRepositoryTagController', - controllerAs: 'ctrl', - }, - }, - }; - - $stateRegistryProvider.register(registryConfiguration); - $stateRegistryProvider.register(registryRepositories); - $stateRegistryProvider.register(registryRepositoryTags); - $stateRegistryProvider.register(registryRepositoryTag); - }, -]); diff --git a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html b/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html deleted file mode 100644 index 72e632518..000000000 --- a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.html +++ /dev/null @@ -1,76 +0,0 @@ -
- - -
-
{{ $ctrl.titleText }}
-
- -
- - - - - - - - - - - - - - - - - - - -
- - Repository - - - - - Tags count -
- {{ item.Name }} - {{ item.TagsCount }}
Loading...
No repository available.
-
- -
-
-
diff --git a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.js b/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.js deleted file mode 100644 index 8dde205ab..000000000 --- a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatable.js +++ /dev/null @@ -1,14 +0,0 @@ -angular.module('portainer.extensions.registrymanagement').component('registryRepositoriesDatatable', { - templateUrl: './registryRepositoriesDatatable.html', - controller: 'RegistryRepositoriesDatatableController', - bindings: { - titleText: '@', - titleIcon: '@', - dataset: '<', - tableKey: '@', - orderBy: '@', - reverseOrder: '<', - paginationAction: '<', - loading: '<', - }, -}); diff --git a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatableController.js b/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatableController.js deleted file mode 100644 index de4769daa..000000000 --- a/app/extensions/registry-management/components/registries-repositories-datatable/registryRepositoriesDatatableController.js +++ /dev/null @@ -1,41 +0,0 @@ -import _ from 'lodash-es'; - -angular.module('portainer.app').controller('RegistryRepositoriesDatatableController', [ - '$scope', - '$controller', - function ($scope, $controller) { - var ctrl = this; - - angular.extend(this, $controller('GenericDatatableController', { $scope: $scope })); - this.state.orderBy = this.orderBy; - - function areDifferent(a, b) { - if (!a || !b) { - return true; - } - var namesA = a - .map(function (x) { - return x.Name; - }) - .sort(); - var namesB = b - .map(function (x) { - return x.Name; - }) - .sort(); - return namesA.join(',') !== namesB.join(','); - } - - $scope.$watch( - function () { - return ctrl.state.filteredDataSet; - }, - function (newValue, oldValue) { - if (newValue && areDifferent(oldValue, newValue)) { - ctrl.paginationAction(_.filter(newValue, { TagsCount: 0 })); - } - }, - true - ); - }, -]); diff --git a/app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.html b/app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.html deleted file mode 100644 index 5602100bc..000000000 --- a/app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.html +++ /dev/null @@ -1,108 +0,0 @@ -
- - -
-
{{ $ctrl.titleText }}
-
-
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - Name - - - - Os/ArchitectureImage IDCompressed sizeActions
- - - - - {{ item.Name }} - {{ item.Os }}/{{ item.Architecture }}{{ item.ImageId | trimshasum }}{{ item.Size | humansize }} - - - Retag - - - - - - - - -
Loading...
No tag available.
-
- -
-
-
diff --git a/app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.js b/app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.js deleted file mode 100644 index 9ee817654..000000000 --- a/app/extensions/registry-management/components/registries-repository-tags-datatable/registriesRepositoryTagsDatatable.js +++ /dev/null @@ -1,17 +0,0 @@ -angular.module('portainer.extensions.registrymanagement').component('registriesRepositoryTagsDatatable', { - templateUrl: './registriesRepositoryTagsDatatable.html', - controller: 'RegistryRepositoriesTagsDatatableController', - bindings: { - titleText: '@', - titleIcon: '@', - dataset: '<', - tableKey: '@', - orderBy: '@', - reverseOrder: '<', - removeAction: '<', - retagAction: '<', - advancedFeaturesAvailable: '<', - paginationAction: '<', - loading: '<', - }, -}); diff --git a/app/extensions/registry-management/components/registries-repository-tags-datatable/registryRepositoriesTagsDatatableController.js b/app/extensions/registry-management/components/registries-repository-tags-datatable/registryRepositoriesTagsDatatableController.js deleted file mode 100644 index cc21dc902..000000000 --- a/app/extensions/registry-management/components/registries-repository-tags-datatable/registryRepositoriesTagsDatatableController.js +++ /dev/null @@ -1,37 +0,0 @@ -import _ from 'lodash-es'; - -angular.module('portainer.app').controller('RegistryRepositoriesTagsDatatableController', [ - '$scope', - '$controller', - function ($scope, $controller) { - angular.extend(this, $controller('GenericDatatableController', { $scope: $scope })); - var ctrl = this; - this.state.orderBy = this.orderBy; - - function diff(item) { - return item.Name + item.ImageDigest; - } - - function areDifferent(a, b) { - if (!a || !b) { - return true; - } - var namesA = _.sortBy(_.map(a, diff)); - var namesB = _.sortBy(_.map(b, diff)); - return namesA.join(',') !== namesB.join(','); - } - - $scope.$watch( - function () { - return ctrl.state.filteredDataSet; - }, - function (newValue, oldValue) { - if (newValue && newValue.length && areDifferent(oldValue, newValue)) { - ctrl.paginationAction(_.filter(newValue, { ImageId: '' })); - ctrl.resetSelectionState(); - } - }, - true - ); - }, -]); diff --git a/app/extensions/registry-management/helpers/localRegistryHelper.js b/app/extensions/registry-management/helpers/localRegistryHelper.js deleted file mode 100644 index 851f4b62a..000000000 --- a/app/extensions/registry-management/helpers/localRegistryHelper.js +++ /dev/null @@ -1,35 +0,0 @@ -import _ from 'lodash-es'; -import { RepositoryTagViewModel } from '../models/repositoryTag'; - -angular.module('portainer.extensions.registrymanagement').factory('RegistryV2Helper', [ - function RegistryV2HelperFactory() { - 'use strict'; - - var helper = {}; - - function historyRawToParsed(rawHistory) { - return _.map(rawHistory, (item) => angular.fromJson(item.v1Compatibility)); - } - - helper.manifestsToTag = function (manifests) { - var v1 = manifests.v1; - var v2 = manifests.v2; - - var history = historyRawToParsed(v1.history); - var name = v1.tag; - var os = history[0].os; - var arch = v1.architecture; - var size = v2.layers.reduce(function (a, b) { - return { - size: a.size + b.size, - }; - }).size; - var imageId = v2.config.digest; - var imageDigest = v2.digest; - - return new RepositoryTagViewModel(name, os, arch, size, imageDigest, imageId, v2, history); - }; - - return helper; - }, -]); diff --git a/app/extensions/registry-management/models/registryImageDetails.js b/app/extensions/registry-management/models/registryImageDetails.js deleted file mode 100644 index 9a80adedc..000000000 --- a/app/extensions/registry-management/models/registryImageDetails.js +++ /dev/null @@ -1,14 +0,0 @@ -export function RegistryImageDetailsViewModel(data) { - this.Id = data.id; - this.Parent = data.parent; - this.Created = data.created; - this.DockerVersion = data.docker_version; - this.Os = data.os; - this.Architecture = data.architecture; - this.Author = data.author; - this.Command = data.config.Cmd; - this.Entrypoint = data.container_config.Entrypoint ? data.container_config.Entrypoint : ''; - this.ExposedPorts = data.container_config.ExposedPorts ? Object.keys(data.container_config.ExposedPorts) : []; - this.Volumes = data.container_config.Volumes ? Object.keys(data.container_config.Volumes) : []; - this.Env = data.container_config.Env ? data.container_config.Env : []; -} diff --git a/app/extensions/registry-management/models/registryImageLayer.js b/app/extensions/registry-management/models/registryImageLayer.js deleted file mode 100644 index e2ec76f87..000000000 --- a/app/extensions/registry-management/models/registryImageLayer.js +++ /dev/null @@ -1,8 +0,0 @@ -import _ from 'lodash-es'; - -export function RegistryImageLayerViewModel(order, data) { - this.Order = order; - this.Id = data.id; - this.Created = data.created; - this.CreatedBy = _.join(data.container_config.Cmd, ' '); -} diff --git a/app/extensions/registry-management/models/repositoryTag.js b/app/extensions/registry-management/models/repositoryTag.js deleted file mode 100644 index b4682438d..000000000 --- a/app/extensions/registry-management/models/repositoryTag.js +++ /dev/null @@ -1,22 +0,0 @@ -export function RepositoryTagViewModel(name, os, arch, size, imageDigest, imageId, v2, history) { - this.Name = name; - this.Os = os || ''; - this.Architecture = arch || ''; - this.Size = size || 0; - this.ImageDigest = imageDigest || ''; - this.ImageId = imageId || ''; - this.ManifestV2 = v2 || {}; - this.History = history || []; -} - -export function RepositoryShortTag(name, imageId, imageDigest, manifest) { - this.Name = name; - this.ImageId = imageId; - this.ImageDigest = imageDigest; - this.ManifestV2 = manifest; -} - -export function RepositoryAddTagPayload(tag, manifest) { - this.Tag = tag; - this.Manifest = manifest; -} diff --git a/app/extensions/registry-management/rest/catalog.js b/app/extensions/registry-management/rest/catalog.js deleted file mode 100644 index dfe11b044..000000000 --- a/app/extensions/registry-management/rest/catalog.js +++ /dev/null @@ -1,34 +0,0 @@ -import linkGetResponse from './transform/linkGetResponse'; - -angular.module('portainer.extensions.registrymanagement').factory('RegistryCatalog', [ - '$resource', - 'API_ENDPOINT_REGISTRIES', - function RegistryCatalogFactory($resource, API_ENDPOINT_REGISTRIES) { - 'use strict'; - return $resource( - API_ENDPOINT_REGISTRIES + '/:id/v2/:action', - {}, - { - get: { - method: 'GET', - params: { id: '@id', action: '_catalog' }, - transformResponse: linkGetResponse, - }, - ping: { - method: 'GET', - params: { id: '@id' }, - timeout: 3500, - }, - pingWithForceNew: { - method: 'GET', - params: { id: '@id' }, - timeout: 3500, - headers: { 'X-RegistryManagement-ForceNew': '1' }, - }, - }, - { - stripTrailingSlashes: false, - } - ); - }, -]); diff --git a/app/extensions/registry-management/rest/manifestJquery.js b/app/extensions/registry-management/rest/manifestJquery.js deleted file mode 100644 index a0f4fb082..000000000 --- a/app/extensions/registry-management/rest/manifestJquery.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * This service has been created to request the docker registry API - * without triggering AngularJS digest cycles - * For more information, see https://github.com/portainer/portainer/pull/2648#issuecomment-505644913 - */ - -import $ from 'jquery'; - -angular.module('portainer.extensions.registrymanagement').factory('RegistryManifestsJquery', [ - 'API_ENDPOINT_REGISTRIES', - function RegistryManifestsJqueryFactory(API_ENDPOINT_REGISTRIES) { - 'use strict'; - - function buildUrl(params) { - return API_ENDPOINT_REGISTRIES + '/' + params.id + '/v2/' + params.repository + '/manifests/' + params.tag; - } - - function _get(params) { - return new Promise((resolve, reject) => { - $.ajax({ - type: 'GET', - dataType: 'JSON', - url: buildUrl(params), - headers: { - 'Cache-Control': 'no-cache', - 'If-Modified-Since': 'Mon, 26 Jul 1997 05:00:00 GMT', - }, - success: (result) => resolve(result), - error: (error) => reject(error), - }); - }); - } - - function _getV2(params) { - return new Promise((resolve, reject) => { - $.ajax({ - type: 'GET', - dataType: 'JSON', - url: buildUrl(params), - headers: { - Accept: 'application/vnd.docker.distribution.manifest.v2+json', - 'Cache-Control': 'no-cache', - 'If-Modified-Since': 'Mon, 26 Jul 1997 05:00:00 GMT', - }, - success: (result, status, request) => { - result.digest = request.getResponseHeader('Docker-Content-Digest'); - resolve(result); - }, - error: (error) => reject(error), - }); - }); - } - - function _put(params, data) { - const transformRequest = (d) => { - return angular.toJson(d, 3); - }; - return new Promise((resolve, reject) => { - $.ajax({ - type: 'PUT', - url: buildUrl(params), - headers: { - 'Content-Type': 'application/vnd.docker.distribution.manifest.v2+json', - }, - data: transformRequest(data), - success: (result) => resolve(result), - error: (error) => reject(error), - }); - }); - } - - function _delete(params) { - return new Promise((resolve, reject) => { - $.ajax({ - type: 'DELETE', - url: buildUrl(params), - success: (result) => resolve(result), - error: (error) => reject(error), - }); - }); - } - - return { - get: _get, - getV2: _getV2, - put: _put, - delete: _delete, - }; - }, -]); diff --git a/app/extensions/registry-management/rest/tags.js b/app/extensions/registry-management/rest/tags.js deleted file mode 100644 index 6087d4eb5..000000000 --- a/app/extensions/registry-management/rest/tags.js +++ /dev/null @@ -1,20 +0,0 @@ -import linkGetResponse from './transform/linkGetResponse'; - -angular.module('portainer.extensions.registrymanagement').factory('RegistryTags', [ - '$resource', - 'API_ENDPOINT_REGISTRIES', - function RegistryTagsFactory($resource, API_ENDPOINT_REGISTRIES) { - 'use strict'; - return $resource( - API_ENDPOINT_REGISTRIES + '/:id/v2/:repository/tags/list', - {}, - { - get: { - method: 'GET', - params: { id: '@id', repository: '@repository' }, - transformResponse: linkGetResponse, - }, - } - ); - }, -]); diff --git a/app/extensions/registry-management/rest/transform/linkGetResponse.js b/app/extensions/registry-management/rest/transform/linkGetResponse.js deleted file mode 100644 index 6362c7a0f..000000000 --- a/app/extensions/registry-management/rest/transform/linkGetResponse.js +++ /dev/null @@ -1,13 +0,0 @@ -export default function linkGetResponse(data, headers) { - var response = angular.fromJson(data); - var link = headers('link'); - if (link) { - var queryString = link.substring(link.indexOf('?') + 1).split('>;')[0]; - var queries = queryString.split('&'); - for (var i = 0; i < queries.length; i++) { - var kv = queries[i].split('='); - response[kv[0]] = kv[1]; - } - } - return response; -} diff --git a/app/extensions/registry-management/services/genericAsyncGenerator.js b/app/extensions/registry-management/services/genericAsyncGenerator.js deleted file mode 100644 index 49978b41c..000000000 --- a/app/extensions/registry-management/services/genericAsyncGenerator.js +++ /dev/null @@ -1,34 +0,0 @@ -import _ from 'lodash-es'; - -function findBestStep(length) { - let step = Math.trunc(length / 10); - if (step < 10) { - step = 10; - } else if (step > 100) { - step = 100; - } - return step; -} - -export default async function* genericAsyncGenerator($q, list, func, params) { - const step = findBestStep(list.length); - let start = 0; - let end = start + step; - let results = []; - while (start < list.length) { - const batch = _.slice(list, start, end); - const promises = []; - for (let i = 0; i < batch.length; i++) { - promises.push(func(...params, batch[i])); - } - yield start; - const res = await $q.all(promises); - for (let i = 0; i < res.length; i++) { - results.push(res[i]); - } - start = end; - end += step; - } - yield list.length; - yield results; -} diff --git a/app/extensions/registry-management/services/registryServiceSelector.js b/app/extensions/registry-management/services/registryServiceSelector.js deleted file mode 100644 index f51d89e7e..000000000 --- a/app/extensions/registry-management/services/registryServiceSelector.js +++ /dev/null @@ -1,84 +0,0 @@ -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; - -angular.module('portainer.extensions.registrymanagement').factory('RegistryServiceSelector', [ - '$q', - 'RegistryV2Service', - 'RegistryGitlabService', - function RegistryServiceSelector($q, RegistryV2Service, RegistryGitlabService) { - 'use strict'; - const service = {}; - - service.ping = ping; - service.repositories = repositories; - service.getRepositoriesDetails = getRepositoriesDetails; - service.tags = tags; - service.getTagsDetails = getTagsDetails; - service.tag = tag; - service.addTag = addTag; - service.deleteManifest = deleteManifest; - - service.shortTagsWithProgress = shortTagsWithProgress; - service.deleteTagsWithProgress = deleteTagsWithProgress; - service.retagWithProgress = retagWithProgress; - - function ping(registry, forceNewConfig) { - let service = RegistryV2Service; - return service.ping(registry, forceNewConfig); - } - - function repositories(registry) { - let service = RegistryV2Service; - if (registry.Type === RegistryTypes.GITLAB) { - service = RegistryGitlabService; - } - return service.repositories(registry); - } - - function getRepositoriesDetails(registry, repositories) { - let service = RegistryV2Service; - return service.getRepositoriesDetails(registry, repositories); - } - - function tags(registry, repository) { - let service = RegistryV2Service; - return service.tags(registry, repository); - } - - function getTagsDetails(registry, repository, tags) { - let service = RegistryV2Service; - return service.getTagsDetails(registry, repository, tags); - } - - function tag(registry, repository, tag) { - let service = RegistryV2Service; - return service.tag(registry, repository, tag); - } - - function addTag(registry, repository, tag, manifest) { - let service = RegistryV2Service; - return service.addTag(registry, repository, tag, manifest); - } - - function deleteManifest(registry, repository, digest) { - let service = RegistryV2Service; - return service.deleteManifest(registry, repository, digest); - } - - function shortTagsWithProgress(registry, repository, tagsList) { - let service = RegistryV2Service; - return service.shortTagsWithProgress(registry, repository, tagsList); - } - - function deleteTagsWithProgress(registry, repository, modifiedDigests, impactedTags) { - let service = RegistryV2Service; - return service.deleteTagsWithProgress(registry, repository, modifiedDigests, impactedTags); - } - - function retagWithProgress(registry, repository, modifiedTags, modifiedDigests, impactedTags) { - let service = RegistryV2Service; - return service.retagWithProgress(registry, repository, modifiedTags, modifiedDigests, impactedTags); - } - - return service; - }, -]); diff --git a/app/extensions/registry-management/services/registryV2Service.js b/app/extensions/registry-management/services/registryV2Service.js deleted file mode 100644 index 242ca364b..000000000 --- a/app/extensions/registry-management/services/registryV2Service.js +++ /dev/null @@ -1,310 +0,0 @@ -import _ from 'lodash-es'; -import { RepositoryAddTagPayload, RepositoryShortTag } from '../models/repositoryTag'; -import { RegistryRepositoryViewModel } from '../models/registryRepository'; -import genericAsyncGenerator from './genericAsyncGenerator'; - -angular.module('portainer.extensions.registrymanagement').factory('RegistryV2Service', [ - '$q', - '$async', - 'RegistryCatalog', - 'RegistryTags', - 'RegistryManifestsJquery', - 'RegistryV2Helper', - function RegistryV2ServiceFactory($q, $async, RegistryCatalog, RegistryTags, RegistryManifestsJquery, RegistryV2Helper) { - 'use strict'; - var service = {}; - - /** - * PING - */ - function ping(registry, forceNewConfig) { - const id = registry.Id; - if (forceNewConfig) { - return RegistryCatalog.pingWithForceNew({ id: id }).$promise; - } - return RegistryCatalog.ping({ id: id }).$promise; - } - - /** - * END PING - */ - - /** - * REPOSITORIES - */ - - function _getCatalogPage(params, deferred, repositories) { - RegistryCatalog.get(params).$promise.then(function (data) { - repositories = _.concat(repositories, data.repositories); - if (data.last && data.n) { - _getCatalogPage({ id: params.id, n: data.n, last: data.last }, deferred, repositories); - } else { - deferred.resolve(repositories); - } - }); - } - - function _getCatalog(id) { - var deferred = $q.defer(); - var repositories = []; - - _getCatalogPage({ id: id }, deferred, repositories); - return deferred.promise; - } - - function repositories(registry) { - const deferred = $q.defer(); - const id = registry.Id; - - _getCatalog(id) - .then(function success(data) { - const repositories = _.map(data, (repositoryName) => new RegistryRepositoryViewModel(repositoryName)); - deferred.resolve(repositories); - }) - .catch(function error(err) { - deferred.reject({ - msg: 'Unable to retrieve repositories', - err: err, - }); - }); - - return deferred.promise; - } - - function getRepositoriesDetails(registry, repositories) { - const deferred = $q.defer(); - const promises = _.map(repositories, (repository) => tags(registry, repository.Name)); - - $q.all(promises) - .then(function success(data) { - var repositories = data.map(function (item) { - return new RegistryRepositoryViewModel(item); - }); - repositories = _.without(repositories, undefined); - deferred.resolve(repositories); - }) - .catch(function error(err) { - deferred.reject({ - msg: 'Unable to retrieve repositories', - err: err, - }); - }); - - return deferred.promise; - } - - /** - * END REPOSITORIES - */ - - /** - * TAGS - */ - - function _getTagsPage(params, deferred, previousTags) { - RegistryTags.get(params) - .$promise.then(function (data) { - previousTags.name = data.name; - previousTags.tags = _.concat(previousTags.tags, data.tags); - if (data.last && data.n) { - _getTagsPage({ id: params.id, repository: params.repository, n: data.n, last: data.last }, deferred, previousTags); - } else { - deferred.resolve(previousTags); - } - }) - .catch(function error(err) { - deferred.reject({ - msg: 'Unable to retrieve tags', - err: err, - }); - }); - } - - function tags(registry, repository) { - const deferred = $q.defer(); - const id = registry.Id; - - _getTagsPage({ id: id, repository: repository }, deferred, { tags: [] }); - return deferred.promise; - } - - function getTagsDetails(registry, repository, tags) { - const promises = _.map(tags, (t) => tag(registry, repository, t.Name)); - - return $q.all(promises); - } - - function tag(registry, repository, tag) { - const deferred = $q.defer(); - const id = registry.Id; - - var promises = { - v1: RegistryManifestsJquery.get({ - id: id, - repository: repository, - tag: tag, - }), - v2: RegistryManifestsJquery.getV2({ - id: id, - repository: repository, - tag: tag, - }), - }; - $q.all(promises) - .then(function success(data) { - var tag = RegistryV2Helper.manifestsToTag(data); - deferred.resolve(tag); - }) - .catch(function error(err) { - deferred.reject({ - msg: 'Unable to retrieve tag ' + tag, - err: err, - }); - }); - - return deferred.promise; - } - - /** - * END TAGS - */ - - /** - * ADD TAG - */ - - // tag: RepositoryAddTagPayload - function _addTagFromGenerator(registry, repository, tag) { - return addTag(registry, repository, tag.Tag, tag.Manifest); - } - - function addTag(registry, repository, tag, manifest) { - const id = registry.Id; - delete manifest.digest; - return RegistryManifestsJquery.put( - { - id: id, - repository: repository, - tag: tag, - }, - manifest - ); - } - - async function* _addTagsWithProgress(registry, repository, tagsList, progression = 0) { - for await (const partialResult of genericAsyncGenerator($q, tagsList, _addTagFromGenerator, [registry, repository])) { - if (typeof partialResult === 'number') { - yield progression + partialResult; - } else { - yield partialResult; - } - } - } - - /** - * END ADD TAG - */ - - /** - * DELETE MANIFEST - */ - - function deleteManifest(registry, repository, imageDigest) { - const id = registry.Id; - return RegistryManifestsJquery.delete({ - id: id, - repository: repository, - tag: imageDigest, - }); - } - - async function* _deleteManifestsWithProgress(registry, repository, manifests) { - for await (const partialResult of genericAsyncGenerator($q, manifests, deleteManifest, [registry, repository])) { - yield partialResult; - } - } - - /** - * END DELETE MANIFEST - */ - - /** - * SHORT TAG - */ - - function _shortTagFromGenerator(id, repository, tag) { - return new Promise((resolve, reject) => { - RegistryManifestsJquery.getV2({ id: id, repository: repository, tag: tag }) - .then((data) => resolve(new RepositoryShortTag(tag, data.config.digest, data.digest, data))) - .catch((err) => reject(err)); - }); - } - - async function* shortTagsWithProgress(registry, repository, tagsList) { - const id = registry.Id; - yield* genericAsyncGenerator($q, tagsList, _shortTagFromGenerator, [id, repository]); - } - - /** - * END SHORT TAG - */ - - /** - * RETAG - */ - async function* retagWithProgress(registry, repository, modifiedTags, modifiedDigests, impactedTags) { - yield* _deleteManifestsWithProgress(registry, repository, modifiedDigests); - - const newTags = _.map(impactedTags, (item) => { - const tagFromTable = _.find(modifiedTags, { Name: item.Name }); - const name = tagFromTable && tagFromTable.Name !== tagFromTable.NewName ? tagFromTable.NewName : item.Name; - return new RepositoryAddTagPayload(name, item.ManifestV2); - }); - - yield* _addTagsWithProgress(registry, repository, newTags, modifiedDigests.length); - } - - /** - * END RETAG - */ - - /** - * DELETE TAGS - */ - - async function* deleteTagsWithProgress(registry, repository, modifiedDigests, impactedTags) { - yield* _deleteManifestsWithProgress(registry, repository, modifiedDigests); - - const newTags = _.map(impactedTags, (item) => new RepositoryAddTagPayload(item.Name, item.ManifestV2)); - - yield* _addTagsWithProgress(registry, repository, newTags, modifiedDigests.length); - } - - /** - * END DELETE TAGS - */ - - /** - * SERVICE FUNCTIONS DECLARATION - */ - - service.ping = ping; - - service.repositories = repositories; - service.getRepositoriesDetails = getRepositoriesDetails; - - service.tags = tags; - service.tag = tag; - service.getTagsDetails = getTagsDetails; - - service.shortTagsWithProgress = shortTagsWithProgress; - - service.addTag = addTag; - service.deleteManifest = deleteManifest; - - service.deleteTagsWithProgress = deleteTagsWithProgress; - service.retagWithProgress = retagWithProgress; - - return service; - }, -]); diff --git a/app/extensions/registry-management/views/configure/configureRegistryController.js b/app/extensions/registry-management/views/configure/configureRegistryController.js deleted file mode 100644 index 588f26876..000000000 --- a/app/extensions/registry-management/views/configure/configureRegistryController.js +++ /dev/null @@ -1,75 +0,0 @@ -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; -import { RegistryManagementConfigurationDefaultModel } from '../../../../portainer/models/registry'; - -angular.module('portainer.extensions.registrymanagement').controller('ConfigureRegistryController', [ - '$scope', - '$state', - '$transition$', - 'RegistryService', - 'RegistryServiceSelector', - 'Notifications', - function ($scope, $state, $transition$, RegistryService, RegistryServiceSelector, Notifications) { - $scope.state = { - testInProgress: false, - updateInProgress: false, - validConfiguration: false, - }; - - $scope.testConfiguration = testConfiguration; - $scope.updateConfiguration = updateConfiguration; - - function testConfiguration() { - $scope.state.testInProgress = true; - - RegistryService.configureRegistry($scope.registry.Id, $scope.model) - .then(function success() { - return RegistryServiceSelector.ping($scope.registry, true); - }) - .then(function success() { - Notifications.success('Success', 'Valid management configuration'); - $scope.state.validConfiguration = true; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Invalid management configuration'); - }) - .finally(function final() { - $scope.state.testInProgress = false; - }); - } - - function updateConfiguration() { - $scope.state.updateInProgress = true; - - RegistryService.configureRegistry($scope.registry.Id, $scope.model) - .then(function success() { - Notifications.success('Success', 'Registry management configuration updated'); - $state.go('portainer.registries.registry.repositories', { id: $scope.registry.Id }, { reload: true }); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to update registry management configuration'); - }) - .finally(function final() { - $scope.state.updateInProgress = false; - }); - } - - function initView() { - var registryId = $transition$.params().id; - $scope.RegistryTypes = RegistryTypes; - - RegistryService.registry(registryId) - .then(function success(data) { - var registry = data; - var model = new RegistryManagementConfigurationDefaultModel(registry); - - $scope.registry = registry; - $scope.model = model; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to retrieve registry details'); - }); - } - - initView(); - }, -]); diff --git a/app/extensions/registry-management/views/configure/configureregistry.html b/app/extensions/registry-management/views/configure/configureregistry.html deleted file mode 100644 index d515830c0..000000000 --- a/app/extensions/registry-management/views/configure/configureregistry.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - Registries > {{ registry.Name }} > Management configuration - - - -
-
- - -
-
- Information -
-
- - The following configuration will be used to access this registry API to provide Portainer - management features. - -
-
- Registry details -
- -
- -
- -
-
- - -
-
- - -
-
- - -
- -
- -
- -
-
- - -
- -
- -
-
- -
- - -
- -
-
- - -
-
- - -
-
- - -
-
- -
- Required TLS files -
- -
- -
- -
- - - {{ model.TLSCACertFile.name }} - - - -
-
- - -
- -
- - - {{ model.TLSCertFile.name }} - - - -
-
- - -
- -
- - - {{ model.TLSKeyFile.name }} - - - -
-
- -
-
- -
- Actions -
-
-
- - -
-
-
-
-
-
-
diff --git a/app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.html b/app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.html deleted file mode 100644 index 7bb5b7c2d..000000000 --- a/app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.html +++ /dev/null @@ -1,11 +0,0 @@ - - - -

- - {{ $ctrl.resolve.message }} -

-
-   {{ $ctrl.resolve.progressLabel }} : {{ $ctrl.resolve.context.progression }}% - {{ $ctrl.resolve.context.elapsedTime | number: 0 }}s -
-
diff --git a/app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.js b/app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.js deleted file mode 100644 index bc4df86fb..000000000 --- a/app/extensions/registry-management/views/repositories/edit/progression-modal/progressionModal.js +++ /dev/null @@ -1,6 +0,0 @@ -angular.module('portainer.extensions.registrymanagement').component('progressionModal', { - templateUrl: './progressionModal.html', - bindings: { - resolve: '<', - }, -}); diff --git a/app/extensions/registry-management/views/repositories/edit/registryRepository.html b/app/extensions/registry-management/views/repositories/edit/registryRepository.html deleted file mode 100644 index 23ae7a37f..000000000 --- a/app/extensions/registry-management/views/repositories/edit/registryRepository.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - Registries > {{ registry.Name }} > - {{ repository.Name }} - - - -
- - -

- - Portainer needs to retrieve additional information to enable tags modifications (addition, removal, rename) and repository removal features.
- As this repository contains more than {{ state.tagsRetrieval.limit }} tags, the additional retrieval wasn't started automatically.
- Once started you can still navigate this page, leaving the page will cancel the retrieval process.
-
- Note: on very large repositories or high latency environments the retrieval process can take a few minutes. -

- - -
- -   Retrieval progress : {{ state.tagsRetrieval.progression }}% - {{ state.tagsRetrieval.elapsedTime | number: 0 }}s - - - Retrieval completed in {{ state.tagsRetrieval.elapsedTime | number: 0 }}s - -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - -
Repository - {{ repository.Name }} - - -
Tags count{{ repository.Tags.length }}
Images count{{ short.Images.length }}
-
-
-
- -
- - - -
-
- -
- -
-
-
- - - - {{ $select.selected | trimshasum }} - - - {{ image | trimshasum }} - - -
-
-
- -
-
-
-
-
-
-
- -
-
- - -
-
diff --git a/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js b/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js deleted file mode 100644 index e8ab74f09..000000000 --- a/app/extensions/registry-management/views/repositories/edit/registryRepositoryController.js +++ /dev/null @@ -1,423 +0,0 @@ -import _ from 'lodash-es'; -import { RepositoryShortTag, RepositoryTagViewModel } from '../../../models/repositoryTag'; - -angular.module('portainer.app').controller('RegistryRepositoryController', [ - '$q', - '$async', - '$scope', - '$uibModal', - '$interval', - '$transition$', - '$state', - 'RegistryServiceSelector', - 'RegistryService', - 'ModalService', - 'Notifications', - 'ImageHelper', - function ($q, $async, $scope, $uibModal, $interval, $transition$, $state, RegistryServiceSelector, RegistryService, ModalService, Notifications, ImageHelper) { - $scope.state = { - actionInProgress: false, - loading: false, - tagsRetrieval: { - auto: true, - running: false, - limit: 100, - progression: 0, - elapsedTime: 0, - asyncGenerator: null, - clock: null, - }, - tagsRetag: { - running: false, - progression: 0, - elapsedTime: 0, - asyncGenerator: null, - clock: null, - }, - tagsDelete: { - running: false, - progression: 0, - elapsedTime: 0, - asyncGenerator: null, - clock: null, - }, - }; - $scope.formValues = { - Tag: '', // new tag name on add feature - }; - $scope.tags = []; // RepositoryTagViewModel (for datatable) - $scope.short = { - Tags: [], // RepositoryShortTag - Images: [], // strings extracted from short.Tags - }; - $scope.repository = { - Name: '', - Tags: [], // string list - }; - - function toSeconds(time) { - return time / 1000; - } - function toPercent(progress, total) { - return ((progress / total) * 100).toFixed(); - } - - function openModal(resolve) { - return $uibModal.open({ - component: 'progressionModal', - backdrop: 'static', - keyboard: false, - resolve: resolve, - }); - } - - $scope.paginationAction = function (tags) { - $scope.state.loading = true; - RegistryServiceSelector.getTagsDetails($scope.registry, $scope.repository.Name, tags) - .then(function success(data) { - for (var i = 0; i < data.length; i++) { - var idx = _.findIndex($scope.tags, { Name: data[i].Name }); - if (idx !== -1) { - $scope.tags[idx] = data[i]; - } - } - $scope.state.loading = false; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to retrieve tags details'); - }); - }; - - /** - * RETRIEVAL SECTION - */ - function updateRetrievalClock(startTime) { - $scope.state.tagsRetrieval.elapsedTime = toSeconds(Date.now() - startTime); - } - - function createRetrieveAsyncGenerator() { - $scope.state.tagsRetrieval.asyncGenerator = RegistryServiceSelector.shortTagsWithProgress($scope.registry, $scope.repository.Name, $scope.repository.Tags); - } - - function resetTagsRetrievalState() { - $scope.state.tagsRetrieval.running = false; - $scope.state.tagsRetrieval.progression = 0; - $scope.state.tagsRetrieval.elapsedTime = 0; - $scope.state.tagsRetrieval.clock = null; - } - - function computeImages() { - const images = _.map($scope.short.Tags, 'ImageId'); - $scope.short.Images = _.without(_.uniq(images), ''); - } - - $scope.startStopRetrieval = function () { - if ($scope.state.tagsRetrieval.running) { - $scope.state.tagsRetrieval.asyncGenerator.return(); - $interval.cancel($scope.state.tagsRetrieval.clock); - } else { - retrieveTags().then(() => { - createRetrieveAsyncGenerator(); - if ($scope.short.Tags.length === 0) { - resetTagsRetrievalState(); - } else { - computeImages(); - } - }); - } - }; - - function retrieveTags() { - return $async(retrieveTagsAsync); - } - - async function retrieveTagsAsync() { - $scope.state.tagsRetrieval.running = true; - const startTime = Date.now(); - $scope.state.tagsRetrieval.clock = $interval(updateRetrievalClock, 1000, 0, true, startTime); - for await (const partialResult of $scope.state.tagsRetrieval.asyncGenerator) { - if (typeof partialResult === 'number') { - $scope.state.tagsRetrieval.progression = toPercent(partialResult, $scope.repository.Tags.length); - } else { - $scope.short.Tags = _.sortBy(partialResult, 'Name'); - } - } - $scope.state.tagsRetrieval.running = false; - $interval.cancel($scope.state.tagsRetrieval.clock); - } - /** - * !END RETRIEVAL SECTION - */ - - /** - * ADD TAG SECTION - */ - - async function addTagAsync() { - try { - $scope.state.actionInProgress = true; - if (!ImageHelper.isValidTag($scope.formValues.Tag)) { - throw { msg: 'Invalid tag pattern, see info for more details on format.' }; - } - const tag = $scope.short.Tags.find((item) => item.ImageId === $scope.formValues.SelectedImage); - const manifest = tag.ManifestV2; - await RegistryServiceSelector.addTag($scope.registry, $scope.repository.Name, $scope.formValues.Tag, manifest); - - Notifications.success('Success', 'Tag successfully added'); - $scope.short.Tags.push(new RepositoryShortTag($scope.formValues.Tag, tag.ImageId, tag.ImageDigest, tag.ManifestV2)); - - await loadRepositoryDetails(); - $scope.formValues.Tag = ''; - delete $scope.formValues.SelectedImage; - } catch (err) { - Notifications.error('Failure', err, 'Unable to add tag'); - } finally { - $scope.state.actionInProgress = false; - } - } - - $scope.addTag = function () { - return $async(addTagAsync); - }; - /** - * !END ADD TAG SECTION - */ - - /** - * RETAG SECTION - */ - function updateRetagClock(startTime) { - $scope.state.tagsRetag.elapsedTime = toSeconds(Date.now() - startTime); - } - - function createRetagAsyncGenerator(modifiedTags, modifiedDigests, impactedTags) { - $scope.state.tagsRetag.asyncGenerator = RegistryServiceSelector.retagWithProgress($scope.registry, $scope.repository.Name, modifiedTags, modifiedDigests, impactedTags); - } - - async function retagActionAsync() { - let modal = null; - try { - $scope.state.tagsRetag.running = true; - - const modifiedTags = _.filter($scope.tags, (item) => item.Modified === true); - for (const tag of modifiedTags) { - if (!ImageHelper.isValidTag(tag.NewName)) { - throw { msg: 'Invalid tag pattern, see info for more details on format.' }; - } - } - modal = await openModal({ - message: () => 'Retag is in progress! Closing your browser or refreshing the page while this operation is in progress will result in loss of tags.', - progressLabel: () => 'Retag progress', - context: () => $scope.state.tagsRetag, - }); - const modifiedDigests = _.uniq(_.map(modifiedTags, 'ImageDigest')); - const impactedTags = _.filter($scope.short.Tags, (item) => _.includes(modifiedDigests, item.ImageDigest)); - - const totalOps = modifiedDigests.length + impactedTags.length; - - createRetagAsyncGenerator(modifiedTags, modifiedDigests, impactedTags); - - const startTime = Date.now(); - $scope.state.tagsRetag.clock = $interval(updateRetagClock, 1000, 0, true, startTime); - for await (const partialResult of $scope.state.tagsRetag.asyncGenerator) { - if (typeof partialResult === 'number') { - $scope.state.tagsRetag.progression = toPercent(partialResult, totalOps); - } - } - - _.map(modifiedTags, (item) => { - const idx = _.findIndex($scope.short.Tags, (i) => i.Name === item.Name); - $scope.short.Tags[idx].Name = item.NewName; - }); - - Notifications.success('Success', 'Tags successfully renamed'); - - await loadRepositoryDetails(); - } catch (err) { - Notifications.error('Failure', err, 'Unable to rename tags'); - } finally { - $interval.cancel($scope.state.tagsRetag.clock); - $scope.state.tagsRetag.running = false; - if (modal) { - modal.close(); - } - } - } - - $scope.retagAction = function () { - return $async(retagActionAsync); - }; - /** - * !END RETAG SECTION - */ - - /** - * REMOVE TAGS SECTION - */ - - function updateDeleteClock(startTime) { - $scope.state.tagsDelete.elapsedTime = toSeconds(Date.now() - startTime); - } - - function createDeleteAsyncGenerator(modifiedDigests, impactedTags) { - $scope.state.tagsDelete.asyncGenerator = RegistryServiceSelector.deleteTagsWithProgress($scope.registry, $scope.repository.Name, modifiedDigests, impactedTags); - } - - async function removeTagsAsync(selectedTags) { - let modal = null; - try { - $scope.state.tagsDelete.running = true; - modal = await openModal({ - message: () => 'Tag delete is in progress! Closing your browser or refreshing the page while this operation is in progress will result in loss of tags.', - progressLabel: () => 'Deletion progress', - context: () => $scope.state.tagsDelete, - }); - - const deletedTagNames = _.map(selectedTags, 'Name'); - const deletedShortTags = _.filter($scope.short.Tags, (item) => _.includes(deletedTagNames, item.Name)); - const modifiedDigests = _.uniq(_.map(deletedShortTags, 'ImageDigest')); - const impactedTags = _.filter($scope.short.Tags, (item) => _.includes(modifiedDigests, item.ImageDigest)); - const tagsToKeep = _.without(impactedTags, ...deletedShortTags); - - const totalOps = modifiedDigests.length + tagsToKeep.length; - - createDeleteAsyncGenerator(modifiedDigests, tagsToKeep); - - const startTime = Date.now(); - $scope.state.tagsDelete.clock = $interval(updateDeleteClock, 1000, 0, true, startTime); - for await (const partialResult of $scope.state.tagsDelete.asyncGenerator) { - if (typeof partialResult === 'number') { - $scope.state.tagsDelete.progression = toPercent(partialResult, totalOps); - } - } - - _.pull($scope.short.Tags, ...deletedShortTags); - $scope.short.Images = _.map(_.uniqBy($scope.short.Tags, 'ImageId'), 'ImageId'); - - Notifications.success('Success', 'Tags successfully deleted'); - - if ($scope.short.Tags.length === 0) { - $state.go('portainer.registries.registry.repositories', { id: $scope.registry.Id }, { reload: true }); - } - await loadRepositoryDetails(); - } catch (err) { - Notifications.error('Failure', err, 'Unable to delete tags'); - } finally { - $interval.cancel($scope.state.tagsDelete.clock); - $scope.state.tagsDelete.running = false; - modal.close(); - } - } - - $scope.removeTags = function (selectedItems) { - ModalService.confirmDeletion('Are you sure you want to remove the selected tags ?', (confirmed) => { - if (!confirmed) { - return; - } - return $async(removeTagsAsync, selectedItems); - }); - }; - /** - * !END REMOVE TAGS SECTION - */ - - /** - * REMOVE REPOSITORY SECTION - */ - async function removeRepositoryAsync() { - try { - const digests = _.uniqBy($scope.short.Tags, 'ImageDigest'); - const promises = []; - _.map(digests, (item) => promises.push(RegistryServiceSelector.deleteManifest($scope.registry, $scope.repository.Name, item.ImageDigest))); - await Promise.all(promises); - Notifications.success('Success', 'Repository sucessfully removed'); - $state.go('portainer.registries.registry.repositories', { id: $scope.registry.Id }, { reload: true }); - } catch (err) { - Notifications.error('Failure', err, 'Unable to delete repository'); - } - } - - $scope.removeRepository = function () { - ModalService.confirmDeletion( - 'This action will only remove the manifests linked to this repository. You need to manually trigger a garbage collector pass on your registry to remove orphan layers and really remove the images content. THIS ACTION CAN NOT BE UNDONE', - function onConfirm(confirmed) { - if (!confirmed) { - return; - } - return $async(removeRepositoryAsync); - } - ); - }; - /** - * !END REMOVE REPOSITORY SECTION - */ - - /** - * INIT SECTION - */ - async function loadRepositoryDetails() { - try { - const registry = $scope.registry; - const repository = $scope.repository.Name; - const tags = await RegistryServiceSelector.tags(registry, repository); - $scope.tags = []; - $scope.repository.Tags = []; - $scope.repository.Tags = _.sortBy(_.concat($scope.repository.Tags, _.without(tags.tags, null))); - _.map($scope.repository.Tags, (item) => $scope.tags.push(new RepositoryTagViewModel(item))); - } catch (err) { - Notifications.error('Failure', err, 'Unable to retrieve tags details'); - } - } - - async function initView() { - try { - const registryId = $transition$.params().id; - $scope.repository.Name = $transition$.params().repository; - $scope.state.loading = true; - - $scope.registry = await RegistryService.registry(registryId); - await loadRepositoryDetails(); - if ($scope.repository.Tags.length > $scope.state.tagsRetrieval.limit) { - $scope.state.tagsRetrieval.auto = false; - } - createRetrieveAsyncGenerator(); - } catch (err) { - Notifications.error('Failure', err, 'Unable to retrieve repository information'); - } finally { - $scope.state.loading = false; - } - } - - $scope.$on('$destroy', () => { - if ($scope.state.tagsRetrieval.asyncGenerator) { - $scope.state.tagsRetrieval.asyncGenerator.return(); - } - if ($scope.state.tagsRetrieval.clock) { - $interval.cancel($scope.state.tagsRetrieval.clock); - } - if ($scope.state.tagsRetag.asyncGenerator) { - $scope.state.tagsRetag.asyncGenerator.return(); - } - if ($scope.state.tagsRetag.clock) { - $interval.cancel($scope.state.tagsRetag.clock); - } - if ($scope.state.tagsDelete.asyncGenerator) { - $scope.state.tagsDelete.asyncGenerator.return(); - } - if ($scope.state.tagsDelete.clock) { - $interval.cancel($scope.state.tagsDelete.clock); - } - }); - - this.$onInit = function () { - return $async(initView).then(() => { - if ($scope.state.tagsRetrieval.auto) { - $scope.startStopRetrieval(); - } - }); - }; - /** - * !END INIT SECTION - */ - }, -]); diff --git a/app/extensions/registry-management/views/repositories/registryRepositories.html b/app/extensions/registry-management/views/repositories/registryRepositories.html deleted file mode 100644 index 191089dad..000000000 --- a/app/extensions/registry-management/views/repositories/registryRepositories.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - Registries > - {{ registry.Name }}{{ registry.Name }} > Repositories - - - -
- - -

- - Portainer was not able to use this registry management features. You might need to update the configuration used by Portainer to access this registry. -

-

Note: Portainer registry management features are only supported with registries exposing the - v2 registry API.

-
- Configure this registry -
-
-
-
- -
-
- - -
-
diff --git a/app/extensions/registry-management/views/repositories/registryRepositoriesController.js b/app/extensions/registry-management/views/repositories/registryRepositoriesController.js deleted file mode 100644 index 00ad8b0cb..000000000 --- a/app/extensions/registry-management/views/repositories/registryRepositoriesController.js +++ /dev/null @@ -1,68 +0,0 @@ -import _ from 'lodash-es'; - -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; - -angular.module('portainer.extensions.registrymanagement').controller('RegistryRepositoriesController', [ - '$transition$', - '$scope', - 'RegistryService', - 'RegistryServiceSelector', - 'Notifications', - 'Authentication', - function ($transition$, $scope, RegistryService, RegistryServiceSelector, Notifications, Authentication) { - $scope.state = { - displayInvalidConfigurationMessage: false, - loading: false, - }; - - $scope.paginationAction = function (repositories) { - if ($scope.registry.Type === RegistryTypes.GITLAB) { - return; - } - $scope.state.loading = true; - RegistryServiceSelector.getRepositoriesDetails($scope.registry, repositories) - .then(function success(data) { - for (var i = 0; i < data.length; i++) { - var idx = _.findIndex($scope.repositories, { Name: data[i].Name }); - if (idx !== -1) { - if (data[i].TagsCount === 0) { - $scope.repositories.splice(idx, 1); - } else { - $scope.repositories[idx].TagsCount = data[i].TagsCount; - } - } - } - $scope.state.loading = false; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to retrieve repositories details'); - }); - }; - - function initView() { - const registryId = $transition$.params().id; - - $scope.isAdmin = Authentication.isAdmin(); - - RegistryService.registry(registryId) - .then(function success(data) { - $scope.registry = data; - RegistryServiceSelector.ping($scope.registry, false) - .then(function success() { - return RegistryServiceSelector.repositories($scope.registry); - }) - .then(function success(data) { - $scope.repositories = data; - }) - .catch(function error() { - $scope.state.displayInvalidConfigurationMessage = true; - }); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to retrieve registry details'); - }); - } - - initView(); - }, -]); diff --git a/app/extensions/registry-management/views/repositories/tag/registryRepositoryTag.html b/app/extensions/registry-management/views/repositories/tag/registryRepositoryTag.html deleted file mode 100644 index 881649b9d..000000000 --- a/app/extensions/registry-management/views/repositories/tag/registryRepositoryTag.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - Registries > {{ ctrl.registry.Name }} > - {{ ctrl.context.repository }} > - {{ ctrl.context.tag }} - - - -
-
- - - -
-
-
-
-
- {{ tag }} -
-
-
-
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
ID - {{ ctrl.details.Id }} -
Parent{{ ctrl.details.Parent }}
Created{{ ctrl.details.Created | getisodate }}
BuildDocker {{ ctrl.details.DockerVersion }} on {{ ctrl.details.Os }}, {{ ctrl.details.Architecture }}
Author{{ ctrl.details.Author }}
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
CMD{{ ctrl.details.Command | command }}
ENTRYPOINT{{ ctrl.details.Entrypoint | command }}
EXPOSE - - {{ port }} - -
VOLUME - - {{ volume }} - -
ENV - - - - - -
{{ var|key: '=' }}{{ var|value: '=' }}
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - -
- - Order - - - - - - Layer - - - -
- {{ layer.Order }} - -
- - - {{ layer.CreatedBy | truncate: 130 }} - - - - - - -
-
- - {{ layer.CreatedBy }} - -
-
-
-
-
-
diff --git a/app/extensions/registry-management/views/repositories/tag/registryRepositoryTagController.js b/app/extensions/registry-management/views/repositories/tag/registryRepositoryTagController.js deleted file mode 100644 index d2a878a74..000000000 --- a/app/extensions/registry-management/views/repositories/tag/registryRepositoryTagController.js +++ /dev/null @@ -1,56 +0,0 @@ -import _ from 'lodash-es'; -import angular from 'angular'; -import { RegistryImageLayerViewModel } from 'Extensions/registry-management/models/registryImageLayer'; -import { RegistryImageDetailsViewModel } from 'Extensions/registry-management/models/registryImageDetails'; - -class RegistryRepositoryTagController { - /* @ngInject */ - constructor($transition$, $async, Notifications, RegistryService, RegistryServiceSelector, imagelayercommandFilter) { - this.$transition$ = $transition$; - this.$async = $async; - this.Notifications = Notifications; - this.RegistryService = RegistryService; - this.RegistryServiceSelector = RegistryServiceSelector; - this.imagelayercommandFilter = imagelayercommandFilter; - - this.context = {}; - this.onInit = this.onInit.bind(this); - } - - toggleLayerCommand(layerId) { - $('#layer-command-expander' + layerId + ' span').toggleClass('glyphicon-plus-sign glyphicon-minus-sign'); - $('#layer-command-' + layerId + '-short').toggle(); - $('#layer-command-' + layerId + '-full').toggle(); - } - - order(sortType) { - this.Sort.Reverse = this.Sort.Type === sortType ? !this.Sort.Reverse : false; - this.Sort.Type = sortType; - } - - async onInit() { - this.context.registryId = this.$transition$.params().id; - this.context.repository = this.$transition$.params().repository; - this.context.tag = this.$transition$.params().tag; - this.Sort = { - Type: 'Order', - Reverse: false, - }; - try { - this.registry = await this.RegistryService.registry(this.context.registryId); - this.tag = await this.RegistryServiceSelector.tag(this.registry, this.context.repository, this.context.tag); - const length = this.tag.History.length; - this.history = _.map(this.tag.History, (layer, idx) => new RegistryImageLayerViewModel(length - idx, layer)); - _.forEach(this.history, (item) => (item.CreatedBy = this.imagelayercommandFilter(item.CreatedBy))); - this.details = new RegistryImageDetailsViewModel(this.tag.History[0]); - } catch (error) { - this.Notifications.error('Failure', error, 'Unable to retrieve tag'); - } - } - - $onInit() { - return this.$async(this.onInit); - } -} -export default RegistryRepositoryTagController; -angular.module('portainer.extensions.registrymanagement').controller('RegistryRepositoryTagController', RegistryRepositoryTagController); diff --git a/app/portainer/components/datatables/registries-datatable/registriesDatatable.html b/app/portainer/components/datatables/registries-datatable/registriesDatatable.html index bde459875..342102e5e 100644 --- a/app/portainer/components/datatables/registries-datatable/registriesDatatable.html +++ b/app/portainer/components/datatables/registries-datatable/registriesDatatable.html @@ -66,21 +66,6 @@ Manage access - - Browse - - - Browse (extension) - diff --git a/app/portainer/components/datatables/registries-datatable/registriesDatatable.js b/app/portainer/components/datatables/registries-datatable/registriesDatatable.js index 98b342f07..f4df3c5a8 100644 --- a/app/portainer/components/datatables/registries-datatable/registriesDatatable.js +++ b/app/portainer/components/datatables/registries-datatable/registriesDatatable.js @@ -10,7 +10,6 @@ angular.module('portainer.app').component('registriesDatatable', { reverseOrder: '<', accessManagement: '<', removeAction: '<', - registryManagement: '<', canBrowse: '<', }, }); diff --git a/app/portainer/components/forms/registry-form-gitlab/registry-form-gitlab.html b/app/portainer/components/forms/registry-form-gitlab/registry-form-gitlab.html index f540d3add..2b64020d4 100644 --- a/app/portainer/components/forms/registry-form-gitlab/registry-form-gitlab.html +++ b/app/portainer/components/forms/registry-form-gitlab/registry-form-gitlab.html @@ -8,10 +8,6 @@ For information on how to generate a Gitlab Personal Access Token, follow the gitlab guide.

-

- You must provide a token with api scope. Failure to do so - will mean you can only push/pull from your registry but not manage it using the registry management (extension). -

diff --git a/app/extensions/registry-management/models/gitlabRegistry.js b/app/portainer/models/gitlabRegistry.js similarity index 100% rename from app/extensions/registry-management/models/gitlabRegistry.js rename to app/portainer/models/gitlabRegistry.js diff --git a/app/portainer/models/registry.js b/app/portainer/models/registry.js index 640271294..54bf040c2 100644 --- a/app/portainer/models/registry.js +++ b/app/portainer/models/registry.js @@ -1,5 +1,5 @@ import _ from 'lodash-es'; -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; +import { RegistryTypes } from '@/portainer/models/registryTypes'; export function RegistryViewModel(data) { this.Id = data.Id; diff --git a/app/extensions/registry-management/models/registryRepository.js b/app/portainer/models/registryRepository.js similarity index 100% rename from app/extensions/registry-management/models/registryRepository.js rename to app/portainer/models/registryRepository.js diff --git a/app/extensions/registry-management/models/registryTypes.js b/app/portainer/models/registryTypes.js similarity index 100% rename from app/extensions/registry-management/models/registryTypes.js rename to app/portainer/models/registryTypes.js diff --git a/app/extensions/registry-management/rest/gitlab.js b/app/portainer/rest/gitlab.js similarity index 92% rename from app/extensions/registry-management/rest/gitlab.js rename to app/portainer/rest/gitlab.js index 5616cba6d..1418a4cb9 100644 --- a/app/extensions/registry-management/rest/gitlab.js +++ b/app/portainer/rest/gitlab.js @@ -1,6 +1,6 @@ import gitlabResponseGetLink from './transform/gitlabResponseGetLink'; -angular.module('portainer.extensions.registrymanagement').factory('Gitlab', [ +angular.module('portainer.app').factory('Gitlab', [ '$resource', 'API_ENDPOINT_REGISTRIES', function GitlabFactory($resource, API_ENDPOINT_REGISTRIES) { diff --git a/app/extensions/registry-management/rest/transform/gitlabResponseGetLink.js b/app/portainer/rest/transform/gitlabResponseGetLink.js similarity index 100% rename from app/extensions/registry-management/rest/transform/gitlabResponseGetLink.js rename to app/portainer/rest/transform/gitlabResponseGetLink.js diff --git a/app/portainer/services/api/registryService.js b/app/portainer/services/api/registryService.js index b59280d50..d1468c91e 100644 --- a/app/portainer/services/api/registryService.js +++ b/app/portainer/services/api/registryService.js @@ -1,6 +1,6 @@ import _ from 'lodash-es'; import { PorImageRegistryModel } from 'Docker/models/porImageRegistry'; -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; +import { RegistryTypes } from '@/portainer/models/registryTypes'; import { RegistryCreateRequest, RegistryViewModel } from '../../models/registry'; angular.module('portainer.app').factory('RegistryService', [ diff --git a/app/extensions/registry-management/services/registryGitlabService.js b/app/portainer/services/registryGitlabService.js similarity index 96% rename from app/extensions/registry-management/services/registryGitlabService.js rename to app/portainer/services/registryGitlabService.js index 657579eb9..f1115cbf2 100644 --- a/app/extensions/registry-management/services/registryGitlabService.js +++ b/app/portainer/services/registryGitlabService.js @@ -2,7 +2,7 @@ import _ from 'lodash-es'; import { RegistryGitlabProject } from '../models/gitlabRegistry'; import { RegistryRepositoryGitlabViewModel } from '../models/registryRepository'; -angular.module('portainer.extensions.registrymanagement').factory('RegistryGitlabService', [ +angular.module('portainer.app').factory('RegistryGitlabService', [ '$async', 'Gitlab', function RegistryGitlabServiceFactory($async, Gitlab) { diff --git a/app/portainer/views/registries/create/createRegistryController.js b/app/portainer/views/registries/create/createRegistryController.js index 4cab30dc2..af7b1c181 100644 --- a/app/portainer/views/registries/create/createRegistryController.js +++ b/app/portainer/views/registries/create/createRegistryController.js @@ -1,4 +1,4 @@ -import { RegistryTypes } from 'Extensions/registry-management/models/registryTypes'; +import { RegistryTypes } from '@/portainer/models/registryTypes'; import { RegistryDefaultModel } from '../../../models/registry'; angular.module('portainer.app').controller('CreateRegistryController', [ @@ -7,8 +7,7 @@ angular.module('portainer.app').controller('CreateRegistryController', [ 'RegistryService', 'Notifications', 'RegistryGitlabService', - 'ExtensionService', - function ($scope, $state, RegistryService, Notifications, RegistryGitlabService, ExtensionService) { + function ($scope, $state, RegistryService, Notifications, RegistryGitlabService) { $scope.selectQuayRegistry = selectQuayRegistry; $scope.selectAzureRegistry = selectAzureRegistry; $scope.selectCustomRegistry = selectCustomRegistry; @@ -106,7 +105,6 @@ angular.module('portainer.app').controller('CreateRegistryController', [ function initView() { $scope.RegistryTypes = RegistryTypes; $scope.model = new RegistryDefaultModel(); - ExtensionService.extensionEnabled(ExtensionService.EXTENSIONS.REGISTRY_MANAGEMENT).then((data) => ($scope.registryExtensionEnabled = data)); } initView(); diff --git a/app/portainer/views/registries/registries.html b/app/portainer/views/registries/registries.html index 22f89ade9..451146be2 100644 --- a/app/portainer/views/registries/registries.html +++ b/app/portainer/views/registries/registries.html @@ -81,7 +81,6 @@ order-by="Name" access-management="isAdmin" remove-action="removeAction" - registry-management="registryManagementAvailable" can-browse="canBrowse" >
diff --git a/app/portainer/views/registries/registriesController.js b/app/portainer/views/registries/registriesController.js index 72e9e51eb..c0e40acf8 100644 --- a/app/portainer/views/registries/registriesController.js +++ b/app/portainer/views/registries/registriesController.js @@ -8,9 +8,8 @@ angular.module('portainer.app').controller('RegistriesController', [ 'DockerHubService', 'ModalService', 'Notifications', - 'ExtensionService', 'Authentication', - function ($q, $scope, $state, RegistryService, DockerHubService, ModalService, Notifications, ExtensionService, Authentication) { + function ($q, $scope, $state, RegistryService, DockerHubService, ModalService, Notifications, Authentication) { $scope.state = { actionInProgress: false, }; @@ -75,12 +74,10 @@ angular.module('portainer.app').controller('RegistriesController', [ $q.all({ registries: RegistryService.registries(), dockerhub: DockerHubService.dockerhub(), - registryManagement: ExtensionService.extensionEnabled(ExtensionService.EXTENSIONS.REGISTRY_MANAGEMENT), }) .then(function success(data) { $scope.registries = data.registries; $scope.dockerhub = data.dockerhub; - $scope.registryManagementAvailable = data.registryManagement; $scope.isAdmin = Authentication.isAdmin(); }) .catch(function error(err) {