diff --git a/app/portainer/views/settings/settings.html b/app/portainer/views/settings/settings.html index d3607d216..22a372b9a 100644 --- a/app/portainer/views/settings/settings.html +++ b/app/portainer/views/settings/settings.html @@ -72,7 +72,6 @@ privacy policy. -
-
App Templates
@@ -112,6 +110,35 @@
+ +
+
+ +
+
+ + + + + + + +
+
+ + + +
Helm Repository
@@ -129,7 +156,6 @@
-
Kubernetes
@@ -138,25 +164,40 @@
+ +
Deployment Options
+
+ +
+
@@ -202,7 +243,7 @@ - + {{ label.name }} {{ label.value }} @@ -211,10 +252,10 @@ > - + No filter available. - + Loading... diff --git a/app/portainer/views/settings/settingsController.js b/app/portainer/views/settings/settingsController.js index 64816d1e4..ea4141e70 100644 --- a/app/portainer/views/settings/settingsController.js +++ b/app/portainer/views/settings/settingsController.js @@ -15,6 +15,7 @@ angular.module('portainer.app').controller('SettingsController', [ function ($scope, $state, Notifications, SettingsService, StateManager, BackupService, FileSaver) { $scope.customBannerFeatureId = FeatureId.CUSTOM_LOGIN_BANNER; $scope.s3BackupFeatureId = FeatureId.S3_BACKUP_SETTING; + $scope.enforceDeploymentOptions = FeatureId.ENFORCE_DEPLOYMENT_OPTIONS; $scope.backupOptions = options; @@ -52,6 +53,9 @@ angular.module('portainer.app').controller('SettingsController', [ $scope.formValues = { customLogo: false, + KubeconfigExpiry: undefined, + HelmRepositoryURL: undefined, + BlackListedLabels: [], labelName: '', labelValue: '', enableTelemetry: false, @@ -91,21 +95,20 @@ angular.module('portainer.app').controller('SettingsController', [ }; $scope.removeFilteredContainerLabel = function (index) { - var settings = $scope.settings; - settings.BlackListedLabels.splice(index, 1); - - updateSettings(settings); + const filteredSettings = $scope.formValues.BlackListedLabels.filter((_, i) => i !== index); + const filteredSettingsPayload = { BlackListedLabels: filteredSettings }; + updateSettings(filteredSettingsPayload, 'Hidden container settings updated'); }; $scope.addFilteredContainerLabel = function () { - var settings = $scope.settings; var label = { name: $scope.formValues.labelName, value: $scope.formValues.labelValue, }; - settings.BlackListedLabels.push(label); - updateSettings(settings); + const filteredSettings = [...$scope.formValues.BlackListedLabels, label]; + const filteredSettingsPayload = { BlackListedLabels: filteredSettings }; + updateSettings(filteredSettingsPayload, 'Hidden container settings updated'); }; $scope.downloadBackup = function () { @@ -130,32 +133,45 @@ angular.module('portainer.app').controller('SettingsController', [ }); }; + // only update the values from the app settings widget. In future separate the api endpoints $scope.saveApplicationSettings = function () { - var settings = $scope.settings; - - if (!$scope.formValues.customLogo) { - settings.LogoURL = ''; - } - - settings.EnableTelemetry = $scope.formValues.enableTelemetry; + const appSettingsPayload = { + SnapshotInterval: $scope.settings.SnapshotInterval, + LogoURL: $scope.formValues.customLogo ? $scope.settings.LogoURL : '', + EnableTelemetry: $scope.formValues.enableTelemetry, + TemplatesURL: $scope.settings.TemplatesURL, + }; $scope.state.actionInProgress = true; - updateSettings(settings); + updateSettings(appSettingsPayload, 'Application settings updated'); }; - function updateSettings(settings) { + // only update the values from the kube settings widget. In future separate the api endpoints + $scope.saveKubernetesSettings = function () { + const kubeSettingsPayload = { + KubeconfigExpiry: $scope.formValues.KubeconfigExpiry, + HelmRepositoryURL: $scope.formValues.HelmRepositoryURL, + GlobalDeploymentOptions: $scope.formValues.GlobalDeploymentOptions, + }; + + $scope.state.kubeSettingsActionInProgress = true; + updateSettings(kubeSettingsPayload, 'Kubernetes settings updated'); + }; + + function updateSettings(settings, successMessage = 'Settings updated') { SettingsService.update(settings) - .then(function success() { - Notifications.success('Success', 'Settings updated'); + .then(function success(response) { + Notifications.success('Success', successMessage); StateManager.updateLogo(settings.LogoURL); StateManager.updateSnapshotInterval(settings.SnapshotInterval); StateManager.updateEnableTelemetry(settings.EnableTelemetry); - $state.reload(); + $scope.formValues.BlackListedLabels = response.BlackListedLabels; }) .catch(function error(err) { Notifications.error('Failure', err, 'Unable to update settings'); }) .finally(function final() { + $scope.state.kubeSettingsActionInProgress = false; $scope.state.actionInProgress = false; }); } @@ -172,7 +188,11 @@ angular.module('portainer.app').controller('SettingsController', [ if (settings.LogoURL !== '') { $scope.formValues.customLogo = true; } + $scope.formValues.enableTelemetry = settings.EnableTelemetry; + $scope.formValues.KubeconfigExpiry = settings.KubeconfigExpiry; + $scope.formValues.HelmRepositoryURL = settings.HelmRepositoryURL; + $scope.formValues.BlackListedLabels = settings.BlackListedLabels; }) .catch(function error(err) { Notifications.error('Failure', err, 'Unable to retrieve application settings'); diff --git a/app/react/components/Svg.tsx b/app/react/components/Svg.tsx index 07ab1490d..53dbbbe61 100644 --- a/app/react/components/Svg.tsx +++ b/app/react/components/Svg.tsx @@ -53,6 +53,7 @@ import upload from '@/assets/ico/upload.svg?c'; import url from '@/assets/ico/url.svg?c'; import usercircle from '@/assets/ico/user-circle.svg?c'; import userlock from '@/assets/ico/user-lock.svg?c'; +import kube from '@/assets/ico/kube.svg?c'; import Placeholder from '@/assets/ico/placeholder.svg?c'; // Placeholder is used when an icon name cant be matched // vendor icons import aws from '@/assets/ico/vendor/aws.svg?c'; @@ -152,6 +153,7 @@ export const SvgIcons = { proget, quay, internal, + kube, }; interface SvgProps { diff --git a/app/react/portainer/feature-flags/enums.ts b/app/react/portainer/feature-flags/enums.ts index 0c1343595..7544e8aee 100644 --- a/app/react/portainer/feature-flags/enums.ts +++ b/app/react/portainer/feature-flags/enums.ts @@ -32,5 +32,6 @@ export enum FeatureId { POD_SECURITY_POLICY_CONSTRAINT = 'pod-security-policy-constraint', HIDE_DOCKER_HUB_ANONYMOUS = 'hide-docker-hub-anonymous', CUSTOM_LOGIN_BANNER = 'custom-login-banner', + ENFORCE_DEPLOYMENT_OPTIONS = 'k8s-enforce-deployment-options', K8S_ADM_ONLY_USR_INGRESS_DEPLY = 'k8s-admin-only-ingress-deploy', } diff --git a/app/react/portainer/feature-flags/feature-flags.service.ts b/app/react/portainer/feature-flags/feature-flags.service.ts index cb7f06fb6..c108cac25 100644 --- a/app/react/portainer/feature-flags/feature-flags.service.ts +++ b/app/react/portainer/feature-flags/feature-flags.service.ts @@ -37,6 +37,7 @@ export async function init(edition: Edition) { [FeatureId.POD_SECURITY_POLICY_CONSTRAINT]: Edition.BE, [FeatureId.HIDE_DOCKER_HUB_ANONYMOUS]: Edition.BE, [FeatureId.CUSTOM_LOGIN_BANNER]: Edition.BE, + [FeatureId.ENFORCE_DEPLOYMENT_OPTIONS]: Edition.BE, [FeatureId.K8S_ADM_ONLY_USR_INGRESS_DEPLY]: Edition.BE, };