mirror of https://github.com/rancher/dashboard.git
281 lines
7.9 KiB
Vue
281 lines
7.9 KiB
Vue
<script>
|
|
import { mapGetters } from 'vuex';
|
|
import NameNsDescription from '@shell/components/form/NameNsDescription';
|
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
import { MANAGEMENT } from '@shell/config/types';
|
|
import { CONTAINER_DEFAULT_RESOURCE_LIMIT, PROJECT } from '@shell/config/labels-annotations';
|
|
import ContainerResourceLimit from '@shell/components/ContainerResourceLimit';
|
|
import PodSecurityAdmission from '@shell/components/PodSecurityAdmission';
|
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
import ResourceTabs from '@shell/components/form/ResourceTabs/index.vue';
|
|
import CruResource from '@shell/components/CruResource';
|
|
import { PROJECT_ID, _VIEW, FLAT_VIEW, _CREATE } from '@shell/config/query-params';
|
|
import ResourceQuota from '@shell/components/form/ResourceQuota/Namespace';
|
|
import Loading from '@shell/components/Loading';
|
|
import { HARVESTER_TYPES, RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
|
|
import Labels from '@shell/components/form/Labels';
|
|
import { randomStr } from '@shell/utils/string';
|
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
|
|
export default {
|
|
emits: ['input'],
|
|
components: {
|
|
ContainerResourceLimit,
|
|
CruResource,
|
|
LabeledSelect,
|
|
Labels,
|
|
Loading,
|
|
NameNsDescription,
|
|
PodSecurityAdmission,
|
|
ResourceQuota,
|
|
Tab,
|
|
ResourceTabs
|
|
},
|
|
|
|
mixins: [CreateEditView],
|
|
inheritAttrs: false,
|
|
|
|
async fetch() {
|
|
if (this.$store.getters['management/schemaFor'](MANAGEMENT.PROJECT)) {
|
|
this.projects = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PROJECT });
|
|
|
|
this.project = this.projects.find((p) => p.id.includes(this.projectName));
|
|
}
|
|
},
|
|
|
|
data() {
|
|
let originalQuotaId = null;
|
|
|
|
if ( this.liveValue?.metadata?.name ) {
|
|
originalQuotaId = `${ this.liveValue.metadata.name }/default-quota`;
|
|
}
|
|
|
|
const projectName = this.value?.metadata?.labels?.[PROJECT] || this.$route.query[PROJECT_ID];
|
|
|
|
return {
|
|
originalQuotaId,
|
|
project: null,
|
|
projects: null,
|
|
viewMode: _VIEW,
|
|
containerResourceLimits: this.value.annotations?.[CONTAINER_DEFAULT_RESOURCE_LIMIT] || this.getDefaultContainerResourceLimits(projectName),
|
|
rerenderNums: randomStr(4),
|
|
projectName,
|
|
HARVESTER_TYPES,
|
|
RANCHER_TYPES,
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
...mapGetters(['isStandaloneHarvester']),
|
|
|
|
isCreate() {
|
|
return this.mode === _CREATE;
|
|
},
|
|
|
|
projectOpts() {
|
|
const clusterId = this.$store.getters['currentCluster'].id;
|
|
let projects = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
|
|
|
|
// Filter out projects not for the current cluster
|
|
projects = projects.filter((c) => c.spec?.clusterName === clusterId);
|
|
const out = projects.map((project) => {
|
|
return {
|
|
label: project.nameDisplay,
|
|
value: project.metadata.name,
|
|
};
|
|
});
|
|
|
|
out.unshift({
|
|
label: this.t('namespace.project.none'),
|
|
value: null,
|
|
});
|
|
|
|
return out;
|
|
},
|
|
|
|
doneLocationOverride() {
|
|
return this.value.listLocation;
|
|
},
|
|
|
|
showResourceQuota() {
|
|
return (!this.isStandaloneHarvester) && Object.keys(this.project?.spec?.resourceQuota?.limit || {}).length > 0;
|
|
},
|
|
|
|
showContainerResourceLimit() {
|
|
return !this.isStandaloneHarvester;
|
|
},
|
|
|
|
flatView() {
|
|
return (this.$route.query[FLAT_VIEW] || false);
|
|
},
|
|
|
|
showPodSecurityAdmission() {
|
|
return !this.isStandaloneHarvester;
|
|
},
|
|
|
|
showHarvesterHelpText() {
|
|
return !this.isStandaloneHarvester && this.$store.getters['currentProduct'].inStore === HARVESTER;
|
|
},
|
|
},
|
|
|
|
watch: {
|
|
project() {
|
|
const limits = this.getDefaultContainerResourceLimits(this.projectName);
|
|
|
|
this['containerResourceLimits'] = limits;
|
|
},
|
|
|
|
projectName(newProjectName) {
|
|
this['project'] = this.projects.find((p) => p.id.includes(newProjectName));
|
|
}
|
|
},
|
|
|
|
created() {
|
|
this.registerBeforeHook(this.willSave, 'willSave');
|
|
},
|
|
|
|
methods: {
|
|
willSave() {
|
|
const cluster = this.$store.getters['currentCluster'];
|
|
const projectId = this.project?.id.split('/')[1];
|
|
const annotation = projectId ? `${ cluster.id }:${ projectId }` : null;
|
|
|
|
this.value.setLabel(PROJECT, projectId);
|
|
this.value.setAnnotation(PROJECT, annotation);
|
|
},
|
|
|
|
getDefaultContainerResourceLimits(projectName) {
|
|
if (!projectName) {
|
|
return;
|
|
}
|
|
|
|
const projects = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
|
|
const project = projects.find((p) => p.id.includes(projectName));
|
|
|
|
return project?.spec?.containerDefaultResourceLimit || {};
|
|
},
|
|
|
|
PSAChanged($event) {
|
|
this.value.setLabels($event);
|
|
this.rerenderNums = randomStr(4);
|
|
}
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Loading v-if="$fetchState.pending" />
|
|
<CruResource
|
|
v-else
|
|
:done-route="doneLocationOverride.name"
|
|
:mode="mode"
|
|
:resource="value"
|
|
:subtypes="[]"
|
|
:validation-passed="true"
|
|
:errors="errors"
|
|
:apply-hooks="applyHooks"
|
|
@error="e=>errors = e"
|
|
@finish="save"
|
|
@cancel="done"
|
|
>
|
|
<NameNsDescription
|
|
v-if="!isView"
|
|
:value="value"
|
|
:namespaced="false"
|
|
:mode="mode"
|
|
:extra-columns="['project-col']"
|
|
>
|
|
<template
|
|
v-if="flatView && isCreate"
|
|
#project-col
|
|
>
|
|
<LabeledSelect
|
|
v-model:value="projectName"
|
|
data-testid="name-ns-description-project"
|
|
:label="t('namespace.project.label')"
|
|
:options="projectOpts"
|
|
/>
|
|
</template>
|
|
</NameNsDescription>
|
|
<ResourceTabs
|
|
:value="value"
|
|
:mode="mode"
|
|
:side-tabs="true"
|
|
:use-hash="useTabbedHash"
|
|
@update:value="$emit('input', $event)"
|
|
>
|
|
<Tab
|
|
v-if="showResourceQuota"
|
|
:weight="1"
|
|
name="container-resource-quotas"
|
|
:label="t('namespace.resourceQuotas')"
|
|
>
|
|
<div class="row">
|
|
<div class="col span-12">
|
|
<p class="helper-text mb-10">
|
|
<t
|
|
v-if="mode === viewMode"
|
|
k="resourceQuota.helpTextDetail"
|
|
/>
|
|
<t
|
|
v-else
|
|
k="resourceQuota.helpText"
|
|
/>
|
|
<span v-if="showHarvesterHelpText">
|
|
{{ t('resourceQuota.helpTextHarvester') }}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<ResourceQuota
|
|
:value="value"
|
|
:mode="mode"
|
|
:project="project"
|
|
:types="isStandaloneHarvester ? HARVESTER_TYPES : RANCHER_TYPES"
|
|
@update:value="$emit('input', $event)"
|
|
/>
|
|
</Tab>
|
|
<Tab
|
|
v-if="showContainerResourceLimit"
|
|
:weight="0"
|
|
name="container-resource-limit"
|
|
:label="t('namespace.containerResourceLimit')"
|
|
>
|
|
<ContainerResourceLimit
|
|
:value="containerResourceLimits"
|
|
:mode="mode"
|
|
:namespace="value"
|
|
:register-before-hook="registerBeforeHook"
|
|
data-testid="namespace-container-resource-limit"
|
|
/>
|
|
</Tab>
|
|
<Tab
|
|
name="labels-and-annotations"
|
|
label-key="generic.labelsAndAnnotations"
|
|
:weight="-1"
|
|
>
|
|
<Labels
|
|
default-container-class="labels-and-annotations-container"
|
|
:value="value"
|
|
:mode="mode"
|
|
:display-side-by-side="false"
|
|
/>
|
|
</Tab>
|
|
<Tab
|
|
v-if="showPodSecurityAdmission"
|
|
name="pod-security-admission"
|
|
label-key="podSecurityAdmission.name"
|
|
:label="t('podSecurityAdmission.name')"
|
|
>
|
|
<PodSecurityAdmission
|
|
:labels="value.labels"
|
|
:mode="mode"
|
|
labels-prefix="pod-security.kubernetes.io/"
|
|
@updateLabels="PSAChanged"
|
|
/>
|
|
</Tab>
|
|
</ResourceTabs>
|
|
</CruResource>
|
|
</template>
|