diff --git a/api/bolt/datastore.go b/api/bolt/datastore.go index 0e94ad157..85273c23b 100644 --- a/api/bolt/datastore.go +++ b/api/bolt/datastore.go @@ -139,6 +139,7 @@ func (store *Store) MigrateData() error { DatabaseVersion: version, EndpointGroupService: store.EndpointGroupService, EndpointService: store.EndpointService, + ExtensionService: store.ExtensionService, ResourceControlService: store.ResourceControlService, SettingsService: store.SettingsService, StackService: store.StackService, diff --git a/api/bolt/migrator/migrate_dbversion16.go b/api/bolt/migrator/migrate_dbversion16.go new file mode 100644 index 000000000..4464a87ce --- /dev/null +++ b/api/bolt/migrator/migrate_dbversion16.go @@ -0,0 +1,19 @@ +package migrator + +func (m *Migrator) updateExtensionsToDBVersion17() error { + legacyExtensions, err := m.extensionService.Extensions() + if err != nil { + return err + } + + for _, extension := range legacyExtensions { + extension.License.Valid = true + + err = m.extensionService.Persist(&extension) + if err != nil { + return err + } + } + + return nil +} diff --git a/api/bolt/migrator/migrator.go b/api/bolt/migrator/migrator.go index 6ec80dcc9..78e452d8a 100644 --- a/api/bolt/migrator/migrator.go +++ b/api/bolt/migrator/migrator.go @@ -5,6 +5,7 @@ import ( "github.com/portainer/portainer" "github.com/portainer/portainer/bolt/endpoint" "github.com/portainer/portainer/bolt/endpointgroup" + "github.com/portainer/portainer/bolt/extension" "github.com/portainer/portainer/bolt/resourcecontrol" "github.com/portainer/portainer/bolt/settings" "github.com/portainer/portainer/bolt/stack" @@ -20,6 +21,7 @@ type ( db *bolt.DB endpointGroupService *endpointgroup.Service endpointService *endpoint.Service + extensionService *extension.Service resourceControlService *resourcecontrol.Service settingsService *settings.Service stackService *stack.Service @@ -35,6 +37,7 @@ type ( DatabaseVersion int EndpointGroupService *endpointgroup.Service EndpointService *endpoint.Service + ExtensionService *extension.Service ResourceControlService *resourcecontrol.Service SettingsService *settings.Service StackService *stack.Service @@ -52,6 +55,7 @@ func NewMigrator(parameters *Parameters) *Migrator { currentDBVersion: parameters.DatabaseVersion, endpointGroupService: parameters.EndpointGroupService, endpointService: parameters.EndpointService, + extensionService: parameters.ExtensionService, resourceControlService: parameters.ResourceControlService, settingsService: parameters.SettingsService, templateService: parameters.TemplateService, @@ -210,5 +214,12 @@ func (m *Migrator) Migrate() error { } } + if m.currentDBVersion < 17 { + err := m.updateExtensionsToDBVersion17() + if err != nil { + return err + } + } + return m.versionService.StoreDBVersion(portainer.DBVersion) } diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index e0a9dd2f9..09e223593 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -486,7 +486,10 @@ func initExtensionManager(fileService portainer.FileService, extensionService po for _, extension := range extensions { err := extensionManager.EnableExtension(&extension, extension.License.LicenseKey) if err != nil { - return nil, err + log.Printf("Unable to enable extension: %s [extension: %s]", err.Error(), extension.Name) + extension.Enabled = false + extension.License.Valid = false + extensionService.Persist(&extension) } } diff --git a/api/exec/extension.go b/api/exec/extension.go index 20cf2eca8..cb58ecad6 100644 --- a/api/exec/extension.go +++ b/api/exec/extension.go @@ -113,6 +113,7 @@ func (manager *ExtensionManager) EnableExtension(extension *portainer.Extension, LicenseKey: licenseKey, Company: licenseDetails[0], Expiration: licenseDetails[1], + Valid: true, } extension.Version = licenseDetails[2] diff --git a/api/http/handler/extensions/extension_create.go b/api/http/handler/extensions/extension_create.go index b0ce72406..22d146f6e 100644 --- a/api/http/handler/extensions/extension_create.go +++ b/api/http/handler/extensions/extension_create.go @@ -42,7 +42,7 @@ func (handler *Handler) extensionCreate(w http.ResponseWriter, r *http.Request) } for _, existingExtension := range extensions { - if existingExtension.ID == extensionID { + if existingExtension.ID == extensionID && existingExtension.Enabled { return &httperror.HandlerError{http.StatusConflict, "Unable to enable extension", portainer.ErrExtensionAlreadyEnabled} } } diff --git a/api/http/handler/extensions/extension_list.go b/api/http/handler/extensions/extension_list.go index 392822528..68d26a7e7 100644 --- a/api/http/handler/extensions/extension_list.go +++ b/api/http/handler/extensions/extension_list.go @@ -42,6 +42,7 @@ func associateExtensionData(definition *portainer.Extension, extensions []portai definition.Enabled = extension.Enabled definition.License.Company = extension.License.Company definition.License.Expiration = extension.License.Expiration + definition.License.Valid = extension.License.Valid definitionVersion := semver.New(definition.Version) extensionVersion := semver.New(extension.Version) diff --git a/api/portainer.go b/api/portainer.go index c8062ed7a..a87d91e6a 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -503,6 +503,7 @@ type ( LicenseKey string `json:"LicenseKey,omitempty"` Company string `json:"Company,omitempty"` Expiration string `json:"Expiration,omitempty"` + Valid bool `json:"Valid,omitempty"` } // CLIService represents a service for managing CLI @@ -780,7 +781,7 @@ const ( // APIVersion is the version number of the Portainer API APIVersion = "1.20.0" // DBVersion is the version number of the Portainer database - DBVersion = 16 + DBVersion = 17 // AssetsServerURL represents the URL of the Portainer asset server AssetsServerURL = "https://portainer-io-assets.sfo2.digitaloceanspaces.com" // MessageOfTheDayURL represents the URL where Portainer MOTD message can be retrieved diff --git a/app/portainer/components/extension-list/extension-item/extensionItem.html b/app/portainer/components/extension-list/extension-item/extensionItem.html index 95acdb9cb..18a41ccc4 100644 --- a/app/portainer/components/extension-list/extension-item/extensionItem.html +++ b/app/portainer/components/extension-list/extension-item/extensionItem.html @@ -21,10 +21,10 @@ coming soon - deal - expired - enabled - update available + deal + expired + enabled + update available diff --git a/app/portainer/components/extension-list/extension-item/extensionItemController.js b/app/portainer/components/extension-list/extension-item/extensionItemController.js index 810e93990..841aadc5a 100644 --- a/app/portainer/components/extension-list/extension-item/extensionItemController.js +++ b/app/portainer/components/extension-list/extension-item/extensionItemController.js @@ -3,7 +3,6 @@ angular.module('portainer.app') function($state) { var ctrl = this; - ctrl.$onInit = $onInit; ctrl.goToExtensionView = goToExtensionView; function goToExtensionView() { @@ -11,10 +10,4 @@ angular.module('portainer.app') $state.go('portainer.extensions.extension', { id: ctrl.model.Id }); } } - - function $onInit() { - if (ctrl.currentDate === ctrl.model.License.Expiration) { - ctrl.model.Expired = true; - } - } }]); diff --git a/app/portainer/components/product-list/product-item/productItem.html b/app/portainer/components/product-list/product-item/productItem.html index fa72a7092..b4ac46d6b 100644 --- a/app/portainer/components/product-list/product-item/productItem.html +++ b/app/portainer/components/product-list/product-item/productItem.html @@ -3,7 +3,7 @@
@@ -15,11 +15,6 @@ {{ $ctrl.model.Name }} - - expired - enabled - update available -
@@ -29,9 +24,6 @@ {{ $ctrl.model.ShortDescription }} - - Licensed to {{ $ctrl.model.License.Company }} - Expires on {{ $ctrl.model.License.Expiration }} - diff --git a/app/portainer/views/extensions/inspect/extension.html b/app/portainer/views/extensions/inspect/extension.html index 0a83740d9..df59e2966 100644 --- a/app/portainer/views/extensions/inspect/extension.html +++ b/app/portainer/views/extensions/inspect/extension.html @@ -36,7 +36,9 @@
- {{ extension.Enabled ? 'Enabled' : extension.Price }} + Enabled + Expired + {{ extension.Price }}