feature nacos升级到版本2.3.2, 并默认开启nacos服务端授权认证

2.X
OldDriver9527 10 months ago
parent 373a16da1d
commit 8df2bc3020

@ -74,6 +74,8 @@
<nacos.server>127.0.0.1:8848</nacos.server>
<nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group>
<nacos.config.group>DEFAULT_GROUP</nacos.config.group>
<nacos.username>nacos</nacos.username>
<nacos.password>nacos</nacos.password>
<logstash.address>127.0.0.1:4560</logstash.address>
</properties>
<activation>
@ -88,6 +90,8 @@
<nacos.server>127.0.0.1:8848</nacos.server>
<nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group>
<nacos.config.group>DEFAULT_GROUP</nacos.config.group>
<nacos.username>nacos</nacos.username>
<nacos.password>nacos</nacos.password>
<logstash.address>127.0.0.1:4560</logstash.address>
</properties>
</profile>

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -18,7 +18,7 @@
<spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>
<sentinel.version>1.8.6</sentinel.version>
<seata.version>1.7.1</seata.version>
<nacos.client.version>2.2.1</nacos.client.version>
<nacos.client.version>2.3.2</nacos.client.version>
<dubbo.version>3.2.11</dubbo.version>
<spring.context.support.version>1.0.11</spring.context.support.version>
</properties>

@ -15,6 +15,8 @@ dubbo:
registry:
address: nacos://${spring.cloud.nacos.server-addr}
group: DUBBO_GROUP
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
parameters:
namespace: ${spring.profiles.active}
# 消费者相关配置

@ -7,6 +7,8 @@ seata:
server-addr: ${spring.cloud.nacos.server-addr}
group: ${spring.cloud.nacos.config.group}
namespace: ${spring.profiles.active}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
data-id: seata-server.properties
registry:
type: nacos
@ -14,6 +16,8 @@ seata:
application: ruoyi-seata-server
server-addr: ${spring.cloud.nacos.server-addr}
group: ${spring.cloud.nacos.discovery.group}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
namespace: ${spring.profiles.active}
# 关闭自动代理
enable-auto-data-source-proxy: false

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -94,6 +94,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -19,6 +19,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -45,6 +45,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -17,6 +17,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -27,7 +27,7 @@
<packaging>jar</packaging>
<properties>
<nacos.version>2.2.1</nacos.version>
<nacos.version>2.3.2</nacos.version>
<!-- 需要与 Nacos 内置 Boot 版本保持一致 -->
<spring-boot.version>2.7.18</spring-boot.version>
<spring-boot-admin.version>2.7.11</spring-boot-admin.version>
@ -76,6 +76,13 @@
<scope>system</scope>
<systemPath>${nacos.lib.path}/nacos-config-${nacos.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-persistence</artifactId>
<version>${nacos.version}</version>
<scope>system</scope>
<systemPath>${nacos.lib.path}/nacos-persistence-${nacos.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-consistency</artifactId>
@ -85,10 +92,17 @@
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-contrl-plugin</artifactId>
<artifactId>nacos-control-plugin</artifactId>
<version>${nacos.version}</version>
<scope>system</scope>
<systemPath>${nacos.lib.path}/nacos-control-plugin-${nacos.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-config-plugin</artifactId>
<version>${nacos.version}</version>
<scope>system</scope>
<systemPath>${nacos.lib.path}/nacos-contrl-plugin-${nacos.version}.jar</systemPath>
<systemPath>${nacos.lib.path}/nacos-config-plugin-${nacos.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
@ -113,10 +127,17 @@
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-plugin-default-impl</artifactId>
<artifactId>default-auth-plugin</artifactId>
<version>${nacos.version}</version>
<scope>system</scope>
<systemPath>${nacos.lib.path}/nacos-plugin-default-impl-${nacos.version}.jar</systemPath>
<systemPath>${nacos.lib.path}/default-auth-plugin-${nacos.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>default-control-plugin</artifactId>
<version>${nacos.version}</version>
<scope>system</scope>
<systemPath>${nacos.lib.path}/default-control-plugin-${nacos.version}.jar</systemPath>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
@ -227,10 +248,6 @@
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-grpc-impl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
@ -245,10 +262,6 @@
<artifactId>jjwt-jackson</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>

@ -16,17 +16,30 @@
package com.alibaba.nacos;
import com.alibaba.nacos.sys.filter.NacosTypeExcludeFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* Nacos starter.
* <p>
* Use @SpringBootApplication and @ComponentScan at the same time, using CUSTOM type filter to control module enabled.
* </p>
*
* @author nacos
*/
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
@SpringBootApplication
@ComponentScan(basePackages = "com.alibaba.nacos", excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = {NacosTypeExcludeFilter.class}),
@Filter(type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}),
@Filter(type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class})})
@ServletComponentScan
@EnableScheduling
public class Nacos {

@ -19,6 +19,7 @@ package com.alibaba.nacos.console.config;
import com.alibaba.nacos.console.filter.XssFilter;
import com.alibaba.nacos.core.code.ControllerMethodsCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
@ -42,10 +43,13 @@ import java.time.ZoneId;
@EnableScheduling
@PropertySource("/application.properties")
public class ConsoleConfig {
@Autowired
private ControllerMethodsCache methodsCache;
@Value("${nacos.console.ui.enabled:true}")
private boolean consoleUiEnabled;
/**
* Init.
*/
@ -56,7 +60,7 @@ public class ConsoleConfig {
methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller");
methodsCache.initClassMethod("com.alibaba.nacos.console.controller");
}
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
@ -69,14 +73,18 @@ public class ConsoleConfig {
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Bean
public XssFilter xssFilter() {
return new XssFilter();
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(ZoneId.systemDefault().toString());
}
public boolean isConsoleUiEnabled() {
return consoleUiEnabled;
}
}

@ -0,0 +1,44 @@
/*
* Copyright 1999-2023 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.config;
import com.alibaba.nacos.sys.module.ModuleState;
import com.alibaba.nacos.sys.module.ModuleStateBuilder;
import com.alibaba.nacos.sys.utils.ApplicationUtils;
/**
* Console module state builder.
*
* @author xiweng.yy
*/
public class ConsoleModuleStateBuilder implements ModuleStateBuilder {
public static final String CONSOLE_MODULE = "console";
private static final String CONSOLE_UI_ENABLED = "console_ui_enabled";
@Override
public ModuleState build() {
ModuleState result = new ModuleState(CONSOLE_MODULE);
try {
ConsoleConfig consoleConfig = ApplicationUtils.getBean(ConsoleConfig.class);
result.newState(CONSOLE_UI_ENABLED, consoleConfig.isConsoleUiEnabled());
} catch (Exception ignored) {
}
return result;
}
}

@ -16,11 +16,10 @@
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.naming.controllers.OperatorController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.core.cluster.health.ModuleHealthCheckerHolder;
import com.alibaba.nacos.core.cluster.health.ReadinessResult;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@ -36,20 +35,9 @@ import javax.servlet.http.HttpServletRequest;
*/
@RestController("consoleHealth")
@RequestMapping("/v1/console/health")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class HealthController {
private static final Logger LOGGER = LoggerFactory.getLogger(HealthController.class);
private final ConfigInfoPersistService configInfoPersistService;
private final OperatorController apiCommands;
@Autowired
public HealthController(ConfigInfoPersistService configInfoPersistService, OperatorController apiCommands) {
this.configInfoPersistService = configInfoPersistService;
this.apiCommands = apiCommands;
}
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted.
*
@ -60,7 +48,7 @@ public class HealthController {
public ResponseEntity<String> liveness() {
return ResponseEntity.ok().body("OK");
}
/**
* Ready to receive the request or not.
*
@ -69,42 +57,11 @@ public class HealthController {
*/
@GetMapping("/readiness")
public ResponseEntity<String> readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request);
if (isConfigReadiness && isNamingReadiness) {
ReadinessResult result = ModuleHealthCheckerHolder.getInstance().checkReadiness();
if (result.isSuccess()) {
return ResponseEntity.ok().body("OK");
}
if (!isConfigReadiness && !isNamingReadiness) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config and Naming are not in readiness");
}
if (!isConfigReadiness) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config is not in readiness");
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Naming is not in readiness");
}
private boolean isConfigReadiness() {
// check db
try {
configInfoPersistService.configInfoCount("");
return true;
} catch (Exception e) {
LOGGER.error("Config health check fail.", e);
}
return false;
}
private boolean isNamingReadiness(HttpServletRequest request) {
try {
apiCommands.metrics(request);
return true;
} catch (Exception e) {
LOGGER.error("Naming health check fail.", e);
}
return false;
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result.getResultMessage());
}
}

@ -21,10 +21,11 @@ import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.service.repository.CommonPersistService;
import com.alibaba.nacos.console.model.Namespace;
import com.alibaba.nacos.console.model.NamespaceAllInfo;
import com.alibaba.nacos.console.service.NamespaceOperationService;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
import com.alibaba.nacos.core.namespace.model.Namespace;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import com.alibaba.nacos.core.service.NamespaceOperationService;
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
import org.springframework.beans.factory.annotation.Autowired;
@ -47,18 +48,21 @@ import java.util.regex.Pattern;
*/
@RestController
@RequestMapping("/v1/console/namespaces")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class NamespaceController {
@Autowired
private CommonPersistService commonPersistService;
private NamespacePersistService namespacePersistService;
@Autowired
private NamespaceOperationService namespaceOperationService;
private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
private final Pattern namespaceNameCheckPattern = Pattern.compile("^[^@#$%^&*]+$");
private static final int NAMESPACE_ID_MAX_LENGTH = 128;
/**
* Get namespace list.
*
@ -68,7 +72,7 @@ public class NamespaceController {
public RestResult<List<Namespace>> getNamespaces() {
return RestResultUtils.success(namespaceOperationService.getNamespaceList());
}
/**
* get namespace all info by namespace id.
*
@ -76,10 +80,10 @@ public class NamespaceController {
* @return namespace all info
*/
@GetMapping(params = "show=all")
public NamespaceAllInfo getNamespace(@RequestParam("namespaceId") String namespaceId) throws NacosException {
public Namespace getNamespace(@RequestParam("namespaceId") String namespaceId) throws NacosException {
return namespaceOperationService.getNamespace(namespaceId);
}
/**
* create namespace.
*
@ -90,8 +94,8 @@ public class NamespaceController {
@PostMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean createNamespace(@RequestParam("customNamespaceId") String namespaceId,
@RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
@RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
if (StringUtils.isBlank(namespaceId)) {
namespaceId = UUID.randomUUID().toString();
} else {
@ -102,6 +106,14 @@ public class NamespaceController {
if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
return false;
}
// check unique
if (namespacePersistService.tenantInfoCountByTenantId(namespaceId) > 0) {
return false;
}
}
// contains illegal chars
if (!namespaceNameCheckPattern.matcher(namespaceName).matches()) {
return false;
}
try {
return namespaceOperationService.createNamespace(namespaceId, namespaceName, namespaceDesc);
@ -109,7 +121,7 @@ public class NamespaceController {
return false;
}
}
/**
* check namespaceId exist.
*
@ -121,9 +133,9 @@ public class NamespaceController {
if (StringUtils.isBlank(namespaceId)) {
return false;
}
return (commonPersistService.tenantInfoCountByTenantId(namespaceId) > 0);
return (namespacePersistService.tenantInfoCountByTenantId(namespaceId) > 0);
}
/**
* edit namespace.
*
@ -135,11 +147,15 @@ public class NamespaceController {
@PutMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean editNamespace(@RequestParam("namespace") String namespace,
@RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
@RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// contains illegal chars
if (!namespaceNameCheckPattern.matcher(namespaceShowName).matches()) {
return false;
}
return namespaceOperationService.editNamespace(namespace, namespaceShowName, namespaceDesc);
}
/**
* del namespace by id.
*
@ -151,5 +167,5 @@ public class NamespaceController {
public Boolean deleteNamespace(@RequestParam("namespaceId") String namespaceId) {
return namespaceOperationService.removeNamespace(namespaceId);
}
}

@ -16,16 +16,28 @@
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.utils.VersionUtils;
import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import com.alibaba.nacos.sys.env.EnvUtil;
import com.alibaba.nacos.sys.module.ModuleState;
import com.alibaba.nacos.sys.module.ModuleStateHolder;
import com.alibaba.nacos.sys.utils.DiskUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import static com.alibaba.nacos.common.utils.StringUtils.FOLDER_SEPARATOR;
import static com.alibaba.nacos.common.utils.StringUtils.TOP_PATH;
import static com.alibaba.nacos.common.utils.StringUtils.WINDOWS_FOLDER_SEPARATOR;
/**
* Server state controller.
*
@ -33,8 +45,13 @@ import java.util.Map;
*/
@RestController
@RequestMapping("/v1/console/server")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class ServerStateController {
private static final String ANNOUNCEMENT_FILE = "announcement.conf";
private static final String GUIDE_FILE = "console-guide.conf";
/**
* Get server state of current server.
*
@ -43,13 +60,34 @@ public class ServerStateController {
@GetMapping("/state")
public ResponseEntity<Map<String, String>> serverState() {
Map<String, String> serverState = new HashMap<>(4);
serverState.put("standalone_mode",
EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER);
serverState.put("function_mode", EnvUtil.getFunctionMode());
serverState.put("version", VersionUtils.version);
for (ModuleState each : ModuleStateHolder.getInstance().getAllModuleStates()) {
each.getStates().forEach((s, o) -> serverState.put(s, null == o ? null : o.toString()));
}
return ResponseEntity.ok().body(serverState);
}
@GetMapping("/announcement")
public RestResult<String> getAnnouncement(
@RequestParam(required = false, name = "language", defaultValue = "zh-CN") String language) {
String file = ANNOUNCEMENT_FILE.substring(0, ANNOUNCEMENT_FILE.length() - 5) + "_" + language + ".conf";
if (file.contains(TOP_PATH) || file.contains(FOLDER_SEPARATOR) || file.contains(WINDOWS_FOLDER_SEPARATOR)) {
throw new IllegalArgumentException("Invalid filename");
}
File announcementFile = new File(EnvUtil.getConfPath(), file);
String announcement = null;
if (announcementFile.exists() && announcementFile.isFile()) {
announcement = DiskUtils.readFile(announcementFile);
}
return RestResultUtils.success(announcement);
}
@GetMapping("/guide")
public RestResult<String> getConsoleUiGuide() {
File guideFile = new File(EnvUtil.getConfPath(), GUIDE_FILE);
String guideInformation = null;
if (guideFile.exists() && guideFile.isFile()) {
guideInformation = DiskUtils.readFile(guideFile);
}
return RestResultUtils.success(guideInformation);
}
}

@ -0,0 +1,66 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.controller.v2;
import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.core.cluster.health.ModuleHealthCheckerHolder;
import com.alibaba.nacos.core.cluster.health.ReadinessResult;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* Health ControllerV2.
*
* @author DiligenceLai
*/
@RestController("consoleHealthV2")
@RequestMapping("/v2/console/health")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class HealthControllerV2 {
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted.
*
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states.
*/
@GetMapping("/liveness")
public Result<String> liveness() {
return Result.success("ok");
}
/**
* Ready to receive the request or not.
*
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready.
*/
@GetMapping("/readiness")
public Result<String> readiness(HttpServletRequest request) {
ReadinessResult result = ModuleHealthCheckerHolder.getInstance().checkReadiness();
if (result.isSuccess()) {
return Result.success("ok");
}
return Result.failure(result.getResultMessage());
}
}

@ -23,10 +23,12 @@ import com.alibaba.nacos.api.model.v2.ErrorCode;
import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.console.model.Namespace;
import com.alibaba.nacos.console.model.NamespaceAllInfo;
import com.alibaba.nacos.console.model.form.NamespaceForm;
import com.alibaba.nacos.console.service.NamespaceOperationService;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.core.namespace.model.Namespace;
import com.alibaba.nacos.core.namespace.model.form.NamespaceForm;
import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import com.alibaba.nacos.core.service.NamespaceOperationService;
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
import com.alibaba.nacos.plugin.auth.constant.SignType;
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
@ -52,18 +54,24 @@ import java.util.regex.Pattern;
@NacosApi
@RestController
@RequestMapping("/v2/console/namespace")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class NamespaceControllerV2 {
private final NamespaceOperationService namespaceOperationService;
public NamespaceControllerV2(NamespaceOperationService namespaceOperationService) {
private NamespacePersistService namespacePersistService;
public NamespaceControllerV2(NamespaceOperationService namespaceOperationService, NamespacePersistService namespacePersistService) {
this.namespaceOperationService = namespaceOperationService;
this.namespacePersistService = namespacePersistService;
}
private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
private final Pattern namespaceNameCheckPattern = Pattern.compile("^[^@#$%^&*]+$");
private static final int NAMESPACE_ID_MAX_LENGTH = 128;
/**
* Get namespace list.
*
@ -73,7 +81,7 @@ public class NamespaceControllerV2 {
public Result<List<Namespace>> getNamespaceList() {
return Result.success(namespaceOperationService.getNamespaceList());
}
/**
* get namespace all info by namespace id.
*
@ -82,12 +90,11 @@ public class NamespaceControllerV2 {
*/
@GetMapping()
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.READ, signType = SignType.CONSOLE)
public Result<NamespaceAllInfo> getNamespace(@RequestParam("namespaceId") String namespaceId)
throws NacosException {
+ "namespaces", action = ActionTypes.READ, signType = SignType.CONSOLE)
public Result<Namespace> getNamespace(@RequestParam("namespaceId") String namespaceId) throws NacosException {
return Result.success(namespaceOperationService.getNamespace(namespaceId));
}
/**
* create namespace.
*
@ -96,31 +103,41 @@ public class NamespaceControllerV2 {
*/
@PostMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
public Result<Boolean> createNamespace(NamespaceForm namespaceForm) throws NacosException {
namespaceForm.validate();
String namespaceId = namespaceForm.getNamespaceId();
String namespaceName = namespaceForm.getNamespaceName();
String namespaceDesc = namespaceForm.getNamespaceDesc();
if (StringUtils.isBlank(namespaceId)) {
namespaceId = UUID.randomUUID().toString();
} else {
namespaceId = namespaceId.trim();
if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"namespaceId [" + namespaceId + "] mismatch the pattern");
"namespaceId [" + namespaceId + "] mismatch the pattern");
}
if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"too long namespaceId, over " + NAMESPACE_ID_MAX_LENGTH);
"too long namespaceId, over " + NAMESPACE_ID_MAX_LENGTH);
}
// check unique
if (namespacePersistService.tenantInfoCountByTenantId(namespaceId) > 0) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"the namespaceId is existed, namespaceId: " + namespaceForm.getNamespaceId());
}
}
// contains illegal chars
if (!namespaceNameCheckPattern.matcher(namespaceName).matches()) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"namespaceName [" + namespaceName + "] contains illegal char");
}
return Result.success(namespaceOperationService.createNamespace(namespaceId, namespaceName, namespaceDesc));
}
/**
* edit namespace.
*
@ -129,14 +146,19 @@ public class NamespaceControllerV2 {
*/
@PutMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
public Result<Boolean> editNamespace(NamespaceForm namespaceForm) throws NacosException {
namespaceForm.validate();
// contains illegal chars
if (!namespaceNameCheckPattern.matcher(namespaceForm.getNamespaceName()).matches()) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"namespaceName [" + namespaceForm.getNamespaceName() + "] contains illegal char");
}
return Result.success(namespaceOperationService
.editNamespace(namespaceForm.getNamespaceId(), namespaceForm.getNamespaceName(),
namespaceForm.getNamespaceDesc()));
.editNamespace(namespaceForm.getNamespaceId(), namespaceForm.getNamespaceName(),
namespaceForm.getNamespaceDesc()));
}
/**
* delete namespace by id.
*
@ -145,7 +167,7 @@ public class NamespaceControllerV2 {
*/
@DeleteMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
public Result<Boolean> deleteNamespace(@RequestParam("namespaceId") String namespaceId) {
return Result.success(namespaceOperationService.removeNamespace(namespaceId));
}

@ -1,66 +0,0 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.enums;
/**
* the enum of namespace.
* 0 : Global configuration 1 : Default private namespace 2 : Custom namespace.
*
* @author chenglu
* @date 2021-05-25 17:01
*/
public enum NamespaceTypeEnum {
/**
* Global configuration.
*/
GLOBAL(0, "Global configuration"),
/**
* Default private namespace.
*/
PRIVATE(1, "Default private namespace"),
/**
* Custom namespace.
*/
CUSTOM(2, "Custom namespace");
/**
* the namespace type.
*/
private final int type;
/**
* the description.
*/
private final String description;
NamespaceTypeEnum(int type, String description) {
this.type = type;
this.description = description;
}
public int getType() {
return type;
}
public String getDescription() {
return description;
}
}

@ -16,6 +16,7 @@
package com.alibaba.nacos.console.exception;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.plugin.auth.exception.AccessException;
import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.common.utils.ExceptionUtil;
@ -26,6 +27,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
@ -37,28 +39,35 @@ import javax.servlet.http.HttpServletRequest;
*/
@ControllerAdvice
public class ConsoleExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
@ExceptionHandler(AccessException.class)
private ResponseEntity<String> handleAccessException(AccessException e) {
LOGGER.error("got exception. {}", e.getErrMsg());
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
}
@ExceptionHandler(IllegalArgumentException.class)
private ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ExceptionUtil.getAllExceptionMsg(e));
}
@ExceptionHandler(NacosRuntimeException.class)
private ResponseEntity<String> handleNacosRuntimeException(NacosRuntimeException e) {
LOGGER.error("got exception. {}", e.getMessage());
return ResponseEntity.status(e.getErrCode()).body(ExceptionUtil.getAllExceptionMsg(e));
}
@ExceptionHandler(Exception.class)
private ResponseEntity<Object> handleException(HttpServletRequest request, Exception e) {
String uri = request.getRequestURI();
LOGGER.error("CONSOLE {}", uri, e);
if (uri.contains(Commons.NACOS_SERVER_VERSION_V2)) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(RestResultUtils.failed(ExceptionUtil.getAllExceptionMsg(e)));
.body(RestResultUtils.failed(HtmlUtils.htmlEscape(ExceptionUtil.getAllExceptionMsg(e), "utf-8")));
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ExceptionUtil.getAllExceptionMsg(e));
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(HtmlUtils.htmlEscape(ExceptionUtil.getAllExceptionMsg(e), "utf-8"));
}
}

@ -19,6 +19,7 @@ package com.alibaba.nacos.console.exception;
import com.alibaba.nacos.api.annotation.NacosApi;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.api.NacosApiException;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.api.model.v2.ErrorCode;
import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.common.utils.ExceptionUtil;
@ -51,77 +52,83 @@ import java.io.IOException;
@ControllerAdvice(annotations = {NacosApi.class})
@ResponseBody
public class NacosApiExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(NacosApiExceptionHandler.class);
@ExceptionHandler(NacosApiException.class)
public ResponseEntity<Result<String>> handleNacosApiException(NacosApiException e) {
LOGGER.error("got exception. {} {}", e.getErrAbstract(), e.getErrMsg());
return ResponseEntity.status(e.getErrCode()).body(new Result<>(e.getDetailErrCode(), e.getErrAbstract(), e.getErrMsg()));
}
@ExceptionHandler(NacosException.class)
public ResponseEntity<Result<String>> handleNacosException(NacosException e) {
LOGGER.error("got exception. {}", e.getErrMsg());
return ResponseEntity.status(e.getErrCode()).body(Result.failure(ErrorCode.SERVER_ERROR, e.getErrMsg()));
}
@ExceptionHandler(NacosRuntimeException.class)
public ResponseEntity<Result<String>> handleNacosRuntimeException(NacosRuntimeException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return ResponseEntity.status(e.getErrCode()).body(Result.failure(ErrorCode.SERVER_ERROR, e.getMessage()));
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public Result<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.PARAMETER_MISSING, e.getMessage());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageConversionException.class)
public Result<String> handleHttpMessageConversionException(HttpMessageConversionException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(NumberFormatException.class)
public Result<String> handleNumberFormatException(NumberFormatException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public Result<String> handleIllegalArgumentException(IllegalArgumentException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
public Result<String> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.PARAMETER_MISSING, e.getMessage());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMediaTypeException.class)
public Result<String> handleHttpMediaTypeException(HttpMediaTypeException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.MEDIA_TYPE_ERROR, e.getMessage());
}
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(AccessException.class)
public Result<String> handleAccessException(AccessException e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.ACCESS_DENIED, e.getErrMsg());
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = {DataAccessException.class, ServletException.class, IOException.class})
public Result<String> handleDataAccessException(Exception e) {
LOGGER.error("got exception. {} {}", e.getMessage(), ExceptionUtil.getAllExceptionMsg(e));
return Result.failure(ErrorCode.DATA_ACCESS_ERROR, e.getMessage());
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public Result<String> handleOtherException(Exception e) {

@ -29,15 +29,15 @@ import java.io.IOException;
* @author onewe
*/
public class XssFilter extends OncePerRequestFilter {
private static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy";
private static final String CONTENT_SECURITY_POLICY = "script-src 'self'";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
throws ServletException, IOException {
response.setHeader(CONTENT_SECURITY_POLICY_HEADER, CONTENT_SECURITY_POLICY);
filterChain.doFilter(request, response);
}

@ -1,115 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.model;
/**
* Namespace.
*
* @author diamond
*/
public class Namespace {
private String namespace;
private String namespaceShowName;
private String namespaceDesc;
private int quota;
private int configCount;
/**
* see {@link com.alibaba.nacos.console.enums.NamespaceTypeEnum}.
*/
private int type;
public String getNamespaceShowName() {
return namespaceShowName;
}
public void setNamespaceShowName(String namespaceShowName) {
this.namespaceShowName = namespaceShowName;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public Namespace() {
}
public Namespace(String namespace, String namespaceShowName) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
}
public Namespace(String namespace, String namespaceShowName, int quota, int configCount, int type) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
this.quota = quota;
this.configCount = configCount;
this.type = type;
}
public Namespace(String namespace, String namespaceShowName, String namespaceDesc, int quota, int configCount,
int type) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
this.quota = quota;
this.configCount = configCount;
this.type = type;
this.namespaceDesc = namespaceDesc;
}
public String getNamespaceDesc() {
return namespaceDesc;
}
public void setNamespaceDesc(String namespaceDesc) {
this.namespaceDesc = namespaceDesc;
}
public int getQuota() {
return quota;
}
public void setQuota(int quota) {
this.quota = quota;
}
public int getConfigCount() {
return configCount;
}
public void setConfigCount(int configCount) {
this.configCount = configCount;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

@ -1,31 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.model;
/**
* all namespace info.
*
* @author Nacos
*/
public class NamespaceAllInfo extends Namespace {
public NamespaceAllInfo(String namespace, String namespaceShowName, int quota, int configCount, int type,
String namespaceDesc) {
super(namespace, namespaceShowName, namespaceDesc, quota, configCount, type);
}
}

@ -1,111 +0,0 @@
/*
* Copyright 1999-2022 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.model.form;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.api.NacosApiException;
import com.alibaba.nacos.api.model.v2.ErrorCode;
import org.springframework.http.HttpStatus;
import java.io.Serializable;
import java.util.Objects;
/**
* NamespaceForm.
* @author dongyafei
* @date 2022/8/16
*/
public class NamespaceForm implements Serializable {
private static final long serialVersionUID = -1078976569495343487L;
private String namespaceId;
private String namespaceName;
private String namespaceDesc;
public NamespaceForm() {
}
public NamespaceForm(String namespaceId, String namespaceName, String namespaceDesc) {
this.namespaceId = namespaceId;
this.namespaceName = namespaceName;
this.namespaceDesc = namespaceDesc;
}
public String getNamespaceId() {
return namespaceId;
}
public void setNamespaceId(String namespaceId) {
this.namespaceId = namespaceId;
}
public String getNamespaceName() {
return namespaceName;
}
public void setNamespaceName(String namespaceName) {
this.namespaceName = namespaceName;
}
public String getNamespaceDesc() {
return namespaceDesc;
}
public void setNamespaceDesc(String namespaceDesc) {
this.namespaceDesc = namespaceDesc;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
NamespaceForm that = (NamespaceForm) o;
return Objects.equals(namespaceId, that.namespaceId) && Objects.equals(namespaceName, that.namespaceName)
&& Objects.equals(namespaceDesc, that.namespaceDesc);
}
@Override
public int hashCode() {
return Objects.hash(namespaceId, namespaceName, namespaceDesc);
}
@Override
public String toString() {
return "NamespaceVo{" + "namespaceId='" + namespaceId + '\'' + ", namespaceName='" + namespaceName + '\''
+ ", namespaceDesc='" + namespaceDesc + '\'' + '}';
}
/**
* check required param.
* @throws NacosException NacosException
*/
public void validate() throws NacosException {
if (null == namespaceId) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.PARAMETER_MISSING, "required parameter 'namespaceId' is missing");
}
if (null == namespaceName) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.PARAMETER_MISSING, "required parameter 'namespaceName' is missing");
}
}
}

@ -0,0 +1,56 @@
/*
* Copyright 1999-2023 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.paramcheck;
import com.alibaba.nacos.common.paramcheck.ParamInfo;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.core.paramcheck.AbstractHttpParamExtractor;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* Console default http param extractor.
*
* @author zhuoguang
*/
public class ConsoleDefaultHttpParamExtractor extends AbstractHttpParamExtractor {
@Override
public List<ParamInfo> extractParam(HttpServletRequest request) {
ParamInfo paramInfo = new ParamInfo();
paramInfo.setNamespaceId(getAliasNamespaceId(request));
paramInfo.setNamespaceShowName(getAliasNamespaceShowName(request));
ArrayList<ParamInfo> paramInfos = new ArrayList<>();
paramInfos.add(paramInfo);
return paramInfos;
}
private String getAliasNamespaceId(HttpServletRequest request) {
String namespaceId = request.getParameter("namespaceId");
if (StringUtils.isBlank(namespaceId)) {
namespaceId = request.getParameter("customNamespaceId");
}
return namespaceId;
}
private String getAliasNamespaceShowName(HttpServletRequest request) {
String namespaceShowName = request.getParameter("namespaceName");
return namespaceShowName;
}
}

@ -1,150 +0,0 @@
/*
* Copyright 1999-2022 Alibaba Group Holding Ltd.
*
* Licensed 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.alibaba.nacos.console.service;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.api.NacosApiException;
import com.alibaba.nacos.api.model.v2.ErrorCode;
import com.alibaba.nacos.common.utils.NamespaceUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.config.server.model.TenantInfo;
import com.alibaba.nacos.config.server.service.repository.CommonPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.console.enums.NamespaceTypeEnum;
import com.alibaba.nacos.console.model.Namespace;
import com.alibaba.nacos.console.model.NamespaceAllInfo;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* NamespaceOperationService.
*
* @author dongyafei
* @date 2022/8/16
*/
@Service
public class NamespaceOperationService {
private final ConfigInfoPersistService configInfoPersistService;
private final CommonPersistService commonPersistService;
private static final String DEFAULT_NAMESPACE = "public";
private static final String DEFAULT_NAMESPACE_SHOW_NAME = "Public";
private static final String DEFAULT_NAMESPACE_DESCRIPTION = "Public Namespace";
private static final int DEFAULT_QUOTA = 200;
private static final String DEFAULT_CREATE_SOURCE = "nacos";
private static final String DEFAULT_TENANT = "";
private static final String DEFAULT_KP = "1";
public NamespaceOperationService(ConfigInfoPersistService configInfoPersistService,
CommonPersistService commonPersistService) {
this.configInfoPersistService = configInfoPersistService;
this.commonPersistService = commonPersistService;
}
public List<Namespace> getNamespaceList() {
// TODO 获取用kp
List<TenantInfo> tenantInfos = commonPersistService.findTenantByKp(DEFAULT_KP);
Namespace namespace0 = new Namespace(NamespaceUtil.getNamespaceDefaultId(), DEFAULT_NAMESPACE, DEFAULT_QUOTA,
configInfoPersistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType());
List<Namespace> namespaceList = new ArrayList<>();
namespaceList.add(namespace0);
for (TenantInfo tenantInfo : tenantInfos) {
int configCount = configInfoPersistService.configInfoCount(tenantInfo.getTenantId());
Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(),
tenantInfo.getTenantDesc(), DEFAULT_QUOTA, configCount, NamespaceTypeEnum.CUSTOM.getType());
namespaceList.add(namespaceTmp);
}
return namespaceList;
}
/**
* query namespace by namespace id.
*
* @param namespaceId namespace Id.
* @return NamespaceAllInfo.
*/
public NamespaceAllInfo getNamespace(String namespaceId) throws NacosException {
// TODO 获取用kp
if (StringUtils.isBlank(namespaceId) || namespaceId.equals(NamespaceUtil.getNamespaceDefaultId())) {
return new NamespaceAllInfo(namespaceId, DEFAULT_NAMESPACE_SHOW_NAME, DEFAULT_QUOTA,
configInfoPersistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType(),
DEFAULT_NAMESPACE_DESCRIPTION);
} else {
TenantInfo tenantInfo = commonPersistService.findTenantByKp(DEFAULT_KP, namespaceId);
if (null == tenantInfo) {
throw new NacosApiException(HttpStatus.NOT_FOUND.value(), ErrorCode.NAMESPACE_NOT_EXIST,
"namespaceId [ " + namespaceId + " ] not exist");
}
int configCount = configInfoPersistService.configInfoCount(namespaceId);
return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), DEFAULT_QUOTA, configCount,
NamespaceTypeEnum.CUSTOM.getType(), tenantInfo.getTenantDesc());
}
}
/**
* create namespace.
*
* @param namespaceId namespace ID
* @param namespaceName namespace Name
* @param namespaceDesc namespace Desc
* @return whether create ok
*/
public Boolean createNamespace(String namespaceId, String namespaceName, String namespaceDesc)
throws NacosException {
// TODO 获取用kp
if (commonPersistService.tenantInfoCountByTenantId(namespaceId) > 0) {
throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.NAMESPACE_ALREADY_EXIST,
"namespaceId [" + namespaceId + "] already exist");
}
commonPersistService
.insertTenantInfoAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc, DEFAULT_CREATE_SOURCE,
System.currentTimeMillis());
return true;
}
/**
* edit namespace.
*/
public Boolean editNamespace(String namespaceId, String namespaceName, String namespaceDesc) {
// TODO 获取用kp
commonPersistService.updateTenantNameAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc);
return true;
}
/**
* remove namespace.
*/
public Boolean removeNamespace(String namespaceId) {
commonPersistService.removeTenantInfoAtomic(DEFAULT_KP, namespaceId);
return true;
}
}

@ -0,0 +1,17 @@
#
# Copyright 1999-2023 Alibaba Group Holding Ltd.
#
# Licensed 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.
#
com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor

@ -0,0 +1,17 @@
#
# Copyright 1999-2023 Alibaba Group Holding Ltd.
#
# Licensed 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.
#
com.alibaba.nacos.console.config.ConsoleModuleStateBuilder

@ -15,12 +15,13 @@
#
#*************** Spring Boot Related Configurations ***************#
server.port=8848
### Default web context path:
server.servlet.contextPath=/nacos
### Include message field
server.error.include-message=ON_PARAM
server.error.include-message=ALWAYS
### Default web server port:
server.port=8848
#*************** Network Related Configurations ***************#
### If prefer hostname over ip for Nacos server addresses in cluster.conf:
@ -32,9 +33,9 @@ server.error.include-message=ON_PARAM
spring.application.name=ruoyi-nacos
#*************** Config Module Related Configurations ***************#
### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
spring.sql.init.platform=mysql
# spring.datasource.platform=mysql
nacos.plugin.datasource.log.enabled=true
spring.sql.init.platform=mysql
### Count of DB:
db.num=1
@ -43,15 +44,18 @@ db.url.0=jdbc:mysql://127.0.0.1:3306/ry-config?characterEncoding=utf8&connectTim
db.user.0=root
db.password.0=root
### the maximum retry times for push
nacos.config.push.maxRetryTime=50
#*************** Naming Module Related Configurations ***************#
### Data dispatch task execution period in milliseconds:
# nacos.naming.distro.taskDispatchPeriod=200
### Data count of batch sync task:
# nacos.naming.distro.batchSyncKeyCount=1000
### Retry delay in milliseconds if sync task failed:
# nacos.naming.distro.syncRetryDelay=5000
### If enable data warmup. If set to false, the server would accept request without local data preparation:
# nacos.naming.data.warmup=true
@ -100,6 +104,18 @@ management.metrics.export.influx.enabled=false
#management.metrics.export.influx.consistency=one
#management.metrics.export.influx.compressed=true
#*************** Access Log Related Configurations ***************#
### If turn on the access log:
server.tomcat.accesslog.enabled=true
### accesslog automatic cleaning time
server.tomcat.accesslog.max-days=30
### The access log pattern:
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
### The directory of access log:
server.tomcat.basedir=file:.
#*************** Access Control Related Configurations ***************#
### If enable spring security, this option is deprecated in 1.2.0:
#spring.security.enabled=false
@ -111,7 +127,7 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/
nacos.core.auth.system.type=nacos
### If turn on auth system:
nacos.core.auth.enabled=false
nacos.core.auth.enabled=true
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=true
@ -142,8 +158,32 @@ nacos.core.auth.plugin.nacos.token.secret.key=SecretKey0123456789012345678901234
#nacos.core.auth.ldap.userdn=cn={0},dc=example,dc=org
#nacos.core.auth.ldap.filter.prefix=uid
#nacos.core.auth.ldap.case.sensitive=true
#nacos.core.auth.ldap.ignore.partial.result.exception=false
#*************** Control Plugin Related Configurations ***************#
# plugin type
#nacos.plugin.control.manager.type=nacos
# local control rule storage dir, default ${nacos.home}/data/connection and ${nacos.home}/data/tps
#nacos.plugin.control.rule.local.basedir=${nacos.home}
# external control rule storage type, if exist
#nacos.plugin.control.rule.external.storage=
#*************** Config Change Plugin Related Configurations ***************#
# webhook
#nacos.core.config.plugin.webhook.enabled=false
# It is recommended to use EB https://help.aliyun.com/document_detail/413974.html
#nacos.core.config.plugin.webhook.url=http://localhost:8080/webhook/send?token=***
# The content push max capacity ,byte
#nacos.core.config.plugin.webhook.contentMaxCapacity=102400
# whitelist
#nacos.core.config.plugin.whitelist.enabled=false
# The import file suffixs
#nacos.core.config.plugin.whitelist.suffixs=xml,text,properties,yaml,html
# fileformatcheck,which validate the import file of type and content
#nacos.core.config.plugin.fileformatcheck.enabled=false
#*************** Istio Related Configurations ***************#
### If turn on the MCP server:
nacos.istio.mcp.server.enabled=false

File diff suppressed because one or more lines are too long

@ -35,7 +35,7 @@
<link rel="stylesheet" type="text/css" href="console-ui/public/css/icon.css">
<link rel="stylesheet" type="text/css" href="console-ui/public/css/font-awesome.css">
<!-- 第三方css结束 -->
<link href="./css/main.css?9f68bc0e1a07ae7085fe" rel="stylesheet"></head>
<link href="./css/main.css?aaab5fd5630d74e778ed" rel="stylesheet"></head>
<body>
<div id="root" style="overflow:hidden"></div>
@ -56,6 +56,6 @@
<script src="console-ui/public/js/merge.js"></script>
<script src="console-ui/public/js/loader.js"></script>
<!-- 第三方js结束 -->
<script type="text/javascript" src="./js/main.js?9f68bc0e1a07ae7085fe"></script></body>
<script type="text/javascript" src="./js/main.js?aaab5fd5630d74e778ed"></script></body>
</html>

File diff suppressed because one or more lines are too long

@ -33,6 +33,8 @@ management.health.mongo.enabled=${oms.mongodb.enable}
# nacos 配置
spring.cloud.nacos.server-addr=@nacos.server@
spring.cloud.nacos.username=@nacos.username@
spring.cloud.nacos.password=@nacos.password@
spring.cloud.nacos.discovery.group=@nacos.discovery.group@
spring.cloud.nacos.discovery.namespace=${spring.profiles.active}
spring.cloud.nacos.config.group=@nacos.config.group@

@ -32,8 +32,8 @@ seata:
server-addr: @nacos.server@
group: @nacos.discovery.group@
namespace: ${spring.profiles.active}
username:
password:
username: @nacos.username@
password: @nacos.password@
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key: ""
#secret-key: ""
@ -47,8 +47,8 @@ seata:
group: @nacos.discovery.group@
namespace: ${spring.profiles.active}
cluster: default
username:
password:
username: @nacos.username@
password: @nacos.password@
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key: ""
#secret-key: ""

@ -21,6 +21,8 @@ spring:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@

@ -13,21 +13,21 @@ USE `ry-config`;
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`group_id` varchar(128) DEFAULT NULL COMMENT 'group_id',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
`encrypted_data_key` text COMMENT '',
`c_desc` varchar(256) DEFAULT NULL COMMENT 'configuration description',
`c_use` varchar(64) DEFAULT NULL COMMENT 'configuration usage',
`effect` varchar(64) DEFAULT NULL COMMENT '配置生效的描述',
`type` varchar(64) DEFAULT NULL COMMENT '配置的类型',
`c_schema` text COMMENT '配置的模式',
`encrypted_data_key` text NOT NULL COMMENT '',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
@ -60,8 +60,8 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
(110, 'sentinel-ruoyi-gateway.json', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:23:00', '2022-01-09 15:23:00', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '限流策略', NULL, NULL, 'json', NULL, ''),
(111, 'ruoyi-powerjob-server.properties', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', '定时任务控制台', NULL, NULL, 'properties', NULL, ''),
(112, 'seata-server.properties', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'seata配置文件', NULL, NULL, 'properties', NULL, ''),
(113, 'ruoyi-sentinel-dashboard.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'sentinel控制台配置文件', NULL, NULL, 'yaml', NULL, '');
(114, 'ruoyi-easyretry-server.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'dev', 'ER定时任务控制台', NULL, NULL, 'yaml', NULL, ''),
(113, 'ruoyi-sentinel-dashboard.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'sentinel控制台配置文件', NULL, NULL, 'yaml', NULL, ''),
(114, 'ruoyi-easyretry-server.yml', 'DEFAULT_GROUP', '# 将项目路径config/下对应文件中内容复制到此处', '2944a25cb97926efcaa43b3ad7a64cf0', '2022-01-09 15:21:02', '2022-01-09 15:21:02', NULL, '0:0:0:0:0:0:0:1', '', 'prod', 'ER定时任务控制台', NULL, NULL, 'yaml', NULL, '');
/******************************************/
/* 表名称 = config_info_aggr */
@ -69,11 +69,11 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) NOT NULL COMMENT 'group_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
`content` longtext NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
`app_name` varchar(128) DEFAULT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
@ -96,7 +96,7 @@ CREATE TABLE `config_info_beta` (
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` text COMMENT '',
`encrypted_data_key` text NOT NULL COMMENT '',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
@ -131,7 +131,7 @@ CREATE TABLE `config_tags_relation` (
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
`nid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增长标识',
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
@ -159,20 +159,20 @@ CREATE TABLE `group_capacity` (
/* 表名称 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`id` bigint(20) unsigned NOT NULL COMMENT 'id',
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增标识',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(50) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`op_type` char(10) DEFAULT NULL COMMENT 'operation type',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` text COMMENT '',
`encrypted_data_key` text NOT NULL COMMENT '',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
@ -219,21 +219,21 @@ insert into tenant_info(id, kp, tenant_id, tenant_name, tenant_desc, create_sour
(2, '1', 'prod', 'prod', '生产环境', NULL, 1641741270448, 1641741287236);
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
`username` varchar(50) NOT NULL PRIMARY KEY COMMENT 'username',
`password` varchar(500) NOT NULL COMMENT 'password',
`enabled` boolean NOT NULL COMMENT 'enabled'
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL COMMENT 'username',
`role` varchar(50) NOT NULL COMMENT 'role',
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(255) NOT NULL,
`action` varchar(8) NOT NULL,
`role` varchar(50) NOT NULL COMMENT 'role',
`resource` varchar(128) NOT NULL COMMENT 'resource',
`action` varchar(8) NOT NULL COMMENT 'action',
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

Loading…
Cancel
Save