mirror of https://github.com/apache/cloudstack.git
config: refactor to enforce all permission checks (#291)
Changes permission checking behaviour where all list of APIs must be permitted to see a view. The first API will be used to list/render the table. Remaining APIs will only be used to verify permissions. If any of the passed API is not found in the allowed APIs for logged-in user's role section/sub-section won't be displayed. Fixes #241 Fixes #244 Fixes #240 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com> Co-authored-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
ddcc2435bd
commit
b9385f49d0
|
|
@ -348,7 +348,8 @@
|
|||
<div class="resource-detail-item__label">{{ $t('serviceofferingname') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="cloud" />
|
||||
<router-link :to="{ path: '/computeoffering/' + resource.serviceofferingid }">{{ resource.serviceofferingname || resource.serviceofferingid }} </router-link>
|
||||
<router-link v-if="$router.resolve('/computeoffering/' + resource.serviceofferingid).route.name !== '404'" :to="{ path: '/computeoffering/' + resource.serviceofferingid }">{{ resource.serviceofferingname || resource.serviceofferingid }} </router-link>
|
||||
<span v-else>{{ resource.serviceofferingname || resource.serviceofferingid }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.templateid">
|
||||
|
|
@ -362,7 +363,8 @@
|
|||
<div class="resource-detail-item__label">{{ $t('diskoffering') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<a-icon type="hdd" />
|
||||
<router-link :to="{ path: '/diskoffering/' + resource.diskofferingid }">{{ resource.diskofferingname || resource.diskofferingid }} </router-link>
|
||||
<router-link v-if="$router.resolve('/diskoffering/' + resource.diskofferingid).route.name !== '404'" :to="{ path: '/diskoffering/' + resource.diskofferingid }">{{ resource.diskofferingname || resource.diskofferingid }} </router-link>
|
||||
<span v-else>{{ resource.diskofferingname || resource.diskofferingid }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.backupofferingid">
|
||||
|
|
|
|||
|
|
@ -130,16 +130,17 @@
|
|||
<router-link :to="{ path: '/account', query: { name: record.account, domainid: record.domainid } }" v-else>{{ text }}</router-link>
|
||||
</a>
|
||||
<span slot="domain" slot-scope="text, record" href="javascript:;">
|
||||
<router-link v-if="record.domainid && !record.domainid.includes(',')" :to="{ path: '/domain/' + record.domainid }">{{ text }}</router-link>
|
||||
<router-link v-if="record.domainid && !record.domainid.includes(',') && $router.resolve('/domain/' + record.domainid).route.name !== '404'" :to="{ path: '/domain/' + record.domainid }">{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
</span>
|
||||
<a slot="zone" slot-scope="text, record" href="javascript:;">
|
||||
<router-link v-if="record.zoneid && !record.zoneid.includes(',')" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
|
||||
<router-link v-if="record.zoneid && !record.zoneid.includes(',') && $router.resolve('/zone/' + record.zoneid).route.name !== '404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
</a>
|
||||
<a slot="zonename" slot-scope="text, record" href="javascript:;">
|
||||
<router-link :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
|
||||
</a>
|
||||
<span slot="zonename" slot-scope="text, record">
|
||||
<router-link v-if="$router.resolve('/zone/' + record.zoneid).route.name !== '404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
</span>
|
||||
|
||||
<div slot="order" slot-scope="text, record" class="shift-btns">
|
||||
<a-tooltip placement="top">
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ import network from '@/config/section/network'
|
|||
import image from '@/config/section/image'
|
||||
import project from '@/config/section/project'
|
||||
import event from '@/config/section/event'
|
||||
import iam from '@/config/section/iam'
|
||||
import user from '@/config/section/user'
|
||||
import account from '@/config/section/account'
|
||||
import domain from '@/config/section/domain'
|
||||
import role from '@/config/section/role'
|
||||
import infra from '@/config/section/infra'
|
||||
import offering from '@/config/section/offering'
|
||||
import config from '@/config/section/config'
|
||||
|
|
@ -194,9 +197,12 @@ export const asyncRouterMap = [
|
|||
generateRouterMap(storage),
|
||||
generateRouterMap(network),
|
||||
generateRouterMap(image),
|
||||
generateRouterMap(project),
|
||||
generateRouterMap(event),
|
||||
generateRouterMap(iam),
|
||||
generateRouterMap(project),
|
||||
generateRouterMap(user),
|
||||
generateRouterMap(account),
|
||||
generateRouterMap(domain),
|
||||
generateRouterMap(role),
|
||||
generateRouterMap(infra),
|
||||
generateRouterMap(offering),
|
||||
generateRouterMap(config),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,157 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
export default {
|
||||
name: 'account',
|
||||
title: 'Accounts',
|
||||
icon: 'team',
|
||||
permission: ['listAccounts'],
|
||||
columns: ['name', 'state', 'rolename', 'roletype', 'domain'],
|
||||
details: ['name', 'id', 'rolename', 'roletype', 'domain', 'networkdomain', 'iptotal', 'vmtotal', 'volumetotal', 'receivedbytes', 'sentbytes', 'vmlimit', 'iplimit', 'volumelimit', 'snapshotlimit', 'templatelimit', 'vpclimit', 'cpulimit', 'memorylimit', 'networklimit', 'primarystoragelimit', 'secondarystoragelimit'],
|
||||
related: [{
|
||||
name: 'accountuser',
|
||||
title: 'Users',
|
||||
param: 'account'
|
||||
}],
|
||||
tabs: [
|
||||
{
|
||||
name: 'details',
|
||||
component: () => import('@/components/view/DetailsTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'certificate',
|
||||
component: () => import('@/views/iam/SSLCertificateTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) },
|
||||
component: () => import('@/components/view/ResourceLimitTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
component: () => import('@/components/view/SettingsTab.vue'),
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) }
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
api: 'createAccount',
|
||||
icon: 'plus',
|
||||
label: 'label.add.account',
|
||||
listView: true,
|
||||
args: ['username', 'password', 'password', 'email', 'firstname', 'lastname', 'domainid', 'account', 'roleid', 'timezone', 'networkdomain']
|
||||
},
|
||||
{
|
||||
api: 'ldapCreateAccount',
|
||||
icon: 'user-add',
|
||||
label: 'label.add.ldap.account',
|
||||
listView: true,
|
||||
popup: true,
|
||||
show: (record, store) => {
|
||||
return store.isLdapEnabled
|
||||
},
|
||||
component: () => import('@/views/iam/AddLdapAccount.vue')
|
||||
},
|
||||
{
|
||||
api: 'updateAccount',
|
||||
icon: 'edit',
|
||||
label: 'Update Account',
|
||||
dataView: true,
|
||||
args: ['newname', 'account', 'domainid', 'networkdomain'],
|
||||
mapping: {
|
||||
account: {
|
||||
value: (record) => { return record.name }
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.domainid }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateResourceCount',
|
||||
icon: 'sync',
|
||||
label: 'Update Resource Count',
|
||||
dataView: true,
|
||||
args: ['account', 'domainid'],
|
||||
mapping: {
|
||||
account: {
|
||||
value: (record) => { return record.name }
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.domainid }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'enableAccount',
|
||||
icon: 'play-circle',
|
||||
label: 'Enable Account',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'disabled' || record.state === 'locked' },
|
||||
params: { lock: 'false' }
|
||||
},
|
||||
{
|
||||
api: 'disableAccount',
|
||||
icon: 'pause-circle',
|
||||
label: 'Disable Account',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'enabled' },
|
||||
args: ['lock'],
|
||||
mapping: {
|
||||
lock: {
|
||||
value: (record) => { return false }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'disableAccount',
|
||||
icon: 'lock',
|
||||
label: 'Lock account',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'enabled' },
|
||||
args: ['lock'],
|
||||
mapping: {
|
||||
lock: {
|
||||
value: (record) => { return true }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'uploadSslCert',
|
||||
icon: 'safety-certificate',
|
||||
label: 'Add certificate',
|
||||
dataView: true,
|
||||
args: ['name', 'certificate', 'privatekey', 'certchain', 'password', 'account', 'domainid'],
|
||||
show: (record) => { return record.state === 'enabled' },
|
||||
mapping: {
|
||||
account: {
|
||||
value: (record) => { return record.name }
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.domainid }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'deleteAccount',
|
||||
icon: 'delete',
|
||||
label: 'Delete account',
|
||||
dataView: true,
|
||||
hidden: (record) => { return record.name === 'admin' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ export default {
|
|||
title: 'Instances',
|
||||
icon: 'desktop',
|
||||
docHelp: 'adminguide/virtual_machines.html',
|
||||
permission: ['listVirtualMachinesMetrics', 'listVirtualMachines'],
|
||||
permission: ['listVirtualMachinesMetrics'],
|
||||
resourceType: 'UserVm',
|
||||
columns: [
|
||||
'name', 'state', 'instancename', 'ipaddress', 'cpunumber', 'cpuused', 'cputotal',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
export default {
|
||||
name: 'iam',
|
||||
title: 'Domains',
|
||||
icon: 'block',
|
||||
permission: ['listDomains'],
|
||||
children: [
|
||||
{
|
||||
name: 'domain',
|
||||
title: 'Domains',
|
||||
icon: 'block',
|
||||
permission: ['listDomains'],
|
||||
resourceType: 'Domain',
|
||||
columns: ['name', 'state', 'path', 'parentdomainname', 'level'],
|
||||
details: ['name', 'id', 'path', 'parentdomainname', 'level', 'networkdomain', 'iptotal', 'vmtotal', 'volumetotal', 'vmlimit', 'iplimit', 'volumelimit', 'snapshotlimit', 'templatelimit', 'vpclimit', 'cpulimit', 'memorylimit', 'networklimit', 'primarystoragelimit', 'secondarystoragelimit'],
|
||||
related: [{
|
||||
name: 'account',
|
||||
title: 'Accounts',
|
||||
param: 'domainid'
|
||||
}],
|
||||
tabs: [
|
||||
{
|
||||
name: 'Domain',
|
||||
component: () => import('@/components/view/InfoCard.vue'),
|
||||
show: (record, route) => { return route.path === '/domain' }
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
component: () => import('@/components/view/DetailsTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) },
|
||||
component: () => import('@/components/view/ResourceLimitTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
component: () => import('@/components/view/SettingsTab.vue'),
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) }
|
||||
}
|
||||
],
|
||||
treeView: true,
|
||||
actions: [
|
||||
{
|
||||
api: 'createDomain',
|
||||
icon: 'plus',
|
||||
label: 'label.add.domain',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['parentdomainid', 'name', 'networkdomain', 'domainid'],
|
||||
mapping: {
|
||||
parentdomainid: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateDomain',
|
||||
icon: 'edit',
|
||||
label: 'label.action.edit.domain',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['name', 'networkdomain']
|
||||
},
|
||||
{
|
||||
api: 'updateResourceCount',
|
||||
icon: 'sync',
|
||||
label: 'label.action.update.resource.count',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['domainid'],
|
||||
mapping: {
|
||||
domainid: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'linkDomainToLdap',
|
||||
icon: 'link',
|
||||
label: 'Link Domain to LDAP Group/OU',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['type', 'domainid', 'name', 'accounttype', 'admin'],
|
||||
mapping: {
|
||||
type: {
|
||||
options: ['GROUP', 'OU']
|
||||
},
|
||||
accounttype: {
|
||||
options: ['0', '2']
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'deleteDomain',
|
||||
icon: 'delete',
|
||||
label: 'label.delete.domain',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
show: (record) => { return record.level !== 0 },
|
||||
args: ['cleanup']
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,370 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
export default {
|
||||
name: 'iam',
|
||||
title: 'Identity and Access',
|
||||
icon: 'solution',
|
||||
permission: ['listAccounts', 'listUsers', 'listDomains', 'listRoles'],
|
||||
children: [
|
||||
{
|
||||
name: 'accountuser',
|
||||
title: 'Users',
|
||||
icon: 'user',
|
||||
permission: ['listUsers'],
|
||||
columns: ['username', 'state', 'firstname', 'lastname', 'email', 'account', 'domain'],
|
||||
details: ['username', 'id', 'firstname', 'lastname', 'email', 'usersource', 'timezone', 'rolename', 'roletype', 'account', 'domain', 'created'],
|
||||
actions: [
|
||||
{
|
||||
api: 'createUser',
|
||||
icon: 'plus',
|
||||
label: 'label.add.user',
|
||||
listView: true,
|
||||
args: ['username', 'password', 'password', 'email', 'firstname', 'lastname', 'timezone', 'account', 'domainid']
|
||||
},
|
||||
{
|
||||
api: 'updateUser',
|
||||
icon: 'edit',
|
||||
label: 'label.edit',
|
||||
dataView: true,
|
||||
args: ['username', 'email', 'firstname', 'lastname', 'timezone']
|
||||
},
|
||||
{
|
||||
api: 'updateUser',
|
||||
icon: 'key',
|
||||
label: 'label.action.change.password',
|
||||
dataView: true,
|
||||
popup: true,
|
||||
component: () => import('@/views/iam/ChangeUserPassword.vue')
|
||||
},
|
||||
{
|
||||
api: 'registerUserKeys',
|
||||
icon: 'file-protect',
|
||||
label: 'label.action.generate.keys',
|
||||
dataView: true
|
||||
},
|
||||
{
|
||||
api: 'enableUser',
|
||||
icon: 'play-circle',
|
||||
label: 'label.action.enable.user',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'disabled' }
|
||||
},
|
||||
{
|
||||
api: 'disableUser',
|
||||
icon: 'pause-circle',
|
||||
label: 'label.action.disable.user',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'enabled' }
|
||||
},
|
||||
{
|
||||
api: 'deleteUser',
|
||||
icon: 'delete',
|
||||
label: 'label.action.delete.user',
|
||||
dataView: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'account',
|
||||
title: 'Accounts',
|
||||
icon: 'team',
|
||||
permission: ['listAccounts'],
|
||||
columns: ['name', 'state', 'rolename', 'roletype', 'domain'],
|
||||
details: ['name', 'id', 'rolename', 'roletype', 'domain', 'networkdomain', 'iptotal', 'vmtotal', 'volumetotal', 'receivedbytes', 'sentbytes', 'vmlimit', 'iplimit', 'volumelimit', 'snapshotlimit', 'templatelimit', 'vpclimit', 'cpulimit', 'memorylimit', 'networklimit', 'primarystoragelimit', 'secondarystoragelimit'],
|
||||
related: [{
|
||||
name: 'accountuser',
|
||||
title: 'Users',
|
||||
param: 'account'
|
||||
}],
|
||||
tabs: [
|
||||
{
|
||||
name: 'details',
|
||||
component: () => import('@/components/view/DetailsTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'certificate',
|
||||
component: () => import('@/views/iam/SSLCertificateTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) },
|
||||
component: () => import('@/components/view/ResourceLimitTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
component: () => import('@/components/view/SettingsTab.vue'),
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) }
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
api: 'createAccount',
|
||||
icon: 'plus',
|
||||
label: 'label.add.account',
|
||||
listView: true,
|
||||
args: ['username', 'password', 'password', 'email', 'firstname', 'lastname', 'domainid', 'account', 'roleid', 'timezone', 'networkdomain']
|
||||
},
|
||||
{
|
||||
api: 'ldapCreateAccount',
|
||||
icon: 'user-add',
|
||||
label: 'label.add.ldap.account',
|
||||
listView: true,
|
||||
popup: true,
|
||||
show: (record, store) => {
|
||||
return store.isLdapEnabled
|
||||
},
|
||||
component: () => import('@/views/iam/AddLdapAccount.vue')
|
||||
},
|
||||
{
|
||||
api: 'updateAccount',
|
||||
icon: 'edit',
|
||||
label: 'Update Account',
|
||||
dataView: true,
|
||||
args: ['newname', 'account', 'domainid', 'networkdomain'],
|
||||
mapping: {
|
||||
account: {
|
||||
value: (record) => { return record.name }
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.domainid }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateResourceCount',
|
||||
icon: 'sync',
|
||||
label: 'Update Resource Count',
|
||||
dataView: true,
|
||||
args: ['account', 'domainid'],
|
||||
mapping: {
|
||||
account: {
|
||||
value: (record) => { return record.name }
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.domainid }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'enableAccount',
|
||||
icon: 'play-circle',
|
||||
label: 'Enable Account',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'disabled' || record.state === 'locked' },
|
||||
params: { lock: 'false' }
|
||||
},
|
||||
{
|
||||
api: 'disableAccount',
|
||||
icon: 'pause-circle',
|
||||
label: 'Disable Account',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'enabled' },
|
||||
args: ['lock'],
|
||||
mapping: {
|
||||
lock: {
|
||||
value: (record) => { return false }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'disableAccount',
|
||||
icon: 'lock',
|
||||
label: 'Lock account',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'enabled' },
|
||||
args: ['lock'],
|
||||
mapping: {
|
||||
lock: {
|
||||
value: (record) => { return true }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'uploadSslCert',
|
||||
icon: 'safety-certificate',
|
||||
label: 'Add certificate',
|
||||
dataView: true,
|
||||
args: ['name', 'certificate', 'privatekey', 'certchain', 'password', 'account', 'domainid'],
|
||||
show: (record) => { return record.state === 'enabled' },
|
||||
mapping: {
|
||||
account: {
|
||||
value: (record) => { return record.name }
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.domainid }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'deleteAccount',
|
||||
icon: 'delete',
|
||||
label: 'Delete account',
|
||||
dataView: true,
|
||||
hidden: (record) => { return record.name === 'admin' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'domain',
|
||||
title: 'Domains',
|
||||
icon: 'block',
|
||||
permission: ['listDomains', 'listDomainChildren'],
|
||||
resourceType: 'Domain',
|
||||
columns: ['name', 'state', 'path', 'parentdomainname', 'level'],
|
||||
details: ['name', 'id', 'path', 'parentdomainname', 'level', 'networkdomain', 'iptotal', 'vmtotal', 'volumetotal', 'vmlimit', 'iplimit', 'volumelimit', 'snapshotlimit', 'templatelimit', 'vpclimit', 'cpulimit', 'memorylimit', 'networklimit', 'primarystoragelimit', 'secondarystoragelimit'],
|
||||
related: [{
|
||||
name: 'account',
|
||||
title: 'Accounts',
|
||||
param: 'domainid'
|
||||
}],
|
||||
tabs: [
|
||||
{
|
||||
name: 'Domain',
|
||||
component: () => import('@/components/view/InfoCard.vue'),
|
||||
show: (record, route) => { return route.path === '/domain' }
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
component: () => import('@/components/view/DetailsTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'limits',
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) },
|
||||
component: () => import('@/components/view/ResourceLimitTab.vue')
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
component: () => import('@/components/view/SettingsTab.vue'),
|
||||
show: (record, route, user) => { return ['Admin'].includes(user.roletype) }
|
||||
}
|
||||
],
|
||||
treeView: true,
|
||||
actions: [
|
||||
{
|
||||
api: 'createDomain',
|
||||
icon: 'plus',
|
||||
label: 'label.add.domain',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['parentdomainid', 'name', 'networkdomain', 'domainid'],
|
||||
mapping: {
|
||||
parentdomainid: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateDomain',
|
||||
icon: 'edit',
|
||||
label: 'label.action.edit.domain',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['name', 'networkdomain']
|
||||
},
|
||||
{
|
||||
api: 'updateResourceCount',
|
||||
icon: 'sync',
|
||||
label: 'label.action.update.resource.count',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['domainid'],
|
||||
mapping: {
|
||||
domainid: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'linkDomainToLdap',
|
||||
icon: 'link',
|
||||
label: 'Link Domain to LDAP Group/OU',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
args: ['type', 'domainid', 'name', 'accounttype', 'admin'],
|
||||
mapping: {
|
||||
type: {
|
||||
options: ['GROUP', 'OU']
|
||||
},
|
||||
accounttype: {
|
||||
options: ['0', '2']
|
||||
},
|
||||
domainid: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'deleteDomain',
|
||||
icon: 'delete',
|
||||
label: 'label.delete.domain',
|
||||
listView: true,
|
||||
dataView: true,
|
||||
show: (record) => { return record.level !== 0 },
|
||||
args: ['cleanup']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'role',
|
||||
title: 'Roles',
|
||||
icon: 'idcard',
|
||||
permission: ['listRoles'],
|
||||
columns: ['name', 'type', 'description'],
|
||||
details: ['name', 'id', 'type', 'description'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
component: () => import('@/components/view/DetailsTab.vue')
|
||||
}, {
|
||||
name: 'Rules',
|
||||
component: () => import('@/views/iam/RolePermissionTab.vue')
|
||||
}],
|
||||
actions: [
|
||||
{
|
||||
api: 'createRole',
|
||||
icon: 'plus',
|
||||
label: 'Create Role',
|
||||
listView: true,
|
||||
args: ['name', 'description', 'type'],
|
||||
mapping: {
|
||||
type: {
|
||||
options: ['Admin', 'DomainAdmin', 'User']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateRole',
|
||||
icon: 'edit',
|
||||
label: 'Edit Role',
|
||||
dataView: true,
|
||||
args: ['name', 'description', 'type'],
|
||||
mapping: {
|
||||
type: {
|
||||
options: ['Admin', 'DomainAdmin', 'User']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'deleteRole',
|
||||
icon: 'delete',
|
||||
label: 'label.delete.role',
|
||||
dataView: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
name: 'cluster',
|
||||
title: 'Clusters',
|
||||
icon: 'cluster',
|
||||
permission: ['listClustersMetrics', 'listClusters'],
|
||||
permission: ['listClustersMetrics'],
|
||||
columns: ['name', 'state', 'allocationstate', 'clustertype', 'hypervisortype', 'hosts', 'cpuused', 'cpumaxdeviation', 'cpuallocated', 'cputotal', 'memoryused', 'memorymaxdeviation', 'memoryallocated', 'memorytotal', 'podname', 'zonename'],
|
||||
details: ['name', 'id', 'allocationstate', 'clustertype', 'hypervisortype', 'podname', 'zonename'],
|
||||
related: [{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
name: 'host',
|
||||
title: 'Hosts',
|
||||
icon: 'desktop',
|
||||
permission: ['listHostsMetrics', 'listHosts'],
|
||||
permission: ['listHostsMetrics'],
|
||||
resourceType: 'Host',
|
||||
params: { type: 'routing' },
|
||||
columns: ['name', 'state', 'resourcestate', 'powerstate', 'ipaddress', 'hypervisor', 'instances', 'cpunumber', 'cputotalghz', 'cpuusedghz', 'cpuallocatedghz', 'memorytotalgb', 'memoryusedgb', 'memoryallocatedgb', 'networkread', 'networkwrite', 'clustername', 'zonename'],
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
name: 'storagepool',
|
||||
title: 'Primary Storage',
|
||||
icon: 'database',
|
||||
permission: ['listStoragePoolsMetrics', 'listStoragePools'],
|
||||
permission: ['listStoragePoolsMetrics'],
|
||||
columns: ['name', 'state', 'ipaddress', 'type', 'path', 'scope', 'disksizeusedgb', 'disksizetotalgb', 'disksizeallocatedgb', 'disksizeunallocatedgb', 'clustername', 'zonename'],
|
||||
details: ['name', 'id', 'ipaddress', 'type', 'scope', 'tags', 'path', 'provider', 'hypervisor', 'overprovisionfactor', 'disksizetotal', 'disksizeallocated', 'disksizeused', 'clustername', 'podname', 'zonename', 'created'],
|
||||
related: [{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
name: 'zone',
|
||||
title: 'Zones',
|
||||
icon: 'global',
|
||||
permission: ['listZonesMetrics', 'listZones'],
|
||||
permission: ['listZonesMetrics'],
|
||||
columns: ['name', 'state', 'allocationstate', 'networktype', 'clusters', 'cpuused', 'cpumaxdeviation', 'cpuallocated', 'cputotal', 'memoryused', 'memorymaxdeviation', 'memoryallocated', 'memorytotal', 'order'],
|
||||
details: ['name', 'id', 'allocationstate', 'networktype', 'guestcidraddress', 'localstorageenabled', 'securitygroupsenabled', 'dns1', 'dns2', 'internaldns1', 'internaldns2'],
|
||||
related: [{
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ export default {
|
|||
name: 'offering',
|
||||
title: 'Offerings',
|
||||
icon: 'shopping',
|
||||
permission: ['listServiceOfferings'],
|
||||
permission: ['createServiceOffering', 'createDiskOffering'],
|
||||
children: [
|
||||
{
|
||||
name: 'computeoffering',
|
||||
title: 'Compute Offerings',
|
||||
icon: 'cloud',
|
||||
permission: ['listServiceOfferings'],
|
||||
permission: ['listServiceOfferings', 'createServiceOffering'],
|
||||
params: { isrecursive: 'true' },
|
||||
columns: ['name', 'displaytext', 'cpunumber', 'cpuspeed', 'memory', 'tags', 'domain', 'zone', 'order'],
|
||||
details: ['name', 'id', 'displaytext', 'offerha', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'tags', 'domain', 'zone', 'created'],
|
||||
|
|
@ -96,7 +96,7 @@ export default {
|
|||
name: 'diskoffering',
|
||||
title: 'Disk Offerings',
|
||||
icon: 'hdd',
|
||||
permission: ['listDiskOfferings'],
|
||||
permission: ['listDiskOfferings', 'createDiskOffering'],
|
||||
params: { isrecursive: 'true' },
|
||||
columns: ['name', 'displaytext', 'disksize', 'tags', 'domain', 'zone', 'order'],
|
||||
details: ['name', 'id', 'displaytext', 'disksize', 'provisioningtype', 'storagetype', 'iscustomized', 'tags', 'domain', 'zone', 'created'],
|
||||
|
|
@ -136,7 +136,7 @@ export default {
|
|||
name: 'backupoffering',
|
||||
title: 'Backup Offerings',
|
||||
icon: 'cloud-upload',
|
||||
permission: ['listBackupOfferings'],
|
||||
permission: ['listBackupOfferings', 'importBackupOffering'],
|
||||
columns: ['name', 'description', 'zoneid'],
|
||||
details: ['name', 'id', 'description', 'externalid', 'zone', 'created'],
|
||||
actions: [{
|
||||
|
|
@ -157,7 +157,7 @@ export default {
|
|||
name: 'networkoffering',
|
||||
title: 'Network Offerings',
|
||||
icon: 'wifi',
|
||||
permission: ['listNetworkOfferings'],
|
||||
permission: ['listNetworkOfferings', 'createNetworkOffering'],
|
||||
params: { isrecursive: 'true' },
|
||||
columns: ['name', 'state', 'guestiptype', 'traffictype', 'networkrate', 'tags', 'domain', 'zone', 'order'],
|
||||
details: ['name', 'id', 'displaytext', 'guestiptype', 'traffictype', 'networkrate', 'ispersistent', 'egressdefaultpolicy', 'availability', 'conservemode', 'specifyvlan', 'specifyipranges', 'supportspublicaccess', 'supportsstrechedl2subnet', 'tags', 'service', 'domain', 'zone'],
|
||||
|
|
@ -221,7 +221,7 @@ export default {
|
|||
name: 'vpcoffering',
|
||||
title: 'VPC Offerings',
|
||||
icon: 'deployment-unit',
|
||||
permission: ['listVPCOfferings'],
|
||||
permission: ['listVPCOfferings', 'createVPCOffering'],
|
||||
params: { isrecursive: 'true' },
|
||||
resourceType: 'VpcOffering',
|
||||
columns: ['name', 'state', 'displaytext', 'domain', 'zone', 'order'],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
export default {
|
||||
name: 'role',
|
||||
title: 'Roles',
|
||||
icon: 'idcard',
|
||||
permission: ['listRoles', 'createRole'],
|
||||
columns: ['name', 'type', 'description'],
|
||||
details: ['name', 'id', 'type', 'description'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
component: () => import('@/components/view/DetailsTab.vue')
|
||||
}, {
|
||||
name: 'Rules',
|
||||
component: () => import('@/views/iam/RolePermissionTab.vue')
|
||||
}],
|
||||
actions: [
|
||||
{
|
||||
api: 'createRole',
|
||||
icon: 'plus',
|
||||
label: 'Create Role',
|
||||
listView: true,
|
||||
args: ['name', 'description', 'type'],
|
||||
mapping: {
|
||||
type: {
|
||||
options: ['Admin', 'DomainAdmin', 'User']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateRole',
|
||||
icon: 'edit',
|
||||
label: 'Edit Role',
|
||||
dataView: true,
|
||||
args: ['name', 'description', 'type'],
|
||||
mapping: {
|
||||
type: {
|
||||
options: ['Admin', 'DomainAdmin', 'User']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'deleteRole',
|
||||
icon: 'delete',
|
||||
label: 'label.delete.role',
|
||||
dataView: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ export default {
|
|||
name: 'volume',
|
||||
title: 'Volumes',
|
||||
icon: 'hdd',
|
||||
permission: ['listVolumesMetrics', 'listVolumes'],
|
||||
permission: ['listVolumesMetrics'],
|
||||
resourceType: 'Volume',
|
||||
columns: ['name', 'state', 'type', 'vmname', 'size', 'physicalsize', 'utilization', 'diskkbsread', 'diskkbswrite', 'diskiopstotal', 'storage', 'account', 'zonename'],
|
||||
details: ['name', 'id', 'type', 'storagetype', 'diskofferingdisplaytext', 'deviceid', 'sizegb', 'physicalsize', 'provisioningtype', 'utilization', 'diskkbsread', 'diskkbswrite', 'diskioread', 'diskiowrite', 'diskiopstotal', 'miniops', 'maxiops', 'path'],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
export default {
|
||||
name: 'accountuser',
|
||||
title: 'Users',
|
||||
icon: 'user',
|
||||
hidden: true,
|
||||
permission: ['listUsers'],
|
||||
columns: ['username', 'state', 'firstname', 'lastname', 'email', 'account', 'domain'],
|
||||
details: ['username', 'id', 'firstname', 'lastname', 'email', 'usersource', 'timezone', 'rolename', 'roletype', 'account', 'domain', 'created'],
|
||||
actions: [
|
||||
{
|
||||
api: 'createUser',
|
||||
icon: 'plus',
|
||||
label: 'label.add.user',
|
||||
listView: true,
|
||||
args: ['username', 'password', 'password', 'email', 'firstname', 'lastname', 'timezone', 'account', 'domainid']
|
||||
},
|
||||
{
|
||||
api: 'updateUser',
|
||||
icon: 'edit',
|
||||
label: 'label.edit',
|
||||
dataView: true,
|
||||
args: ['username', 'email', 'firstname', 'lastname', 'timezone']
|
||||
},
|
||||
{
|
||||
api: 'updateUser',
|
||||
icon: 'key',
|
||||
label: 'label.action.change.password',
|
||||
dataView: true,
|
||||
popup: true,
|
||||
component: () => import('@/views/iam/ChangeUserPassword.vue')
|
||||
},
|
||||
{
|
||||
api: 'registerUserKeys',
|
||||
icon: 'file-protect',
|
||||
label: 'label.action.generate.keys',
|
||||
dataView: true
|
||||
},
|
||||
{
|
||||
api: 'enableUser',
|
||||
icon: 'play-circle',
|
||||
label: 'label.action.enable.user',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'disabled' }
|
||||
},
|
||||
{
|
||||
api: 'disableUser',
|
||||
icon: 'pause-circle',
|
||||
label: 'label.action.disable.user',
|
||||
dataView: true,
|
||||
show: (record) => { return record.state === 'enabled' }
|
||||
},
|
||||
{
|
||||
api: 'deleteUser',
|
||||
icon: 'delete',
|
||||
label: 'label.action.delete.user',
|
||||
dataView: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -20,11 +20,11 @@ import { asyncRouterMap, constantRouterMap } from '@/config/router'
|
|||
function hasApi (apis, route) {
|
||||
if (route.meta && route.meta.permission) {
|
||||
for (const permission of route.meta.permission) {
|
||||
if (apis.includes(permission)) {
|
||||
return true
|
||||
if (!apis.includes(permission)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue