UI: Move Backup Repository to Infrastructure (from Configuration) (#11738)

* UI: Move Backup Repository to Infrastructure (from Configuration)

* Updated nas doc help link
This commit is contained in:
Suresh Kumar Anaparti 2025-10-10 13:25:05 +05:30 committed by GitHub
parent 67250d99d4
commit df49c4f14b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 82 additions and 50 deletions

View File

@ -59,6 +59,7 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.dao.BackupRepositoryDao;
import org.apache.cloudstack.cluster.ClusterDrsAlgorithm;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.ConfigKey;
@ -158,6 +159,8 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
@Inject
private ImageStoreDao imageStoreDao;
@Inject
BackupRepositoryDao backupRepositoryDao;
@Inject
private VMInstanceDao vmInstanceDao;
@Inject
private DomainRouterDao domainRouterDao;
@ -557,6 +560,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
response.setHosts(hostCountAndCpuSockets.first());
response.setStoragePools(storagePoolDao.countAll());
response.setImageStores(imageStoreDao.countAllImageStores());
response.setBackupRepositories(backupRepositoryDao.countAll());
response.setObjectStores(objectStoreDao.countAllObjectStores());
response.setSystemvms(vmInstanceDao.countByTypes(VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm));
response.setRouters(domainRouterDao.countAllByRole(VirtualRouter.Role.VIRTUAL_ROUTER));

View File

@ -47,6 +47,10 @@ public class InfrastructureResponse extends BaseResponse {
@Param(description = "Number of images stores")
private Integer imageStores;
@SerializedName("backuprepositories")
@Param(description = "Number of backup repositories", since = "4.22.0")
private Integer backupRepositories;
@SerializedName("objectstores")
@Param(description = "Number of object stores")
private Integer objectStores;
@ -103,6 +107,10 @@ public class InfrastructureResponse extends BaseResponse {
this.imageStores = imageStores;
}
public void setBackupRepositories(Integer backupRepositories) {
this.backupRepositories = backupRepositories;
}
public void setSystemvms(final Integer systemvms) {
this.systemvms = systemvms;
}

View File

@ -133,52 +133,6 @@ export default {
}
]
},
{
name: 'backuprepository',
title: 'label.backup.repository',
icon: 'inbox-outlined',
docHelp: 'adminguide/backup_and_recovery.html',
permission: ['listBackupRepositories'],
searchFilters: ['zoneid'],
columns: ['name', 'provider', 'type', 'address', 'zonename'],
details: ['name', 'type', 'address', 'provider', 'zonename', 'crosszoneinstancecreation'],
actions: [
{
api: 'addBackupRepository',
icon: 'plus-outlined',
label: 'label.backup.repository.add',
listView: true,
args: [
'name', 'provider', 'address', 'type', 'mountopts', 'zoneid', 'crosszoneinstancecreation'
],
mapping: {
type: {
options: ['nfs', 'cifs', 'ceph']
},
provider: {
value: (record) => { return 'nas' }
}
}
},
{
api: 'updateBackupRepository',
icon: 'edit-outlined',
label: 'label.backup.repository.edit',
message: 'message.action.edit.backup.repository',
args: ['name', 'address', 'mountopts', 'crosszoneinstancecreation'],
dataView: true,
popup: true
},
{
api: 'deleteBackupRepository',
icon: 'delete-outlined',
label: 'label.backup.repository.remove',
message: 'message.action.delete.backup.repository',
dataView: true,
popup: true
}
]
},
{
name: 'hypervisorcapability',
title: 'label.hypervisor.capabilities',

View File

@ -23,6 +23,7 @@ import clusters from '@/config/section/infra/clusters'
import hosts from '@/config/section/infra/hosts'
import primaryStorages from '@/config/section/infra/primaryStorages'
import secondaryStorages from '@/config/section/infra/secondaryStorages'
import backupRepositories from '@/config/section/infra/backupRepositories'
import objectStorages from '@/config/section/infra/objectStorages'
import systemVms from '@/config/section/infra/systemVms'
import routers from '@/config/section/infra/routers'
@ -50,6 +51,7 @@ export default {
hosts,
primaryStorages,
secondaryStorages,
backupRepositories,
objectStorages,
systemVms,
routers,

View File

@ -0,0 +1,63 @@
// 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: 'backuprepository',
title: 'label.backup.repository',
icon: 'inbox-outlined',
docHelp: 'adminguide/nas_plugin.html',
permission: ['listBackupRepositories'],
searchFilters: ['zoneid'],
columns: ['name', 'provider', 'type', 'address', 'zonename'],
details: ['name', 'type', 'address', 'provider', 'zonename', 'crosszoneinstancecreation'],
actions: [
{
api: 'addBackupRepository',
icon: 'plus-outlined',
label: 'label.backup.repository.add',
listView: true,
args: [
'name', 'provider', 'address', 'type', 'mountopts', 'zoneid', 'crosszoneinstancecreation'
],
mapping: {
type: {
options: ['nfs', 'cifs', 'ceph']
},
provider: {
value: (record) => { return 'nas' }
}
}
},
{
api: 'updateBackupRepository',
icon: 'edit-outlined',
label: 'label.backup.repository.edit',
message: 'message.action.edit.backup.repository',
args: ['name', 'address', 'mountopts', 'crosszoneinstancecreation'],
dataView: true,
popup: true
},
{
api: 'deleteBackupRepository',
icon: 'delete-outlined',
label: 'label.backup.repository.remove',
message: 'message.action.delete.backup.repository',
dataView: true,
popup: true
}
]
}

View File

@ -156,7 +156,7 @@
v-if="routes[section]">
<chart-card :loading="loading">
<div class="chart-card-inner">
<router-link :to="{ name: section.substring(0, section.length - 1) }">
<router-link :to="{ name: section === 'backuprepositories' ? 'backuprepository' : section.substring(0, section.length - 1) }">
<h2>{{ $t(routes[section].title) }}</h2>
<h2><render-icon :icon="routes[section].icon" /> {{ stats[section] }}</h2>
</router-link>
@ -187,7 +187,7 @@ export default {
return {
loading: true,
routes: {},
sections: ['zones', 'pods', 'clusters', 'hosts', 'storagepools', 'imagestores', 'objectstores', 'systemvms', 'routers', 'cpusockets', 'managementservers', 'alerts', 'ilbvms', 'metrics'],
sections: ['zones', 'pods', 'clusters', 'hosts', 'storagepools', 'imagestores', 'backuprepositories', 'objectstores', 'systemvms', 'routers', 'cpusockets', 'managementservers', 'alerts', 'ilbvms', 'metrics'],
sslFormVisible: false,
stats: {},
intermediateCertificates: [],
@ -216,10 +216,11 @@ export default {
fetchData () {
this.routes = {}
for (const section of this.sections) {
if (router.resolve('/' + section.substring(0, section.length - 1)).matched[0].redirect === '/exception/404') {
const route = section === 'backuprepositories' ? 'backuprepository' : section.substring(0, section.length - 1)
if (router.resolve('/' + route).matched[0].redirect === '/exception/404') {
continue
}
const node = router.resolve({ name: section.substring(0, section.length - 1) })
const node = router.resolve({ name: route })
this.routes[section] = {
title: node.meta.title,
icon: node.meta.icon