kafka acl user search and show list
This commit is contained in:
374
pom.xml
374
pom.xml
@@ -1,194 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.10</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.xuxd</groupId>
|
||||
<artifactId>kafka-console-ui</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>kafka-console-ui</name>
|
||||
<description>Kafka console manage ui</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<ui.path>${project.basedir}/ui</ui.path>
|
||||
<frontend-maven-plugin.version>1.11.0</frontend-maven-plugin.version>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>2.13.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-compiler</artifactId>
|
||||
<version>2.13.6</version>
|
||||
</dependency>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.10</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.xuxd</groupId>
|
||||
<artifactId>kafka-console-ui</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>kafka-console-ui</name>
|
||||
<description>Kafka console manage ui</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<ui.path>${project.basedir}/ui</ui.path>
|
||||
<frontend-maven-plugin.version>1.11.0</frontend-maven-plugin.version>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>2.13.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-compiler</artifactId>
|
||||
<version>2.13.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-clients</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-clients</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>23.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>23.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.20</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.20</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
|
||||
<!-- <sourceDirectory>${basedir}/src/main</sourceDirectory>-->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.scala-tools</groupId>
|
||||
<artifactId>maven-scala-plugin</artifactId>
|
||||
<version>2.15.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>scala-compile-first</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*.scala</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<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>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
</profile>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>${frontend-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<workingDirectory>${ui.path}</workingDirectory>
|
||||
<nodeVersion>v8.17.0</nodeVersion>
|
||||
<downloadRoot>http://npm.taobao.org/mirrors/node/</downloadRoot>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- <execution>-->
|
||||
<!-- <id>install node and npm</id>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>install-node-and-npm</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>install --registry=https://registry.npmjs.org/</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm run build</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run build</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>${basedir}/target/classes/public</targetPath>
|
||||
<directory>${ui.path}/dist</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>${basedir}/target/classes</targetPath>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.scala-tools</groupId>
|
||||
<artifactId>maven-scala-plugin</artifactId>
|
||||
<version>2.15.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>scala-compile-first</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*.scala</include>
|
||||
</includes>
|
||||
</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>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>${frontend-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<workingDirectory>${ui.path}</workingDirectory>
|
||||
<nodeVersion>v8.17.0</nodeVersion>
|
||||
<downloadRoot>http://npm.taobao.org/mirrors/node/</downloadRoot>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- <execution>-->
|
||||
<!-- <id>install node and npm</id>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>install-node-and-npm</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>install --registry=https://registry.npmjs.org/</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm run build</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run build</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>${basedir}/target/classes/public</targetPath>
|
||||
<directory>${ui.path}/dist</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>${basedir}/target/classes</targetPath>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.xuxd.kafka.console.beans;
|
||||
|
||||
import java.util.Objects;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.kafka.common.acl.AccessControlEntry;
|
||||
import org.apache.kafka.common.acl.AccessControlEntryFilter;
|
||||
@@ -21,7 +20,6 @@ import org.apache.kafka.common.security.auth.KafkaPrincipal;
|
||||
* @author xuxd
|
||||
* @date 2021-08-28 20:17:27
|
||||
**/
|
||||
@Data
|
||||
public class AclEntry {
|
||||
|
||||
private String resourceType;
|
||||
@@ -100,4 +98,72 @@ public class AclEntry {
|
||||
entry.setPermissionType(this.permissionType);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(String resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPatternType() {
|
||||
return patternType;
|
||||
}
|
||||
|
||||
public void setPatternType(String patternType) {
|
||||
this.patternType = patternType;
|
||||
}
|
||||
|
||||
public String getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(String principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public String getPermissionType() {
|
||||
return permissionType;
|
||||
}
|
||||
|
||||
public void setPermissionType(String permissionType) {
|
||||
this.permissionType = permissionType;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "AclEntry{" +
|
||||
"resourceType='" + resourceType + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", patternType='" + patternType + '\'' +
|
||||
", principal='" + principal + '\'' +
|
||||
", host='" + host + '\'' +
|
||||
", operation='" + operation + '\'' +
|
||||
", permissionType='" + permissionType + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.xuxd.kafka.console.beans.CounterMap;
|
||||
import com.xuxd.kafka.console.beans.ResponseData;
|
||||
import com.xuxd.kafka.console.service.AclService;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -13,6 +14,7 @@ import java.util.stream.Collectors;
|
||||
import kafka.console.KafkaAclConsole;
|
||||
import kafka.console.KafkaConfigConsole;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.kafka.common.acl.AclBinding;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -35,7 +37,7 @@ public class AclServiceImpl implements AclService {
|
||||
|
||||
@Override public ResponseData<Set<String>> getUserList() {
|
||||
try {
|
||||
return ResponseData.create(Set.class).data(configConsole.getUserList()).success();
|
||||
return ResponseData.create(Set.class).data(configConsole.getUserList(null)).success();
|
||||
} catch (Exception e) {
|
||||
log.error("getUserList error.", e);
|
||||
return ResponseData.create().failed();
|
||||
@@ -60,8 +62,21 @@ public class AclServiceImpl implements AclService {
|
||||
List<AclBinding> aclBindingList = entry.isNull() ? aclConsole.getAclList(null) : aclConsole.getAclList(entry);
|
||||
List<AclEntry> entryList = aclBindingList.stream().map(x -> AclEntry.valueOf(x)).collect(Collectors.toList());
|
||||
Map<String, List<AclEntry>> entryMap = entryList.stream().collect(Collectors.groupingBy(AclEntry::getPrincipal));
|
||||
Map<String, Map<String, List<AclEntry>>> resultMap = new HashMap<>();
|
||||
entryMap.forEach((k, v) -> {
|
||||
Map<String, List<AclEntry>> map = v.stream().collect(Collectors.groupingBy(e -> e.getResourceType() + "#" + e.getName()));
|
||||
resultMap.put(k, map);
|
||||
});
|
||||
if (entry.isNull() || StringUtils.isNotBlank(entry.getPrincipal())) {
|
||||
Set<String> userList = configConsole.getUserList(StringUtils.isNotBlank(entry.getPrincipal()) ? Collections.singletonList(entry.getPrincipal()) : null);
|
||||
userList.forEach(u -> {
|
||||
if (!resultMap.containsKey(u)) {
|
||||
resultMap.put(u, Collections.emptyMap());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return ResponseData.create().data(new CounterMap<>(entryMap)).success();
|
||||
return ResponseData.create().data(new CounterMap<>(resultMap)).success();
|
||||
}
|
||||
|
||||
@Override public ResponseData deleteAcl(AclEntry entry) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
server:
|
||||
port: 7766
|
||||
servlet:
|
||||
context-path: /kafka-console
|
||||
|
||||
kafka:
|
||||
config:
|
||||
|
||||
@@ -41,7 +41,7 @@ class KafkaAclConsole(config: KafkaConfig) extends KafkaConsole(config: KafkaCon
|
||||
}
|
||||
|
||||
var principal: String = null
|
||||
if ( StringUtils.isNotBlank(entry.getPrincipal) && !KafkaPrincipal.ANONYMOUS.toString.equalsIgnoreCase(f.entryFilter().principal())) {
|
||||
if (StringUtils.isNotBlank(entry.getPrincipal()) && !KafkaPrincipal.ANONYMOUS.toString.equalsIgnoreCase(f.entryFilter().principal())) {
|
||||
principal = f.entryFilter().principal();
|
||||
}
|
||||
val filter = new AclBindingFilter(new ResourcePatternFilter(resourceType, name, f.patternFilter().patternType()),
|
||||
|
||||
@@ -17,9 +17,9 @@ class KafkaConfigConsole(config: KafkaConfig) extends KafkaConsole(config: Kafka
|
||||
|
||||
private val defaultIterations = 4096
|
||||
|
||||
def getUserList(): Set[String] = {
|
||||
def getUserList(users: util.List[String]): Set[String] = {
|
||||
withAdminClient({
|
||||
adminClient => adminClient.describeUserScramCredentials().all().get().keySet()
|
||||
adminClient => adminClient.describeUserScramCredentials(users).all().get().keySet()
|
||||
}).asInstanceOf[Set[String]]
|
||||
}
|
||||
|
||||
|
||||
11
ui/package-lock.json
generated
11
ui/package-lock.json
generated
@@ -2587,6 +2587,14 @@
|
||||
"integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
|
||||
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"babel-eslint": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz",
|
||||
@@ -5826,8 +5834,7 @@
|
||||
"follow-redirects": {
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.2.tgz",
|
||||
"integrity": "sha1-zsuCUEfAD15msUL5D+1PUV3seJs=",
|
||||
"dev": true
|
||||
"integrity": "sha1-zsuCUEfAD15msUL5D+1PUV3seJs="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^1.7.8",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.6.5",
|
||||
"moment": "^2.29.1",
|
||||
"vue": "^2.6.11",
|
||||
|
||||
@@ -5,9 +5,11 @@ import store from "./store";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import Antd from "ant-design-vue";
|
||||
import "ant-design-vue/dist/antd.css";
|
||||
import { VueAxios } from "./utils/request";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
Vue.use(Antd);
|
||||
Vue.use(VueAxios);
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
|
||||
33
ui/src/utils/axios.js
Normal file
33
ui/src/utils/axios.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const VueAxios = {
|
||||
vm: {},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
install(Vue, instance) {
|
||||
if (this.installed) {
|
||||
return;
|
||||
}
|
||||
this.installed = true;
|
||||
|
||||
if (!instance) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error("You have to install axios");
|
||||
return;
|
||||
}
|
||||
|
||||
Vue.axios = instance;
|
||||
|
||||
Object.defineProperties(Vue.prototype, {
|
||||
axios: {
|
||||
get: function get() {
|
||||
return instance;
|
||||
},
|
||||
},
|
||||
$http: {
|
||||
get: function get() {
|
||||
return instance;
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export { VueAxios };
|
||||
44
ui/src/utils/request.js
Normal file
44
ui/src/utils/request.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import axios from "axios";
|
||||
import notification from "ant-design-vue/es/notification";
|
||||
import { VueAxios } from "./axios";
|
||||
|
||||
// 创建 axios 实例
|
||||
const request = axios.create({
|
||||
// API 请求的默认前缀
|
||||
baseURL: "/kafka-console",
|
||||
timeout: 10000, // 请求超时时间
|
||||
});
|
||||
|
||||
// 异常拦截处理器
|
||||
const errorHandler = (error) => {
|
||||
if (error.response) {
|
||||
const data = error.response.data;
|
||||
notification.error({
|
||||
message: error.response.status,
|
||||
description: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
// request interceptor
|
||||
// request.interceptors.request.use(config => {
|
||||
//
|
||||
// return config
|
||||
// }, errorHandler)
|
||||
|
||||
// response interceptor
|
||||
request.interceptors.response.use((response) => {
|
||||
return response.data;
|
||||
}, errorHandler);
|
||||
|
||||
const installer = {
|
||||
vm: {},
|
||||
install(Vue) {
|
||||
Vue.use(VueAxios, request);
|
||||
},
|
||||
};
|
||||
|
||||
export default request;
|
||||
|
||||
export { installer as VueAxios, request as axios };
|
||||
@@ -1,6 +1,50 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<div class="acl">
|
||||
<div id="components-form-demo-advanced-search">
|
||||
<a-form
|
||||
class="ant-advanced-search-form"
|
||||
:form="form"
|
||||
@submit="handleSearch"
|
||||
>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="8">
|
||||
<a-form-item :label="`用户名`">
|
||||
<a-input
|
||||
placeholder="username"
|
||||
class="input-w"
|
||||
v-decorator="['username']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :label="`topic`">
|
||||
<a-input
|
||||
placeholder="topic"
|
||||
class="input-w"
|
||||
v-decorator="['topic']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :label="`消费组`">
|
||||
<a-input
|
||||
placeholder="groupId"
|
||||
class="input-w"
|
||||
v-decorator="['groupId']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="24" :style="{ textAlign: 'right' }">
|
||||
<a-button type="primary" html-type="submit"> 搜索 </a-button>
|
||||
<a-button :style="{ marginLeft: '8px' }" @click="handleReset">
|
||||
重置
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<a-table :columns="columns" :data-source="data" bordered>
|
||||
<a slot="operation" slot-scope="{}">删除</a>
|
||||
<!-- <a-table-->
|
||||
@@ -33,19 +77,87 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from "@/utils/request";
|
||||
import notification from "ant-design-vue/es/notification";
|
||||
|
||||
export default {
|
||||
name: "Acl",
|
||||
data() {
|
||||
return {
|
||||
data,
|
||||
queryParam: {},
|
||||
data: [],
|
||||
columns,
|
||||
innerColumns,
|
||||
innerData,
|
||||
form: this.$form.createForm(this, { name: "advanced_search" }),
|
||||
};
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
handleSearch(e) {
|
||||
e.preventDefault();
|
||||
this.form.validateFields((error, values) => {
|
||||
let queryParam = {};
|
||||
if (values.username) {
|
||||
queryParam.username = values.username;
|
||||
}
|
||||
if (values.topic) {
|
||||
queryParam.resourceType = "TOPIC";
|
||||
queryParam.resourceName = values.topic;
|
||||
} else if (values.groupId) {
|
||||
queryParam.resourceType = "GROUP";
|
||||
queryParam.resourceName = values.groupId;
|
||||
}
|
||||
getAclList(this.data, queryParam);
|
||||
});
|
||||
},
|
||||
|
||||
handleReset() {
|
||||
this.form.resetFields();
|
||||
},
|
||||
},
|
||||
created() {
|
||||
getAclList(this.data, this.queryParam);
|
||||
},
|
||||
};
|
||||
|
||||
const api = {
|
||||
getAclList: {
|
||||
url: "/acl/list",
|
||||
method: "post",
|
||||
},
|
||||
};
|
||||
|
||||
function getAclList(data, requestParameters) {
|
||||
request({
|
||||
url: api.getAclList.url,
|
||||
method: api.getAclList.method,
|
||||
data: requestParameters,
|
||||
}).then((response) => {
|
||||
data.splice(0, data.length);
|
||||
if (response.code != 0) {
|
||||
notification.error({
|
||||
message: response.msg,
|
||||
});
|
||||
return;
|
||||
}
|
||||
for (let k in response.data.map) {
|
||||
let v = response.data.map[k];
|
||||
let topicList = Object.keys(v)
|
||||
.filter((e) => e.startsWith("TOPIC"))
|
||||
.map((e) => e.split("#")[1]);
|
||||
let groupList = Object.keys(v)
|
||||
.filter((e) => e.startsWith("GROUP"))
|
||||
.map((e) => e.split("#")[1]);
|
||||
data.push({
|
||||
key: k,
|
||||
username: k,
|
||||
topicList: topicList.join(", "),
|
||||
groupList: groupList.join(", "),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{ title: "用户名", dataIndex: "username", key: "username" },
|
||||
{ title: "topic列表", dataIndex: "topicList", key: "topicList" },
|
||||
@@ -57,20 +169,6 @@ const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
const data = [];
|
||||
for (let i = 0; i < 30; ++i) {
|
||||
data.push({
|
||||
key: i,
|
||||
username: "amdin",
|
||||
topicList: ["test_topic1", "test_topic2", "test_topic3"].join(", "),
|
||||
groupList: [
|
||||
"test_topic1_consumer",
|
||||
"test_topic2_consumer",
|
||||
"test_topic3_consumer",
|
||||
].join(", "),
|
||||
});
|
||||
}
|
||||
|
||||
const innerColumns = [
|
||||
{ title: "Date", dataIndex: "date", key: "date" },
|
||||
{ title: "Name", dataIndex: "name", key: "name" },
|
||||
@@ -100,4 +198,38 @@ for (let i = 0; i < 3; ++i) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ant-advanced-search-form {
|
||||
padding: 24px;
|
||||
background: #fbfbfb;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.ant-advanced-search-form .ant-form-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ant-advanced-search-form .ant-form-item-control-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#components-form-demo-advanced-search .ant-form {
|
||||
max-width: none;
|
||||
margin-bottom: 1%;
|
||||
}
|
||||
|
||||
#components-form-demo-advanced-search .search-result-list {
|
||||
margin-top: 16px;
|
||||
border: 1px dashed #e9e9e9;
|
||||
border-radius: 6px;
|
||||
background-color: #fafafa;
|
||||
min-height: 200px;
|
||||
text-align: center;
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.input-w {
|
||||
width: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
14
ui/vue.config.js
Normal file
14
ui/vue.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
productionSourceMap: process.env.NODE_ENV !== "production",
|
||||
devServer: {
|
||||
proxy: {
|
||||
"/kafka-console": {
|
||||
target: `${process.env.SW_PROXY_TARGET || "http://127.0.0.1:7766"}`,
|
||||
changeOrigin: true,
|
||||
// pathRewrite: {
|
||||
// '^/kafka-console': '/'
|
||||
// }
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user