feat(deployment): enforce deployment options EE-4416 (#7974)

pull/8071/head
Ali 2022-11-17 22:00:34 +13:00 committed by GitHub
parent e0f3a8c0a2
commit d012a4efc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 31 deletions

View File

@ -72,7 +72,6 @@
<a href="https://www.portainer.io/documentation/in-app-analytics-and-privacy-policy/" target="_blank">privacy policy</a>.
</div>
</div>
<!-- login screen banner -->
<div class="form-group">
<por-switch-field
@ -86,7 +85,6 @@
></por-switch-field>
</div>
<!-- !login screen banner -->
<!-- templates -->
<div class="col-sm-12 form-section-title"> App Templates </div>
<div>
@ -112,6 +110,35 @@
</div>
</div>
<!-- !templates -->
<!-- actions -->
<div class="form-group">
<div class="col-sm-12">
<button
type="button"
class="btn btn-primary btn-sm"
ng-click="saveApplicationSettings()"
ng-disabled="state.actionInProgress || !settings.TemplatesURL"
button-spinner="state.actionInProgress"
data-cy="settings-saveSettingsButton"
>
<span ng-hide="state.actionInProgress">Save application settings</span>
<span ng-show="state.actionInProgress">Saving...</span>
</button>
</div>
</div>
<!-- !actions -->
</form>
</rd-widget-body>
</rd-widget>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<rd-widget>
<rd-widget-header icon="svg-kube" feather-icon="true" title-text="Kubernetes settings"></rd-widget-header>
<rd-widget-body>
<form class="form-horizontal">
<!-- helm charts -->
<div class="col-sm-12 form-section-title"> Helm Repository </div>
<div>
@ -129,7 +156,6 @@
</div>
</div>
<!-- !helm charts -->
<!-- host-filesystem -->
<!-- kube -->
<div class="col-sm-12 form-section-title"> Kubernetes </div>
<div class="form-group">
@ -138,25 +164,40 @@
<select
id="kubeconfig_expiry"
class="form-control"
ng-model="settings.KubeconfigExpiry"
ng-model="formValues.KubeconfigExpiry"
ng-options="opt.value as opt.key for opt in state.availableKubeconfigExpiryOptions"
></select>
</div>
</div>
<!-- ! kube -->
<!-- deployment options -->
<div class="col-sm-12 form-section-title"> Deployment Options </div>
<div class="form-group">
<por-switch-field
label="'Enforce code-based deployment'"
name="'toggle_hideAddWithForm'"
feature-id="enforceDeploymentOptions"
disabled="true"
checked="false"
field-class="'col-sm-12'"
label-class="'col-sm-2'"
tooltip="'Hides the \'Add with form\' buttons and prevents adding/editing of resources via forms'"
></por-switch-field>
</div>
<!-- !deployment options -->
<!-- actions -->
<div class="form-group">
<div class="col-sm-12">
<button
type="button"
class="btn btn-primary btn-sm"
ng-click="saveApplicationSettings()"
ng-disabled="state.actionInProgress || !settings.TemplatesURL"
button-spinner="state.actionInProgress"
ng-click="saveKubernetesSettings()"
ng-disabled="state.kubeSettingsActionInProgress"
button-spinner="state.kubeSettingsActionInProgress"
data-cy="settings-saveSettingsButton"
>
<span ng-hide="state.actionInProgress">Save settings</span>
<span ng-show="state.actionInProgress">Saving...</span>
<span ng-hide="state.kubeSettingsActionInProgress">Save Kubernetes settings</span>
<span ng-show="state.kubeSettingsActionInProgress">Saving...</span>
</button>
</div>
</div>
@ -202,7 +243,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="label in settings.BlackListedLabels">
<tr ng-repeat="label in formValues.BlackListedLabels">
<td>{{ label.name }}</td>
<td>{{ label.value }}</td>
<td>
@ -211,10 +252,10 @@
>
</td>
</tr>
<tr ng-if="settings.BlackListedLabels.length === 0">
<tr ng-if="formValues.BlackListedLabels.length === 0">
<td colspan="3" class="text-center text-muted">No filter available.</td>
</tr>
<tr ng-if="!settings.BlackListedLabels">
<tr ng-if="!formValues.BlackListedLabels">
<td colspan="3" class="text-center text-muted">Loading...</td>
</tr>
</tbody>

View File

@ -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');

View File

@ -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 {

View File

@ -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',
}

View File

@ -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,
};