From 9cdc0da615268467b1affd0d3d12e68caecec9cd Mon Sep 17 00:00:00 2001 From: Ali <83188384+testA113@users.noreply.github.com> Date: Thu, 1 Dec 2022 13:46:23 +1300 Subject: [PATCH] feat(kompose): hide kompose [EE-4562] (#8084) --- .../test_data/output_24_to_latest.json | 1 + api/http/handler/settings/settings_public.go | 3 ++ api/http/handler/settings/settings_update.go | 6 +++ api/portainer.go | 2 + .../create/createApplication.html | 8 +++ .../views/deploy/deployController.js | 16 ++++-- app/portainer/models/settings.js | 2 + app/portainer/views/settings/settings.html | 10 ++++ .../views/settings/settingsController.js | 49 ++++++++++++++++++- 9 files changed, 92 insertions(+), 5 deletions(-) diff --git a/api/datastore/test_data/output_24_to_latest.json b/api/datastore/test_data/output_24_to_latest.json index 96b0daa75..14dc4db67 100644 --- a/api/datastore/test_data/output_24_to_latest.json +++ b/api/datastore/test_data/output_24_to_latest.json @@ -640,6 +640,7 @@ "Scopes": "", "UserIdentifier": "" }, + "ShowKomposeBuildOption": false, "SnapshotInterval": "5m", "TemplatesURL": "https://raw.githubusercontent.com/portainer/templates/master/templates-2.0.json", "TrustOnFirstConnect": false, diff --git a/api/http/handler/settings/settings_public.go b/api/http/handler/settings/settings_public.go index 96191f983..dcbf636ef 100644 --- a/api/http/handler/settings/settings_public.go +++ b/api/http/handler/settings/settings_public.go @@ -16,6 +16,8 @@ type publicSettingsResponse struct { AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod" example:"1"` // The minimum required length for a password of any user when using internal auth mode RequiredPasswordLength int `json:"RequiredPasswordLength" example:"1"` + // Show the Kompose build option (discontinued in 2.18) + ShowKomposeBuildOption bool `json:"ShowKomposeBuildOption" example:"false"` // Whether edge compute features are enabled EnableEdgeComputeFeatures bool `json:"EnableEdgeComputeFeatures" example:"true"` // Supported feature flags @@ -70,6 +72,7 @@ func generatePublicSettings(appSettings *portainer.Settings) *publicSettingsResp AuthenticationMethod: appSettings.AuthenticationMethod, RequiredPasswordLength: appSettings.InternalAuthSettings.RequiredPasswordLength, EnableEdgeComputeFeatures: appSettings.EnableEdgeComputeFeatures, + ShowKomposeBuildOption: appSettings.ShowKomposeBuildOption, EnableTelemetry: appSettings.EnableTelemetry, KubeconfigExpiry: appSettings.KubeconfigExpiry, Features: appSettings.FeatureFlagSettings, diff --git a/api/http/handler/settings/settings_update.go b/api/http/handler/settings/settings_update.go index 0d6544f09..e4ddf81b0 100644 --- a/api/http/handler/settings/settings_update.go +++ b/api/http/handler/settings/settings_update.go @@ -32,6 +32,8 @@ type settingsUpdatePayload struct { TemplatesURL *string `example:"https://raw.githubusercontent.com/portainer/templates/master/templates.json"` // The default check in interval for edge agent (in seconds) EdgeAgentCheckinInterval *int `example:"5"` + // Show the Kompose build option (discontinued in 2.18) + ShowKomposeBuildOption *bool `json:"ShowKomposeBuildOption" example:"false"` // Whether edge compute features are enabled EnableEdgeComputeFeatures *bool `example:"true"` // The duration of a user session @@ -131,6 +133,10 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) * settings.TemplatesURL = *payload.TemplatesURL } + if payload.ShowKomposeBuildOption != nil { + settings.ShowKomposeBuildOption = *payload.ShowKomposeBuildOption + } + if payload.HelmRepositoryURL != nil { if *payload.HelmRepositoryURL != "" { diff --git a/api/portainer.go b/api/portainer.go index ca5e325a8..2cb11e026 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -857,6 +857,8 @@ type ( TemplatesURL string `json:"TemplatesURL" example:"https://raw.githubusercontent.com/portainer/templates/master/templates.json"` // The default check in interval for edge agent (in seconds) EdgeAgentCheckinInterval int `json:"EdgeAgentCheckinInterval" example:"5"` + // Show the Kompose build option (discontinued in 2.18) + ShowKomposeBuildOption bool `json:"ShowKomposeBuildOption" example:"false"` // Whether edge compute features are enabled EnableEdgeComputeFeatures bool `json:"EnableEdgeComputeFeatures"` // The duration of a user session diff --git a/app/kubernetes/views/applications/create/createApplication.html b/app/kubernetes/views/applications/create/createApplication.html index a10450eaa..75a3dd57b 100644 --- a/app/kubernetes/views/applications/create/createApplication.html +++ b/app/kubernetes/views/applications/create/createApplication.html @@ -108,6 +108,14 @@ You can get more information about Compose file format in the official documentation.
+In a forthcoming Portainer release, we plan to remove support for docker-compose format manifests for Kubernetes deployments, and the Kompose conversion tool + which enables this. The reason for this is because Kompose now poses a security risk, since it has a number of Common Vulnerabilities and Exposures (CVEs).
+Unfortunately, while the Kompose project has a maintainer and is part of the CNCF, it is not being actively maintained. Releases are very infrequent and new + pull requests to the project (including ones we've submitted) are taking months to be merged, with new CVEs arising in the meantime.
diff --git a/app/kubernetes/views/deploy/deployController.js b/app/kubernetes/views/deploy/deployController.js index 9c5aa18c5..d248eaa7a 100644 --- a/app/kubernetes/views/deploy/deployController.js +++ b/app/kubernetes/views/deploy/deployController.js @@ -9,6 +9,7 @@ import { renderTemplate } from '@/react/portainer/custom-templates/components/ut import { isBE } from '@/react/portainer/feature-flags/feature-flags.service'; import { compose, kubernetes } from '@@/BoxSelector/common-options/deployment-methods'; import { editor, git, template, url } from '@@/BoxSelector/common-options/build-methods'; +import { getPublicSettings } from '@/react/portainer/settings/settings.service'; class KubernetesDeployController { /* @ngInject */ @@ -27,10 +28,7 @@ class KubernetesDeployController { this.isTemplateVariablesEnabled = isBE; - this.deployOptions = [ - { ...kubernetes, value: KubernetesDeployManifestTypes.KUBERNETES }, - { ...compose, value: KubernetesDeployManifestTypes.COMPOSE }, - ]; + this.deployOptions = [{ ...kubernetes, value: KubernetesDeployManifestTypes.KUBERNETES }]; this.methodOptions = [ { ...git, value: KubernetesDeployBuildMethods.GIT }, @@ -341,6 +339,16 @@ class KubernetesDeployController { } } + try { + const publicSettings = await getPublicSettings(); + this.showKomposeBuildOption = publicSettings.ShowKomposeBuildOption; + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to get public settings'); + } + if (this.showKomposeBuildOption) { + this.deployOptions = [...this.deployOptions, { ...compose, value: KubernetesDeployManifestTypes.COMPOSE }]; + } + this.state.viewReady = true; this.$window.onbeforeunload = () => { diff --git a/app/portainer/models/settings.js b/app/portainer/models/settings.js index 59b82df04..2e9b1ca02 100644 --- a/app/portainer/models/settings.js +++ b/app/portainer/models/settings.js @@ -20,6 +20,7 @@ export function SettingsViewModel(data) { this.EnforceEdgeID = data.EnforceEdgeID; this.AgentSecret = data.AgentSecret; this.EdgePortainerUrl = data.EdgePortainerUrl; + this.ShowKomposeBuildOption = data.ShowKomposeBuildOption; } export function PublicSettingsViewModel(settings) { @@ -36,6 +37,7 @@ export function PublicSettingsViewModel(settings) { this.Features = settings.Features; this.Edge = new EdgeSettingsViewModel(settings.Edge); this.DefaultRegistry = settings.DefaultRegistry; + this.ShowKomposeBuildOption = settings.ShowKomposeBuildOption; } export function InternalAuthSettingsViewModel(data) { diff --git a/app/portainer/views/settings/settings.html b/app/portainer/views/settings/settings.html index 64ef297c4..440d03274 100644 --- a/app/portainer/views/settings/settings.html +++ b/app/portainer/views/settings/settings.html @@ -184,6 +184,16 @@ tooltip="'Hides the \'Add with form\' buttons and prevents adding/editing of resources via forms'" > +
In a forthcoming Portainer release, we plan to remove support for docker-compose format manifests for Kubernetes deployments, and the Kompose conversion tool which enables this. The reason for this is because Kompose now poses a security risk, since it has a number of Common Vulnerabilities and Exposures (CVEs).
+Unfortunately, while the Kompose project has a maintainer and is part of the CNCF, it is not being actively maintained. Releases are very infrequent and new pull requests to the project (including ones we've submitted) are taking months to be merged, with new CVEs arising in the meantime.
`, + buttons: { + confirm: { + label: 'Ok', + className: 'btn-warning', + }, + }, + callback: function (confirmed) { + $scope.setShowCompose(confirmed); + }, + }); + return; + } + $scope.setShowCompose(checked); + }; + + $scope.setShowCompose = function setShowCompose(checked) { + return $scope.$evalAsync(() => { + $scope.formValues.ShowKomposeBuildOption = checked; + }); + }; + $scope.onToggleAutoBackups = function onToggleAutoBackups(checked) { $scope.$evalAsync(() => { $scope.formValues.scheduleAutomaticBackups = checked; @@ -152,8 +186,13 @@ angular.module('portainer.app').controller('SettingsController', [ KubeconfigExpiry: $scope.formValues.KubeconfigExpiry, HelmRepositoryURL: $scope.formValues.HelmRepositoryURL, GlobalDeploymentOptions: $scope.formValues.GlobalDeploymentOptions, + ShowKomposeBuildOption: $scope.formValues.ShowKomposeBuildOption, }; + if (kubeSettingsPayload.ShowKomposeBuildOption !== $scope.initialFormValues.ShowKomposeBuildOption && $scope.initialFormValues.enableTelemetry) { + trackEvent('kubernetes-allow-compose', { category: 'kubernetes', metadata: { 'kubernetes-allow-compose': kubeSettingsPayload.ShowKomposeBuildOption } }); + } + $scope.state.kubeSettingsActionInProgress = true; updateSettings(kubeSettingsPayload, 'Kubernetes settings updated'); }; @@ -165,6 +204,8 @@ angular.module('portainer.app').controller('SettingsController', [ StateManager.updateLogo(settings.LogoURL); StateManager.updateSnapshotInterval(settings.SnapshotInterval); StateManager.updateEnableTelemetry(settings.EnableTelemetry); + $scope.initialFormValues.ShowKomposeBuildOption = response.ShowKomposeBuildOption; + $scope.initialFormValues.enableTelemetry = response.EnableTelemetry; $scope.formValues.BlackListedLabels = response.BlackListedLabels; }) .catch(function error(err) { @@ -193,6 +234,12 @@ angular.module('portainer.app').controller('SettingsController', [ $scope.formValues.KubeconfigExpiry = settings.KubeconfigExpiry; $scope.formValues.HelmRepositoryURL = settings.HelmRepositoryURL; $scope.formValues.BlackListedLabels = settings.BlackListedLabels; + if (settings.ShowKomposeBuildOption) { + $scope.formValues.ShowKomposeBuildOption = settings.ShowKomposeBuildOption; + } + + $scope.initialFormValues.ShowKomposeBuildOption = settings.ShowKomposeBuildOption; + $scope.initialFormValues.enableTelemetry = settings.EnableTelemetry; }) .catch(function error(err) { Notifications.error('Failure', err, 'Unable to retrieve application settings');