From fb82ca3c918b36692fd0d3f21aa1a73ccd0ba862 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 19 Feb 2025 17:20:26 +0530 Subject: [PATCH] config: fix ManagementServer scope Signed-off-by: Abhishek Kumar --- .../command/admin/config/ListCfgsByCmd.java | 25 ++++-- .../api/command/admin/config/ResetCfgCmd.java | 15 ++++ .../command/admin/config/UpdateCfgCmd.java | 16 +++- ...spring-engine-schema-core-daos-context.xml | 1 + .../META-INF/db/schema-42210to42300.sql | 12 +++ framework/cluster/pom.xml | 6 ++ .../cluster/ManagementServerHostDetailVO.java | 87 +++++++++++++++++++ .../dao/ManagementServerHostDetailsDao.java | 27 ++++++ .../ManagementServerHostDetailsDaoImpl.java | 46 ++++++++++ .../ConfigurationManagerImpl.java | 34 +++++++- .../cloud/server/ManagementServerImpl.java | 6 ++ ui/src/components/view/SettingsTab.vue | 4 + .../config/section/infra/managementServers.js | 4 + 13 files changed, 275 insertions(+), 8 deletions(-) create mode 100644 framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostDetailVO.java create mode 100644 framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDao.java create mode 100644 framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDaoImpl.java diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java index f6f66415f53..a7757cf0ee3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java @@ -19,23 +19,24 @@ package org.apache.cloudstack.api.command.admin.config; import java.util.ArrayList; import java.util.List; -import org.apache.cloudstack.api.ApiErrorCode; -import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.commons.lang3.StringUtils; - import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiArgValidator; import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.ClusterResponse; import org.apache.cloudstack.api.response.ConfigurationResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.ManagementServerResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.config.Configuration; +import org.apache.commons.lang3.StringUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.utils.Pair; @@ -94,6 +95,13 @@ public class ListCfgsByCmd extends BaseListCmd { description = "The ID of the Image Store to update the parameter value for corresponding image store") private Long imageStoreId; + @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID, + type = CommandType.UUID, + entityType = ManagementServerResponse.class, + description = "the ID of the Management Server to update the parameter value for corresponding management server", + since = "4.23.0") + private Long managementServerId; + @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Lists configuration by group name (primarily used for UI)", since = "4.18.0") private String groupName; @@ -139,6 +147,10 @@ public class ListCfgsByCmd extends BaseListCmd { return imageStoreId; } + public Long getManagementServerId() { + return managementServerId; + } + public String getGroupName() { return groupName; } @@ -200,6 +212,9 @@ public class ListCfgsByCmd extends BaseListCmd { if (getImageStoreId() != null){ cfgResponse.setScope("imagestore"); } + if (getManagementServerId() != null){ + cfgResponse.setScope("managementserver"); + } } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java index 2d511cff34d..5e7d38c830f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.cloudstack.api.response.ManagementServerResponse; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.api.response.AccountResponse; @@ -84,6 +85,13 @@ public class ResetCfgCmd extends BaseCmd { description = "The ID of the Image Store to reset the parameter value for corresponding image store") private Long imageStoreId; + @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID, + type = CommandType.UUID, + entityType = ManagementServerResponse.class, + description = "the ID of the Management Server to update the parameter value for corresponding management server", + since = "4.23.0") + private Long managementServerId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -116,6 +124,10 @@ public class ResetCfgCmd extends BaseCmd { return imageStoreId; } + public Long getManagementServerId() { + return managementServerId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -149,6 +161,9 @@ public class ResetCfgCmd extends BaseCmd { if (getImageStoreId() != null) { response.setScope(ConfigKey.Scope.ImageStore.name()); } + if (getManagementServerId() != null) { + response.setScope(ConfigKey.Scope.ManagementServer.name()); + } response.setValue(cfg.second()); this.setResponseObject(response); } else { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java index 97dee8f638a..c6fb62b4ff8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.ClusterResponse; import org.apache.cloudstack.api.response.ConfigurationResponse; import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.cloudstack.api.response.ManagementServerResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.config.Configuration; @@ -88,6 +89,13 @@ public class UpdateCfgCmd extends BaseCmd { validations = ApiArgValidator.PositiveNumber) private Long imageStoreId; + @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID, + type = CommandType.UUID, + entityType = ManagementServerResponse.class, + description = "the ID of the Management Server to update the parameter value for corresponding management server", + since = "4.23.0") + private Long managementServerId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -112,7 +120,7 @@ public class UpdateCfgCmd extends BaseCmd { return clusterId; } - public Long getStoragepoolId() { + public Long getStoragePoolId() { return storagePoolId; } @@ -128,6 +136,10 @@ public class UpdateCfgCmd extends BaseCmd { return imageStoreId; } + public Long getManagementServerId() { + return managementServerId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -182,7 +194,7 @@ public class UpdateCfgCmd extends BaseCmd { if (getClusterId() != null) { response.setScope("cluster"); } - if (getStoragepoolId() != null) { + if (getStoragePoolId() != null) { response.setScope("storagepool"); } if (getAccountId() != null) { diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index fda874745df..0e72337ec45 100644 --- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -116,6 +116,7 @@ + diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql index 47b28964acd..9e928fe0c77 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql @@ -118,6 +118,18 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tin --- Disable/enable NICs CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.nics','enabled', 'TINYINT(1) NOT NULL DEFAULT 1 COMMENT ''Indicates whether the NIC is enabled or not'' '); +-- Add management_server_details table to allow ManagementServer scope configs +CREATE TABLE IF NOT EXISTS `management_server_details` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `management_server_id` bigint unsigned NOT NULL COMMENT 'management server the detail is related to', + `name` varchar(255) NOT NULL COMMENT 'name of the detail', + `value` varchar(255) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'True if the detail can be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_management_server_details__management_server_id` FOREIGN KEY `fk_management_server_details__management_server_id`(`management_server_id`) REFERENCES `mshost`(`id`) ON DELETE CASCADE, + KEY `i_management_server_details__name__value` (`name`(128),`value`(128)) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- Add checkpoint tracking fields to backups table for incremental backup support CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.backups', 'from_checkpoint_id', 'VARCHAR(255) DEFAULT NULL COMMENT "Previous active checkpoint id for incremental backups"'); CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.backups', 'to_checkpoint_id', 'VARCHAR(255) DEFAULT NULL COMMENT "New checkpoint id created for the next incremental backup"'); diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 2dd28e8e628..75bcaf9a7dd 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -48,6 +48,12 @@ cloud-api ${project.version} + + org.apache.cloudstack + cloud-engine-schema + ${project.version} + compile + diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostDetailVO.java b/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostDetailVO.java new file mode 100644 index 00000000000..fcaa2a22e34 --- /dev/null +++ b/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostDetailVO.java @@ -0,0 +1,87 @@ +// 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. + +package com.cloud.cluster; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "management_server_details") +public class ManagementServerHostDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name = "management_server_id") + long resourceId; + + @Column(name = "name") + String name; + + @Column(name = "value") + String value; + + @Column(name = "display") + private boolean display = true; + + public ManagementServerHostDetailVO(long poolId, String name, String value, boolean display) { + this.resourceId = poolId; + this.name = name; + this.value = value; + this.display = display; + } + + public ManagementServerHostDetailVO() { + } + + @Override + public long getId() { + return id; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public String getName() { + return name; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDao.java b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDao.java new file mode 100644 index 00000000000..f3ede42bbe4 --- /dev/null +++ b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDao.java @@ -0,0 +1,27 @@ +// 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. + +package com.cloud.cluster.dao; + +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.cluster.ManagementServerHostDetailVO; +import com.cloud.utils.db.GenericDao; + +public interface ManagementServerHostDetailsDao extends GenericDao, ResourceDetailsDao { +} + diff --git a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDaoImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDaoImpl.java new file mode 100644 index 00000000000..5865bee0926 --- /dev/null +++ b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDetailsDaoImpl.java @@ -0,0 +1,46 @@ +// 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. + +package com.cloud.cluster.dao; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.ScopedConfigStorage; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; + +import com.cloud.cluster.ManagementServerHostDetailVO; + +public class ManagementServerHostDetailsDaoImpl extends ResourceDetailsDaoBase implements ManagementServerHostDetailsDao, ScopedConfigStorage { + + public ManagementServerHostDetailsDaoImpl() { + } + + @Override + public ConfigKey.Scope getScope() { + return ConfigKey.Scope.ManagementServer; + } + + @Override + public String getConfigValue(long id, String key) { + ManagementServerHostDetailVO vo = findDetail(id, key); + return vo == null ? null : vo.getValue(); + } + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new ManagementServerHostDetailVO(resourceId, key, value, display)); + } +} diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index 6da5dda967d..97a1a42b559 100644 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -160,6 +160,9 @@ import com.cloud.api.query.dao.NetworkOfferingJoinDao; import com.cloud.api.query.vo.NetworkOfferingJoinVO; import com.cloud.capacity.CapacityManager; import com.cloud.capacity.dao.CapacityDao; +import com.cloud.cluster.ManagementServerHostVO; +import com.cloud.cluster.dao.ManagementServerHostDao; +import com.cloud.cluster.dao.ManagementServerHostDetailsDao; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterDetailsDao; @@ -469,6 +472,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Inject ImageStoreDetailsDao _imageStoreDetailsDao; @Inject + ManagementServerHostDao managementServerHostDao; + @Inject + ManagementServerHostDetailsDao managementServerHostDetailsDao; + @Inject MessageBus messageBus; @Inject AgentManager _agentManager; @@ -885,6 +892,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } break; + case ManagementServer: + final ManagementServerHostVO managementServer = managementServerHostDao.findById(resourceId); + Preconditions.checkState(managementServer != null); + resourceType = ApiCommandResourceType.ManagementServer; + managementServerHostDetailsDao.addDetail(resourceId, name, value, true); + break; + default: throw new InvalidParameterValueException("Scope provided is invalid"); } @@ -1032,8 +1046,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati String value = cmd.getValue(); final Long zoneId = cmd.getZoneId(); final Long clusterId = cmd.getClusterId(); - final Long storagepoolId = cmd.getStoragepoolId(); + final Long storagepoolId = cmd.getStoragePoolId(); final Long imageStoreId = cmd.getImageStoreId(); + final Long managementServerId = cmd.getManagementServerId(); Long accountId = cmd.getAccountId(); Long domainId = cmd.getDomainId(); // check if config value exists @@ -1113,6 +1128,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati id = imageStoreId; paramCountCheck++; } + if (managementServerId != null) { + scope = ConfigKey.Scope.ManagementServer.toString(); + id = managementServerId; + paramCountCheck++; + } if (paramCountCheck > 1) { throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope"); @@ -1168,6 +1188,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final Long accountId = cmd.getAccountId(); final Long domainId = cmd.getDomainId(); final Long imageStoreId = cmd.getImageStoreId(); + final Long managementServerId = cmd.getManagementServerId(); ConfigKey configKey = null; Optional optionalValue; String defaultValue; @@ -1201,6 +1222,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati scopeMap.put(ConfigKey.Scope.Account.toString(), accountId); scopeMap.put(ConfigKey.Scope.StoragePool.toString(), storagepoolId); scopeMap.put(ConfigKey.Scope.ImageStore.toString(), imageStoreId); + scopeMap.put(ConfigKey.Scope.ManagementServer.toString(), managementServerId); ParamCountPair paramCountPair = getParamCount(scopeMap); id = paramCountPair.getId(); @@ -1297,6 +1319,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati newValue = optionalValue.isPresent() ? optionalValue.get().toString() : defaultValue; break; + case ManagementServer: + final ManagementServerHostVO managementServer = managementServerHostDao.findById(id); + if (managementServer == null) { + throw new InvalidParameterValueException("unable to find management server by id " + id); + } + managementServerHostDetailsDao.removeDetail(id, name); + optionalValue = Optional.ofNullable(configKey != null ? configKey.valueIn(id) : config.getValue()); + newValue = optionalValue.isPresent() ? optionalValue.get().toString() : defaultValue; + break; + default: if (!_configDao.update(name, category, defaultValue)) { logger.error("Failed to reset configuration option, name: {}, defaultValue: {}", name, defaultValue); diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index d4266496e98..f0b257670ef 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -2362,6 +2362,7 @@ public class ManagementServerImpl extends MutualExclusiveIdsManagerBase implemen final Long clusterId = cmd.getClusterId(); final Long storagepoolId = cmd.getStoragepoolId(); final Long imageStoreId = cmd.getImageStoreId(); + final Long managementServerId = cmd.getManagementServerId(); Long accountId = cmd.getAccountId(); Long domainId = cmd.getDomainId(); final String groupName = cmd.getGroupName(); @@ -2415,6 +2416,11 @@ public class ManagementServerImpl extends MutualExclusiveIdsManagerBase implemen id = imageStoreId; paramCountCheck++; } + if (managementServerId != null) { + scope = ConfigKey.Scope.ManagementServer; + id = managementServerId; + paramCountCheck++; + } if (paramCountCheck > 1) { throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope"); diff --git a/ui/src/components/view/SettingsTab.vue b/ui/src/components/view/SettingsTab.vue index 0e0ee33f280..476c20b5c06 100644 --- a/ui/src/components/view/SettingsTab.vue +++ b/ui/src/components/view/SettingsTab.vue @@ -87,6 +87,7 @@ export default { } }, created () { + console.log('---------------', this.$route.meta.name) switch (this.$route.meta.name) { case 'account': this.scopeKey = 'accountid' @@ -106,6 +107,9 @@ export default { case 'imagestore': this.scopeKey = 'imagestoreuuid' break + case 'managementserver': + this.scopeKey = 'managementserverid' + break default: this.scopeKey = '' } diff --git a/ui/src/config/section/infra/managementServers.js b/ui/src/config/section/infra/managementServers.js index d2d11d5b25d..4bf54943fd8 100644 --- a/ui/src/config/section/infra/managementServers.js +++ b/ui/src/config/section/infra/managementServers.js @@ -39,6 +39,10 @@ export default { name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) }, + { + name: 'settings', + component: shallowRef(defineAsyncComponent(() => import('@/components/view/SettingsTab.vue'))) + }, { name: 'management.server.peers', component: shallowRef(defineAsyncComponent(() => import('@/views/infra/ManagementServerPeerTab.vue')))