feat(kubernetes): Prevent deployment/edition of resources inside a system namespace (#4039)

* feat(kubernetes): Prevent deployment/edition of resources inside a system namespace

* feat(kubernetes): minor UI update

Co-authored-by: Anthony Lapenna <lapenna.anthony@gmail.com>
pull/4029/head
Maxime Bajeux 2020-07-14 07:39:13 +02:00 committed by GitHub
parent 181a6f4553
commit 8b79f2524d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 5 deletions

View File

@ -37,7 +37,8 @@ class KubernetesCreateApplicationController {
KubernetesStackService, KubernetesStackService,
KubernetesConfigurationService, KubernetesConfigurationService,
KubernetesNodeService, KubernetesNodeService,
KubernetesPersistentVolumeClaimService KubernetesPersistentVolumeClaimService,
KubernetesNamespaceHelper
) { ) {
this.$async = $async; this.$async = $async;
this.$state = $state; this.$state = $state;
@ -51,6 +52,7 @@ class KubernetesCreateApplicationController {
this.KubernetesConfigurationService = KubernetesConfigurationService; this.KubernetesConfigurationService = KubernetesConfigurationService;
this.KubernetesNodeService = KubernetesNodeService; this.KubernetesNodeService = KubernetesNodeService;
this.KubernetesPersistentVolumeClaimService = KubernetesPersistentVolumeClaimService; this.KubernetesPersistentVolumeClaimService = KubernetesPersistentVolumeClaimService;
this.KubernetesNamespaceHelper = KubernetesNamespaceHelper;
this.ApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes; this.ApplicationDeploymentTypes = KubernetesApplicationDeploymentTypes;
this.ApplicationDataAccessPolicies = KubernetesApplicationDataAccessPolicies; this.ApplicationDataAccessPolicies = KubernetesApplicationDataAccessPolicies;
@ -592,7 +594,8 @@ class KubernetesCreateApplicationController {
const [resourcePools, nodes] = await Promise.all([this.KubernetesResourcePoolService.get(), this.KubernetesNodeService.get()]); const [resourcePools, nodes] = await Promise.all([this.KubernetesResourcePoolService.get(), this.KubernetesNodeService.get()]);
this.resourcePools = resourcePools; this.resourcePools = _.filter(resourcePools, (resourcePool) => !this.KubernetesNamespaceHelper.isSystemNamespace(resourcePool.Namespace.Name));
this.formValues.ResourcePool = this.resourcePools[0]; this.formValues.ResourcePool = this.resourcePools[0];
_.forEach(nodes, (item) => { _.forEach(nodes, (item) => {

View File

@ -5,7 +5,7 @@ import { KubernetesConfigurationTypes } from 'Kubernetes/models/configuration/mo
class KubernetesCreateConfigurationController { class KubernetesCreateConfigurationController {
/* @ngInject */ /* @ngInject */
constructor($async, $state, Notifications, Authentication, KubernetesConfigurationService, KubernetesResourcePoolService) { constructor($async, $state, Notifications, Authentication, KubernetesConfigurationService, KubernetesResourcePoolService, KubernetesNamespaceHelper) {
this.$async = $async; this.$async = $async;
this.$state = $state; this.$state = $state;
this.Notifications = Notifications; this.Notifications = Notifications;
@ -13,6 +13,7 @@ class KubernetesCreateConfigurationController {
this.KubernetesConfigurationService = KubernetesConfigurationService; this.KubernetesConfigurationService = KubernetesConfigurationService;
this.KubernetesResourcePoolService = KubernetesResourcePoolService; this.KubernetesResourcePoolService = KubernetesResourcePoolService;
this.KubernetesConfigurationTypes = KubernetesConfigurationTypes; this.KubernetesConfigurationTypes = KubernetesConfigurationTypes;
this.KubernetesNamespaceHelper = KubernetesNamespaceHelper;
this.onInit = this.onInit.bind(this); this.onInit = this.onInit.bind(this);
this.createConfigurationAsync = this.createConfigurationAsync.bind(this); this.createConfigurationAsync = this.createConfigurationAsync.bind(this);
@ -74,7 +75,9 @@ class KubernetesCreateConfigurationController {
this.formValues.Data.push(new KubernetesConfigurationFormValuesDataEntry()); this.formValues.Data.push(new KubernetesConfigurationFormValuesDataEntry());
try { try {
this.resourcePools = await this.KubernetesResourcePoolService.get(); const resourcePools = await this.KubernetesResourcePoolService.get();
this.resourcePools = _.filter(resourcePools, (resourcePool) => !this.KubernetesNamespaceHelper.isSystemNamespace(resourcePool.Namespace.Name));
this.formValues.ResourcePool = this.resourcePools[0]; this.formValues.ResourcePool = this.resourcePools[0];
await this.getConfigurations(); await this.getConfigurations();
} catch (err) { } catch (err) {

View File

@ -76,7 +76,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<rd-widget> <rd-widget>
<rd-widget-body> <rd-widget-body>
<form class="form-horizontal" name="kubernetesConfigurationCreationForm" autocomplete="off"> <form ng-if="!ctrl.isSystemNamespace()" class="form-horizontal" name="kubernetesConfigurationCreationForm" autocomplete="off">
<kubernetes-configuration-data ng-if="ctrl.formValues" form-values="ctrl.formValues" is-valid="ctrl.state.isDataValid"></kubernetes-configuration-data> <kubernetes-configuration-data ng-if="ctrl.formValues" form-values="ctrl.formValues" is-valid="ctrl.state.isDataValid"></kubernetes-configuration-data>
<!-- actions --> <!-- actions -->
@ -99,6 +99,32 @@
</div> </div>
<!-- !actions --> <!-- !actions -->
</form> </form>
<div ng-if="ctrl.isSystemNamespace()">
<div class="col-sm-12 form-section-title" style="margin-top: 10px;">
Data
</div>
<table class="table">
<tbody>
<tr class="text-muted">
<td style="width: 10%; border-top: none;">Key</td>
<td style="width: 90%; border-top: none;">Value</td>
</tr>
<tr ng-repeat="item in ctrl.formValues.Data track by $index">
<td>{{ item.Key }}</td>
<td>
<div style="white-space: pre-wrap;">{{ item.Value }}</div>
<div style="margin-top: 2px;">
<span class="btn btn-primary btn-xs" ng-click="ctrl.copyConfigurationValue($index)"> <i class="fa fa-copy space-right" aria-hidden="true"></i>Copy </span>
<span id="copyValueNotification_{{ $index }}" style="display: none; color: #23ae89; margin-left: 5px;" class="small">
<i class="fa fa-check" aria-hidden="true"></i> copied
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</rd-widget-body> </rd-widget-body>
</rd-widget> </rd-widget>
</div> </div>

View File

@ -10,6 +10,7 @@ class KubernetesConfigurationController {
constructor( constructor(
$async, $async,
$state, $state,
clipboard,
Notifications, Notifications,
LocalStorage, LocalStorage,
KubernetesConfigurationService, KubernetesConfigurationService,
@ -21,6 +22,7 @@ class KubernetesConfigurationController {
) { ) {
this.$async = $async; this.$async = $async;
this.$state = $state; this.$state = $state;
this.clipboard = clipboard;
this.Notifications = Notifications; this.Notifications = Notifications;
this.LocalStorage = LocalStorage; this.LocalStorage = LocalStorage;
this.ModalService = ModalService; this.ModalService = ModalService;
@ -55,6 +57,13 @@ class KubernetesConfigurationController {
this.selectTab(2); this.selectTab(2);
} }
copyConfigurationValue(idx) {
this.clipboard.copyText(this.formValues.Data[idx].Value);
$('#copyValueNotification_' + idx)
.show()
.fadeOut(2500);
}
isFormValid() { isFormValid() {
if (this.formValues.IsSimple) { if (this.formValues.IsSimple) {
return this.formValues.Data.length > 0 && this.state.isDataValid; return this.formValues.Data.length > 0 && this.state.isDataValid;