fixed 打包后访问权限问题,升级1.0.8.
This commit is contained in:
20
README.md
20
README.md
@@ -1,7 +1,7 @@
|
||||
# kafka可视化管理平台
|
||||
一款轻量级的kafka可视化管理平台,安装配置快捷、简单易用。
|
||||
为了开发的省事,没有国际化支持,页面只支持中文展示。
|
||||
用过rocketmq-console吧,对,前端展示风格跟那个有点类似。
|
||||
用过rocketmq-console(rocketmq-dashboard)吧,对,前端展示风格跟那个有点类似。
|
||||
|
||||
## 页面预览
|
||||
如果github能查看图片的话,可以点击[查看菜单页面](./document/overview/概览.md),查看每个页面的样子
|
||||
@@ -25,11 +25,11 @@ v1.0.6版本之前,如果kafka集群启用了ACL,但是控制台没看到Acl
|
||||

|
||||
|
||||
## 安装包下载
|
||||
点击下载(v1.0.7版本):[kafka-console-ui.zip](https://github.com/xxd763795151/kafka-console-ui/releases/download/v1.0.7/kafka-console-ui.zip)
|
||||
点击下载(v1.0.8版本):[kafka-console-ui.zip](https://github.com/xxd763795151/kafka-console-ui/releases/download/v1.0.8/kafka-console-ui.zip)
|
||||
|
||||
如果安装包下载的比较慢,可以查看下面的源码打包说明,把代码下载下来,本地快速打包.
|
||||
|
||||
github下载慢也可以试试从gitee下载,点击下载[gitee来源kafka-console-ui.zip](https://gitee.com/xiaodong_xu/kafka-console-ui/releases/download/v1.0.7/kafka-console-ui.zip)
|
||||
github下载慢也可以试试从gitee下载,点击下载[gitee来源kafka-console-ui.zip](https://gitee.com/xiaodong_xu/kafka-console-ui/releases/download/v1.0.8/kafka-console-ui.zip)
|
||||
|
||||
## 快速使用
|
||||
### Windows
|
||||
@@ -79,11 +79,23 @@ sh bin/shutdown.sh
|
||||
如果需要本地开发,开发环境配置查看:[本地开发](./document/develop/开发配置.md)
|
||||
|
||||
## 登录认证和权限
|
||||
目前主分支不支持登录认证,感谢@dongyinuo 同学开发了一版支持登录认证,及相关的按钮权限(主要有两个角色:管理员和普通开发人员)。
|
||||
1.0.7版本及之前,主分支不支持登录认证,感谢@dongyinuo 同学开发了一版支持登录认证,及相关的按钮权限(主要有两个角色:管理员和普通开发人员)。
|
||||
在分支:feature/dongyinuo/20220501/devops 上。
|
||||
如果有需要使用管理台登录认证的,可以切换到这个分支上进行打包,打包方式看 源码打包 说明。
|
||||
默认登录账户:admin/kafka-console-ui521
|
||||
|
||||
目前最新版本主分支已增加登录认证、用户、角色等权限配置,如需开启登录认证,修改配置文件config/application.yml: auth.enable=true(默认 false),如下:
|
||||
```yaml
|
||||
# 权限认证设置,设置为true,需要先登录才能访问
|
||||
auth:
|
||||
enable: true
|
||||
# 登录用户token的过期时间,单位:小时
|
||||
expire-hours: 24
|
||||
```
|
||||
默认有两个登录用户:super-admin/123465,admin/123456,登录成功后在个人设置修改密码。super-admin和admin的唯一区别是super-admin可以增加删除用户,admin不能。如果觉得不合适,请在用户菜单下删除相关用户或角色自行创建合适的角色或用户。
|
||||
注意:不开启登录认证,页面不显示用户菜单,正常现象。
|
||||
|
||||
|
||||
## DockerCompose部署
|
||||
感谢@wdkang123 同学分享的部署方式,如果有需要请查看[DockerCompose部署方式](./document/deploy/docker部署.md)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR=`dirname $0`
|
||||
PROJECT_DIR="$SCRIPT_DIR/.."
|
||||
SCRIPT_DIR=$(dirname "`pwd`/$0")
|
||||
PROJECT_DIR=`dirname "$SCRIPT_DIR"`
|
||||
# 不要修改进程标记,作为进程属性关闭使用
|
||||
PROCESS_FLAG="kafka-console-ui-process-flag:${PROJECT_DIR}"
|
||||
pkill -f $PROCESS_FLAG
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# 设置jvm堆大小及栈大小,栈大小最少设置为256K,不要小于这个值,比如设置为128,太小了
|
||||
JAVA_MEM_OPTS="-Xmx512m -Xms512m -Xmn256m -Xss256k"
|
||||
|
||||
SCRIPT_DIR=`dirname $0`
|
||||
PROJECT_DIR="$SCRIPT_DIR/.."
|
||||
SCRIPT_DIR=$(dirname "`pwd`/$0")
|
||||
PROJECT_DIR=`dirname "$SCRIPT_DIR"`
|
||||
CONF_FILE="$PROJECT_DIR/config/application.yml"
|
||||
TARGET="$PROJECT_DIR/lib/kafka-console-ui.jar"
|
||||
|
||||
|
||||
46
pom.xml
46
pom.xml
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
<groupId>com.xuxd</groupId>
|
||||
<artifactId>kafka-console-ui</artifactId>
|
||||
<version>1.0.7</version>
|
||||
<version>1.0.8</version>
|
||||
<name>kafka-console-ui</name>
|
||||
<description>Kafka console manage ui</description>
|
||||
<properties>
|
||||
@@ -174,26 +174,26 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.codehaus.mojo</groupId>-->
|
||||
<!-- <artifactId>build-helper-maven-plugin</artifactId>-->
|
||||
<!-- <version>3.2.0</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <id>add-source</id>-->
|
||||
<!-- <phase>generate-sources</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>add-source</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <sources>-->
|
||||
<!-- <source>src/main/java</source>-->
|
||||
<!-- <source>src/main/scala</source>-->
|
||||
<!-- </sources>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.codehaus.mojo</groupId>-->
|
||||
<!-- <artifactId>build-helper-maven-plugin</artifactId>-->
|
||||
<!-- <version>3.2.0</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <id>add-source</id>-->
|
||||
<!-- <phase>generate-sources</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>add-source</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <sources>-->
|
||||
<!-- <source>src/main/java</source>-->
|
||||
<!-- <source>src/main/scala</source>-->
|
||||
<!-- </sources>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@@ -201,6 +201,8 @@
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
<!-- <debug>false</debug>-->
|
||||
<!-- <parameters>false</parameters>-->
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -225,7 +227,7 @@
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- <arguments>install --registry=https://registry.npmjs.org/</arguments>-->
|
||||
<!-- <arguments>install --registry=https://registry.npmjs.org/</arguments>-->
|
||||
<arguments>install --registry=https://registry.npm.taobao.org</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@@ -54,12 +54,12 @@ public class AclUserController {
|
||||
|
||||
@Permission("acl:sasl-scram:detail")
|
||||
@GetMapping("/detail")
|
||||
public Object getUserDetail(@RequestParam String username) {
|
||||
public Object getUserDetail(@RequestParam("username") String username) {
|
||||
return aclService.getUserDetail(username);
|
||||
}
|
||||
|
||||
@GetMapping("/scram")
|
||||
public Object getSaslScramUserList(@RequestParam(required = false) String username) {
|
||||
public Object getSaslScramUserList(@RequestParam(required = false, name = "username") String username) {
|
||||
AclEntry entry = new AclEntry();
|
||||
entry.setPrincipal(StringUtils.isNotBlank(username) ? username : null);
|
||||
return aclService.getSaslScramUserList(entry);
|
||||
|
||||
@@ -45,19 +45,19 @@ public class ConsumerController {
|
||||
|
||||
@Permission("group:del")
|
||||
@DeleteMapping("/group")
|
||||
public Object deleteConsumerGroup(@RequestParam String groupId) {
|
||||
public Object deleteConsumerGroup(@RequestParam("groupId") String groupId) {
|
||||
return consumerService.deleteConsumerGroup(groupId);
|
||||
}
|
||||
|
||||
@Permission("group:client")
|
||||
@GetMapping("/member")
|
||||
public Object getConsumerMembers(@RequestParam String groupId) {
|
||||
public Object getConsumerMembers(@RequestParam("groupId") String groupId) {
|
||||
return consumerService.getConsumerMembers(groupId);
|
||||
}
|
||||
|
||||
@Permission("group:consumer-detail")
|
||||
@GetMapping("/detail")
|
||||
public Object getConsumerDetail(@RequestParam String groupId) {
|
||||
public Object getConsumerDetail(@RequestParam("groupId") String groupId) {
|
||||
return consumerService.getConsumerDetail(groupId);
|
||||
}
|
||||
|
||||
@@ -114,19 +114,19 @@ public class ConsumerController {
|
||||
}
|
||||
|
||||
@GetMapping("/topic/list")
|
||||
public Object getSubscribeTopicList(@RequestParam String groupId) {
|
||||
public Object getSubscribeTopicList(@RequestParam("groupId") String groupId) {
|
||||
return consumerService.getSubscribeTopicList(groupId);
|
||||
}
|
||||
|
||||
@Permission({"topic:consumer-detail"})
|
||||
@GetMapping("/topic/subscribed")
|
||||
public Object getTopicSubscribedByGroups(@RequestParam String topic) {
|
||||
public Object getTopicSubscribedByGroups(@RequestParam("topic") String topic) {
|
||||
return consumerService.getTopicSubscribedByGroups(topic);
|
||||
}
|
||||
|
||||
@Permission("group:offset-partition")
|
||||
@GetMapping("/offset/partition")
|
||||
public Object getOffsetPartition(@RequestParam String groupId) {
|
||||
public Object getOffsetPartition(@RequestParam("groupId") String groupId) {
|
||||
return consumerService.getOffsetPartition(groupId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class OperationController {
|
||||
}
|
||||
|
||||
@DeleteMapping("/sync/alignment")
|
||||
public Object deleteAlignment(@RequestParam Long id) {
|
||||
public Object deleteAlignment(@RequestParam("id") Long id) {
|
||||
return operationService.deleteAlignmentById(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class TopicController {
|
||||
|
||||
@Permission("topic:load")
|
||||
@GetMapping("/list")
|
||||
public Object getTopicList(@RequestParam(required = false) String topic, @RequestParam String type) {
|
||||
public Object getTopicList(@RequestParam(required = false, name = "topic") String topic, @RequestParam("type") String type) {
|
||||
return topicService.getTopicList(topic, TopicType.valueOf(type.toUpperCase()));
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class TopicController {
|
||||
|
||||
@Permission("topic:partition-detail")
|
||||
@GetMapping("/partition")
|
||||
public Object getTopicPartitionInfo(@RequestParam String topic) {
|
||||
public Object getTopicPartitionInfo(@RequestParam("topic") String topic) {
|
||||
return topicService.getTopicPartitionInfo(topic.trim());
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class TopicController {
|
||||
}
|
||||
|
||||
@GetMapping("/replica/assignment")
|
||||
public Object getCurrentReplicaAssignment(@RequestParam String topic) {
|
||||
public Object getCurrentReplicaAssignment(@RequestParam("topic") String topic) {
|
||||
return topicService.getCurrentReplicaAssignment(topic);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public class TopicController {
|
||||
|
||||
@Permission("topic:send-count")
|
||||
@GetMapping("/send/stats")
|
||||
public Object sendStats(@RequestParam String topic) {
|
||||
public Object sendStats(@RequestParam("topic") String topic) {
|
||||
return topicService.sendStats(topic);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +73,14 @@ public class UserManageController {
|
||||
@Permission("user-manage:role:del")
|
||||
@ControllerLog("删除角色")
|
||||
@DeleteMapping("/role")
|
||||
public Object deleteRole(@RequestParam Long id) {
|
||||
public Object deleteRole(@RequestParam("id") Long id) {
|
||||
return userManageService.deleteRole(id);
|
||||
}
|
||||
|
||||
@Permission("user-manage:user:del")
|
||||
@ControllerLog("删除用户")
|
||||
@DeleteMapping("/user")
|
||||
public Object deleteUser(@RequestParam Long id) {
|
||||
public Object deleteUser(@RequestParam("id") Long id) {
|
||||
return userManageService.deleteUser(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package com.xuxd.kafka.console.dao.init;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import scala.collection.mutable.StringBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -22,7 +19,7 @@ import java.util.Map;
|
||||
@Slf4j
|
||||
public class SqlParse {
|
||||
|
||||
private final String FILE = "classpath:db/data-h2.sql";
|
||||
private final String FILE = "db/data-h2.sql";
|
||||
|
||||
private final Map<String, List<String>> sqlMap = new HashMap<>();
|
||||
|
||||
@@ -37,8 +34,7 @@ public class SqlParse {
|
||||
|
||||
String table = null;
|
||||
try {
|
||||
File file = ResourceUtils.getFile(FILE);
|
||||
List<String> lines = Files.readLines(file, Charset.forName("UTF-8"));
|
||||
List<String> lines = getSqlLines();
|
||||
for (String str : lines) {
|
||||
if (StringUtils.isNotEmpty(str)) {
|
||||
if (str.indexOf("start--") > 0) {
|
||||
@@ -61,9 +57,7 @@ public class SqlParse {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -82,4 +76,21 @@ public class SqlParse {
|
||||
private boolean isSql(String str) {
|
||||
return StringUtils.isNotEmpty(str) && str.startsWith("insert");
|
||||
}
|
||||
|
||||
private List<String> getSqlLines() throws Exception {
|
||||
// File file = ResourceUtils.getFile(FILE);
|
||||
// List<String> lines = Files.readLines(file, Charset.forName("UTF-8"));
|
||||
List<String> lines = new ArrayList<>();
|
||||
try (InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(FILE)) {
|
||||
try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream)) {
|
||||
try (BufferedReader reader = new BufferedReader(inputStreamReader)) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ public class AuthFilter implements Filter {
|
||||
String accessToken = request.getHeader(TOKEN_HEADER);
|
||||
|
||||
String requestURI = request.getRequestURI();
|
||||
if (isResourceRequest(requestURI)) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
if (requestURI.startsWith(AUTH_URI_PREFIX)) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
@@ -63,8 +67,12 @@ public class AuthFilter implements Filter {
|
||||
try {
|
||||
CredentialsContext.set(credentials);
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}finally {
|
||||
} finally {
|
||||
CredentialsContext.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isResourceRequest(String requestURI) {
|
||||
return requestURI.contains(".") || requestURI.equals("/");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ const errorHandler = (error) => {
|
||||
});
|
||||
Router.push({ path: "/login-page" });
|
||||
} else if (error.response.status == 403) {
|
||||
// const data = error.response.data;
|
||||
// notification.error({
|
||||
// message: error.response.status,
|
||||
// description: data.msg,
|
||||
// });
|
||||
const data = error.response.data;
|
||||
notification.error({
|
||||
message: error.response.status,
|
||||
description: data.msg,
|
||||
});
|
||||
} else {
|
||||
const data = error.response.data;
|
||||
notification.error({
|
||||
|
||||
@@ -160,6 +160,7 @@ import Member from "@/views/group/Member";
|
||||
import ConsumerDetail from "@/views/group/ConsumerDetail";
|
||||
import AddSupscription from "@/views/group/AddSupscription";
|
||||
import OffsetTopicPartition from "@/views/group/OffsetTopicPartition";
|
||||
import { isAuthorized } from "@/utils/auth";
|
||||
|
||||
export default {
|
||||
name: "ConsumerGroup",
|
||||
@@ -235,6 +236,9 @@ export default {
|
||||
});
|
||||
},
|
||||
openConsumerMemberDialog(groupId) {
|
||||
if (!isAuthorized("group:client")) {
|
||||
return;
|
||||
}
|
||||
this.showConsumerGroupDialog = true;
|
||||
this.selectDetail.resourceName = groupId;
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<div class="content" v-action:topic:load>
|
||||
<a-spin :spinning="loading">
|
||||
<div class="topic">
|
||||
<div id="components-form-topic-advanced-search">
|
||||
|
||||
@@ -45,7 +45,11 @@
|
||||
bordered
|
||||
row-key="id"
|
||||
>
|
||||
<div slot="operation" slot-scope="record" v-show="record.username != 'super-admin'">
|
||||
<div
|
||||
slot="operation"
|
||||
slot-scope="record"
|
||||
v-show="record.username != 'super-admin'"
|
||||
>
|
||||
<a-popconfirm
|
||||
:title="'删除用户: ' + record.username + '?'"
|
||||
ok-text="确认"
|
||||
|
||||
Reference in New Issue
Block a user