enable acl switch
This commit is contained in:
16
README.md
16
README.md
@@ -1,13 +1,23 @@
|
|||||||
# kafka可视化管理平台
|
# kafka可视化管理平台
|
||||||
目前支持acl:SASL认证机制及受权管理操作
|
## 功能支持
|
||||||
实现:spring boot + scala + vue + kafka
|
* 基于SASL_SCRAM认证授权管理
|
||||||
|
* Topic管理
|
||||||
|
* 消费组管理
|
||||||
|
* 运维
|
||||||
|
## 技术栈
|
||||||
|
* spring boot
|
||||||
|
* java、scala
|
||||||
|
* kafka
|
||||||
|
* h2
|
||||||
|
* vue
|
||||||
## kafka版本
|
## kafka版本
|
||||||
* kafka 2.8.0
|
* 当前使用的kafka 2.8.0
|
||||||
# 打包、部署
|
# 打包、部署
|
||||||
## 打包
|
## 打包
|
||||||
环境要求
|
环境要求
|
||||||
* maven 3+
|
* maven 3+
|
||||||
* jdk 8
|
* jdk 8
|
||||||
|
* git
|
||||||
```
|
```
|
||||||
git clone https://github.com/xxd763795151/kafka-console-ui.git
|
git clone https://github.com/xxd763795151/kafka-console-ui.git
|
||||||
cd kafka-console-ui
|
cd kafka-console-ui
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public class KafkaConfig {
|
|||||||
|
|
||||||
private String zookeeperAddr;
|
private String zookeeperAddr;
|
||||||
|
|
||||||
|
private boolean enableAcl;
|
||||||
|
|
||||||
public String getBootstrapServer() {
|
public String getBootstrapServer() {
|
||||||
return bootstrapServer;
|
return bootstrapServer;
|
||||||
}
|
}
|
||||||
@@ -102,4 +104,12 @@ public class KafkaConfig {
|
|||||||
public void setZookeeperAddr(String zookeeperAddr) {
|
public void setZookeeperAddr(String zookeeperAddr) {
|
||||||
this.zookeeperAddr = zookeeperAddr;
|
this.zookeeperAddr = zookeeperAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEnableAcl() {
|
||||||
|
return enableAcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableAcl(boolean enableAcl) {
|
||||||
|
this.enableAcl = enableAcl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.xuxd.kafka.console.controller;
|
||||||
|
|
||||||
|
import com.xuxd.kafka.console.beans.ResponseData;
|
||||||
|
import com.xuxd.kafka.console.config.KafkaConfig;
|
||||||
|
import com.xuxd.kafka.console.utils.ConvertUtil;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kafka-console-ui.
|
||||||
|
*
|
||||||
|
* @author xuxd
|
||||||
|
* @date 2021-09-08 16:08:22
|
||||||
|
**/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/config")
|
||||||
|
public class ConfigController {
|
||||||
|
|
||||||
|
private final KafkaConfig config;
|
||||||
|
private final Map<String, Object> configMap;
|
||||||
|
|
||||||
|
public ConfigController(KafkaConfig config) {
|
||||||
|
this.config = config;
|
||||||
|
this.configMap = ConvertUtil.toMap(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public Object getConfig() {
|
||||||
|
return ResponseData.create().data(configMap).success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -208,7 +208,7 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public void afterSingletonsInstantiated() {
|
@Override public void afterSingletonsInstantiated() {
|
||||||
if (kafkaConfig.isAdminCreate()) {
|
if (kafkaConfig.isEnableAcl() && kafkaConfig.isAdminCreate()) {
|
||||||
log.info("Start create admin user, username: {}, password: {}", kafkaConfig.getAdminUsername(), kafkaConfig.getAdminPassword());
|
log.info("Start create admin user, username: {}, password: {}", kafkaConfig.getAdminUsername(), kafkaConfig.getAdminPassword());
|
||||||
boolean done = configConsole.addOrUpdateUserWithZK(kafkaConfig.getAdminUsername(), kafkaConfig.getAdminPassword());
|
boolean done = configConsole.addOrUpdateUserWithZK(kafkaConfig.getAdminUsername(), kafkaConfig.getAdminPassword());
|
||||||
if (!done) {
|
if (!done) {
|
||||||
|
|||||||
40
src/main/java/com/xuxd/kafka/console/utils/ConvertUtil.java
Normal file
40
src/main/java/com/xuxd/kafka/console/utils/ConvertUtil.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package com.xuxd.kafka.console.utils;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kafka-console-ui.
|
||||||
|
*
|
||||||
|
* @author xuxd
|
||||||
|
* @date 2021-09-08 16:21:43
|
||||||
|
**/
|
||||||
|
@Slf4j
|
||||||
|
public class ConvertUtil {
|
||||||
|
|
||||||
|
public static Map<String, Object> toMap(Object src) {
|
||||||
|
Preconditions.checkNotNull(src);
|
||||||
|
Map<String, Object> res = new HashMap<>();
|
||||||
|
for (Class<?> clz = src.getClass(); clz != Object.class; clz = clz.getSuperclass()) {
|
||||||
|
if (ClassUtils.isCglibProxyClass(clz)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Arrays.stream(clz.getDeclaredFields()).forEach(f -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
boolean accessible = f.isAccessible();
|
||||||
|
f.setAccessible(true);
|
||||||
|
res.put(f.getName(), f.get(src));
|
||||||
|
f.setAccessible(accessible);
|
||||||
|
} catch (IllegalAccessException ignore) {
|
||||||
|
log.error("filed: " + f.getName(), ignore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ kafka:
|
|||||||
# kafka broker地址,多个以逗号分隔
|
# kafka broker地址,多个以逗号分隔
|
||||||
bootstrap-server: 'localhost:9092'
|
bootstrap-server: 'localhost:9092'
|
||||||
request-timeout-ms: 60000
|
request-timeout-ms: 60000
|
||||||
|
# 服务端是否启用acl,如果不启用,下面的几项都忽略即可
|
||||||
|
enable-acl: true
|
||||||
security-protocol: SASL_PLAINTEXT
|
security-protocol: SASL_PLAINTEXT
|
||||||
sasl-mechanism: SCRAM-SHA-256
|
sasl-mechanism: SCRAM-SHA-256
|
||||||
# 超级管理员用户名,在broker上已经配置为超级管理员
|
# 超级管理员用户名,在broker上已经配置为超级管理员
|
||||||
|
|||||||
@@ -41,9 +41,11 @@ class KafkaConsole(config: KafkaConfig) {
|
|||||||
val props: Properties = new Properties();
|
val props: Properties = new Properties();
|
||||||
props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, config.getBootstrapServer)
|
props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, config.getBootstrapServer)
|
||||||
props.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, config.getRequestTimeoutMs())
|
props.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, config.getRequestTimeoutMs())
|
||||||
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, config.getSecurityProtocol())
|
if (config.isEnableAcl) {
|
||||||
props.put(SaslConfigs.SASL_MECHANISM, config.getSaslMechanism())
|
props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, config.getSecurityProtocol())
|
||||||
props.put(SaslConfigs.SASL_JAAS_CONFIG, config.getSaslJaasConfig())
|
props.put(SaslConfigs.SASL_MECHANISM, config.getSaslMechanism())
|
||||||
|
props.put(SaslConfigs.SASL_JAAS_CONFIG, config.getSaslJaasConfig())
|
||||||
|
}
|
||||||
|
|
||||||
Admin.create(props)
|
Admin.create(props)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,39 @@
|
|||||||
<div id="app">
|
<div id="app">
|
||||||
<div id="nav">
|
<div id="nav">
|
||||||
<router-link to="/" class="pad-l-r">主页</router-link>
|
<router-link to="/" class="pad-l-r">主页</router-link>
|
||||||
|<router-link to="/acl" class="pad-l-r">Acl</router-link>
|
<span>|</span
|
||||||
<!-- |<router-link-->
|
><router-link to="/topic" class="pad-l-r">Topic</router-link>
|
||||||
<!-- to="/topic"-->
|
<span>|</span
|
||||||
<!-- class="pad-l-r"-->
|
><router-link to="/group" class="pad-l-r">消费组</router-link>
|
||||||
<!-- >主题</router-link-->
|
<span v-show="config.enableAcl">|</span
|
||||||
<!-- >-->
|
><router-link to="/acl" class="pad-l-r" v-show="config.enableAcl"
|
||||||
|
>Acl</router-link
|
||||||
|
>
|
||||||
|
<span>|</span><router-link to="/op" class="pad-l-r">运维</router-link>
|
||||||
</div>
|
</div>
|
||||||
<router-view class="content" />
|
<router-view class="content" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script>
|
||||||
|
import { KafkaAclApi } from "@/utils/api";
|
||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
config: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
request({
|
||||||
|
url: KafkaAclApi.getConfig.url,
|
||||||
|
method: KafkaAclApi.getConfig.method,
|
||||||
|
}).then((res) => {
|
||||||
|
this.config = res.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#app {
|
#app {
|
||||||
|
|||||||
@@ -47,4 +47,8 @@ export const KafkaAclApi = {
|
|||||||
url: "/acl",
|
url: "/acl",
|
||||||
method: "delete",
|
method: "delete",
|
||||||
},
|
},
|
||||||
|
getConfig: {
|
||||||
|
url: "/config",
|
||||||
|
method: "get",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user