dashboard/models/rbac.authorization.k8s.io.r...

215 lines
5.6 KiB
JavaScript

import { uniq } from '@/utils/array';
import Vue from 'vue';
import { SCHEMA } from '@/config/types';
import { cleanForNew } from '@/plugins/steve/normalize';
import isEmpty from 'lodash/isEmpty';
export const SUBTYPE_MAPPING = {
GLOBAL: {
key: 'GLOBAL',
type: 'management.cattle.io.globalrole',
groupSortOrder: 0,
defaultKey: 'newUserDefault',
id: 'GLOBAL',
labelKey: 'rbac.roletemplate.subtypes.GLOBAL.label',
bannerAbbrvKey: 'rbac.roletemplate.subtypes.GLOBAL.abbreviation',
},
CLUSTER: {
key: 'CLUSTER',
type: 'management.cattle.io.roletemplate',
context: 'cluster',
groupSortOrder: 1,
defaultKey: 'clusterCreatorDefault',
id: 'CLUSTER',
labelKey: 'rbac.roletemplate.subtypes.CLUSTER.label',
bannerAbbrvKey: 'rbac.roletemplate.subtypes.CLUSTER.abbreviation',
},
NAMESPACE: {
key: 'NAMESPACE',
type: 'management.cattle.io.roletemplate',
context: 'project',
groupSortOrder: 2,
defaultKey: 'projectCreatorDefault',
id: 'NAMESPACE',
labelKey: 'rbac.roletemplate.subtypes.NAMESPACE.label',
bannerAbbrvKey: 'rbac.roletemplate.subtypes.NAMESPACE.abbreviation',
}
};
export const VERBS = [
'create',
'delete',
'get',
'list',
'patch',
'update',
'watch',
];
const GLOBAL_GROUP = '.cattle.io';
export const SUBTYPES = uniq(Object.values(SUBTYPE_MAPPING).map(mapping => mapping.type));
export function copyResourceValues(from, to) {
to.context = from.context;
to.metadata = from.metadata;
to.rules = from.rules;
to.roleTemplateIds = from.roleTemplateIds;
to.builtin = from.builtin;
to.locked = from.locked;
to.displayName = from.displayName;
to.kind = from.kind;
to.apiVersion = from.apiVersion;
Object.values(SUBTYPE_MAPPING).forEach((mapping) => {
to[mapping.defaultKey] = from[mapping.defaultKey];
});
}
export default {
customValidationRules() {
return [
{
path: 'rules',
validators: ['roleTemplateRules'],
required: true,
nullable: false,
type: 'array',
},
];
},
save() {
return async() => {
const errors = await this.validationErrors(this);
if (!isEmpty(errors)) {
return Promise.reject(errors);
}
let template;
if (this.template) {
template = this.$rootGetters['cluster/byId'](this.template.type, this.template.id);
} else {
const newTemplate = {
type: SUBTYPE_MAPPING[this.subtype].type,
displayName: this.name,
builtin: false
};
template = await this.$dispatch('cluster/create', newTemplate, { root: true });
}
copyResourceValues(this, template);
await template.save();
return {};
};
},
cleanForNew() {
return () => {
cleanForNew(this);
if (this.template) {
this.updateSubtype(this.subtype);
delete this.template;
}
};
},
canCustomEdit() {
return true;
},
subtype() {
if (this._subtype) {
return this._subtype;
}
if (this.template?.type === SUBTYPE_MAPPING.GLOBAL.type) {
return SUBTYPE_MAPPING.GLOBAL.key;
}
if (this.template?.type === SUBTYPE_MAPPING.CLUSTER.type && this.context === SUBTYPE_MAPPING.CLUSTER.context) {
return SUBTYPE_MAPPING.CLUSTER.key;
}
if (this.template?.type === SUBTYPE_MAPPING.NAMESPACE.type && this.context === SUBTYPE_MAPPING.NAMESPACE.context) {
return SUBTYPE_MAPPING.NAMESPACE.key;
}
return null;
},
subtypeDisplay() {
if (!this.subtype) {
return this.t(`rbac.roletemplate.subtypes.noContext.label`);
}
return this.t(`rbac.roletemplate.subtypes.${ this.subtype }.label`);
},
subtypeSort() {
if (!this.subtype) {
return Object.keys(SUBTYPE_MAPPING).length;
}
return SUBTYPE_MAPPING[this.subtype].groupSortOrder;
},
updateSubtype() {
return (subtype) => {
Vue.set(this, '_subtype', subtype);
if (SUBTYPE_MAPPING[subtype].key !== SUBTYPE_MAPPING.GLOBAL.key) {
this.context = SUBTYPE_MAPPING[subtype].context;
}
};
},
default() {
const defaultKey = SUBTYPE_MAPPING[this.subtype]?.defaultKey;
return !!this[defaultKey];
},
updateDefault() {
return (value) => {
const defaultKey = SUBTYPE_MAPPING[this.subtype].defaultKey;
Vue.set(this, defaultKey, value);
};
},
allResources() {
return this.$getters['all'](SCHEMA).filter(r => r.attributes?.kind);
},
globalResources() {
return this.allResources.filter(r => r.attributes.group.includes(GLOBAL_GROUP));
},
clusterResources() {
return this.allResources.filter(r => !r.attributes.namespaced && !r.attributes.group.includes(GLOBAL_GROUP));
},
namespaceResources() {
return this.allResources.filter(r => r.attributes.namespaced && !r.attributes.group.includes(GLOBAL_GROUP));
},
subtypeResources() {
switch (this.subtype) {
case SUBTYPE_MAPPING.CLUSTER.key:
return this.clusterResources;
case SUBTYPE_MAPPING.NAMESPACE.key:
return this.namespaceResources;
default:
return this.globalResources;
}
},
resources() {
return uniq(this.subtypeResources.map(r => r.attributes?.kind)).sort();
}
};