user detail
This commit is contained in:
@@ -40,4 +40,6 @@ public interface AclService {
|
|||||||
|
|
||||||
ResponseData getOperationList();
|
ResponseData getOperationList();
|
||||||
|
|
||||||
|
ResponseData getUserDetail(String username);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,6 +181,18 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
|
|||||||
return ResponseData.create().data(operations).success();
|
return ResponseData.create().data(operations).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public ResponseData getUserDetail(String username) {
|
||||||
|
Map<String, Object> param = new HashMap<>();
|
||||||
|
param.put("username", username);
|
||||||
|
List<KafkaUserDO> dos = kafkaUserMapper.selectByMap(param);
|
||||||
|
if (dos.isEmpty()) {
|
||||||
|
return ResponseData.create().data(new CounterList<>(dos)).success("Retrieved the user info is null.");
|
||||||
|
}
|
||||||
|
// check for consistency.
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void afterSingletonsInstantiated() {
|
@Override public void afterSingletonsInstantiated() {
|
||||||
if (kafkaConfig.isAdminCreate()) {
|
if (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());
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ import java.util.{Properties, Set}
|
|||||||
import com.xuxd.kafka.console.config.KafkaConfig
|
import com.xuxd.kafka.console.config.KafkaConfig
|
||||||
import kafka.server.ConfigType
|
import kafka.server.ConfigType
|
||||||
import kafka.utils.Implicits.PropertiesOps
|
import kafka.utils.Implicits.PropertiesOps
|
||||||
import kafka.zk.{AdminZkClient, KafkaZkClient}
|
|
||||||
import org.apache.kafka.clients.admin._
|
import org.apache.kafka.clients.admin._
|
||||||
import org.apache.kafka.common.security.scram.internals.{ScramCredentialUtils, ScramFormatter}
|
import org.apache.kafka.common.security.scram.internals.{ScramCredentialUtils, ScramFormatter}
|
||||||
import org.apache.kafka.common.utils.Time
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kafka-console-ui.
|
* kafka-console-ui.
|
||||||
@@ -51,9 +49,7 @@ class KafkaConfigConsole(config: KafkaConfig) extends KafkaConsole(config: Kafka
|
|||||||
}
|
}
|
||||||
|
|
||||||
def addOrUpdateUserWithZK(name: String, pass: String): Boolean = {
|
def addOrUpdateUserWithZK(name: String, pass: String): Boolean = {
|
||||||
|
withZKClient(adminZkClient => {
|
||||||
val zkClient = KafkaZkClient(config.getZookeeperAddr, false, 30000, 30000, Int.MaxValue, Time.SYSTEM)
|
|
||||||
val adminZkClient = new AdminZkClient(zkClient)
|
|
||||||
try {
|
try {
|
||||||
val credential = new ScramFormatter(org.apache.kafka.common.security.scram.internals.ScramMechanism.forMechanismName(config.getSaslMechanism))
|
val credential = new ScramFormatter(org.apache.kafka.common.security.scram.internals.ScramMechanism.forMechanismName(config.getSaslMechanism))
|
||||||
.generateCredential(pass, defaultIterations)
|
.generateCredential(pass, defaultIterations)
|
||||||
@@ -69,9 +65,8 @@ class KafkaConfigConsole(config: KafkaConfig) extends KafkaConsole(config: Kafka
|
|||||||
} catch {
|
} catch {
|
||||||
case e: Exception => log.error("addOrUpdateAdminWithZK error.", e)
|
case e: Exception => log.error("addOrUpdateAdminWithZK error.", e)
|
||||||
false
|
false
|
||||||
} finally {
|
|
||||||
zkClient.close()
|
|
||||||
}
|
}
|
||||||
|
}).asInstanceOf[Boolean]
|
||||||
}
|
}
|
||||||
|
|
||||||
def deleteUser(name: String): (Boolean, String) = {
|
def deleteUser(name: String): (Boolean, String) = {
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package kafka.console
|
|||||||
import java.util.Properties
|
import java.util.Properties
|
||||||
|
|
||||||
import com.xuxd.kafka.console.config.KafkaConfig
|
import com.xuxd.kafka.console.config.KafkaConfig
|
||||||
|
import kafka.zk.{AdminZkClient, KafkaZkClient}
|
||||||
import org.apache.kafka.clients.CommonClientConfigs
|
import org.apache.kafka.clients.CommonClientConfigs
|
||||||
import org.apache.kafka.clients.admin.{Admin, AdminClientConfig}
|
import org.apache.kafka.clients.admin.{Admin, AdminClientConfig}
|
||||||
import org.apache.kafka.common.config.SaslConfigs
|
import org.apache.kafka.common.config.SaslConfigs
|
||||||
|
import org.apache.kafka.common.utils.Time
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kafka-console-ui.
|
* kafka-console-ui.
|
||||||
@@ -25,6 +27,16 @@ class KafkaConsole(config: KafkaConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected def withZKClient(f: AdminZkClient => Any): Any = {
|
||||||
|
val zkClient = KafkaZkClient(config.getZookeeperAddr, false, 30000, 30000, Int.MaxValue, Time.SYSTEM)
|
||||||
|
val adminZkClient = new AdminZkClient(zkClient)
|
||||||
|
try {
|
||||||
|
f(adminZkClient)
|
||||||
|
} finally {
|
||||||
|
zkClient.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private def createAdminClient(): Admin = {
|
private def createAdminClient(): Admin = {
|
||||||
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)
|
||||||
|
|||||||
@@ -53,7 +53,23 @@
|
|||||||
></UpdateUser>
|
></UpdateUser>
|
||||||
</div>
|
</div>
|
||||||
<a-table :columns="columns" :data-source="data" bordered>
|
<a-table :columns="columns" :data-source="data" bordered>
|
||||||
<a slot="topicList" slot-scope="topicList, record">
|
<div slot="username" slot-scope="username">
|
||||||
|
<span>{{ username }}</span
|
||||||
|
><a-button
|
||||||
|
size="small"
|
||||||
|
shape="round"
|
||||||
|
type="dashed"
|
||||||
|
style="float: right"
|
||||||
|
@click="onUserDetail(username)"
|
||||||
|
>详情</a-button
|
||||||
|
>
|
||||||
|
<UserDetail
|
||||||
|
:visible="openUserDetailDialog"
|
||||||
|
@userDetailDialog="closeUserDetailDialog"
|
||||||
|
></UserDetail>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="topicList" slot-scope="topicList, record">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
v-for="t in topicList"
|
v-for="t in topicList"
|
||||||
@@ -66,9 +82,9 @@
|
|||||||
:selectDetail="selectDetail"
|
:selectDetail="selectDetail"
|
||||||
@aclDetailDialog="closeAclDetailDialog"
|
@aclDetailDialog="closeAclDetailDialog"
|
||||||
></AclDetail>
|
></AclDetail>
|
||||||
</a>
|
</div>
|
||||||
|
|
||||||
<a slot="groupList" slot-scope="groupList, record">
|
<div slot="groupList" slot-scope="groupList, record">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
v-for="t in groupList"
|
v-for="t in groupList"
|
||||||
@@ -76,9 +92,9 @@
|
|||||||
@click="onGroupDetail(t, record.username)"
|
@click="onGroupDetail(t, record.username)"
|
||||||
><div style="border-bottom: 1px solid #e5e1e1">{{ t }}</div>
|
><div style="border-bottom: 1px solid #e5e1e1">{{ t }}</div>
|
||||||
</a>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
|
|
||||||
<a
|
<div
|
||||||
slot="operation"
|
slot="operation"
|
||||||
slot-scope="record"
|
slot-scope="record"
|
||||||
v-show="!record.user || record.user.role != 'admin'"
|
v-show="!record.user || record.user.role != 'admin'"
|
||||||
@@ -89,9 +105,12 @@
|
|||||||
cancel-text="取消"
|
cancel-text="取消"
|
||||||
@confirm="onDeleteUser(record)"
|
@confirm="onDeleteUser(record)"
|
||||||
>
|
>
|
||||||
<a href="javascript:;" class="operation-btn">删除</a>
|
<a-button size="small" href="javascript:;" class="operation-btn"
|
||||||
|
>删除</a-button
|
||||||
|
>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
<a
|
<a-button
|
||||||
|
size="small"
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
class="operation-btn"
|
class="operation-btn"
|
||||||
@click="onManageProducerAuth(record)"
|
@click="onManageProducerAuth(record)"
|
||||||
@@ -101,9 +120,10 @@
|
|||||||
:record="selectRow"
|
:record="selectRow"
|
||||||
@manageProducerAuthDialog="closeManageProducerAuthDialog"
|
@manageProducerAuthDialog="closeManageProducerAuthDialog"
|
||||||
></ManageProducerAuth>
|
></ManageProducerAuth>
|
||||||
</a>
|
</a-button>
|
||||||
|
|
||||||
<a
|
<a-button
|
||||||
|
size="small"
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
class="operation-btn"
|
class="operation-btn"
|
||||||
@click="onManageConsumerAuth(record)"
|
@click="onManageConsumerAuth(record)"
|
||||||
@@ -113,8 +133,9 @@
|
|||||||
:record="selectRow"
|
:record="selectRow"
|
||||||
@manageConsumerAuthDialog="closeManageConsumerAuthDialog"
|
@manageConsumerAuthDialog="closeManageConsumerAuthDialog"
|
||||||
></ManageConsumerAuth>
|
></ManageConsumerAuth>
|
||||||
</a>
|
</a-button>
|
||||||
<a
|
<a-button
|
||||||
|
size="small"
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
class="operation-btn"
|
class="operation-btn"
|
||||||
@click="onAddAuth(record)"
|
@click="onAddAuth(record)"
|
||||||
@@ -124,32 +145,8 @@
|
|||||||
:record="selectRow"
|
:record="selectRow"
|
||||||
@addAuthDialog="closeAddAuthDialog"
|
@addAuthDialog="closeAddAuthDialog"
|
||||||
></AddAuth>
|
></AddAuth>
|
||||||
</a>
|
</a-button>
|
||||||
</a>
|
</div>
|
||||||
<!-- <a-table-->
|
|
||||||
<!-- slot="expandedRowRender"-->
|
|
||||||
<!-- slot-scope="{}"-->
|
|
||||||
<!-- :columns="innerColumns"-->
|
|
||||||
<!-- :data-source="innerData"-->
|
|
||||||
<!-- :pagination="false"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <span slot="status" slot-scope="{}"> <a-badge status="success" />Finished </span>-->
|
|
||||||
<!-- <span slot="operation" slot-scope="{}" class="table-operation">-->
|
|
||||||
<!-- <a>Pause</a>-->
|
|
||||||
<!-- <a>Stop</a>-->
|
|
||||||
<!-- <a-dropdown>-->
|
|
||||||
<!-- <a-menu slot="overlay">-->
|
|
||||||
<!-- <a-menu-item>-->
|
|
||||||
<!-- Action 1-->
|
|
||||||
<!-- </a-menu-item>-->
|
|
||||||
<!-- <a-menu-item>-->
|
|
||||||
<!-- Action 2-->
|
|
||||||
<!-- </a-menu-item>-->
|
|
||||||
<!-- </a-menu>-->
|
|
||||||
<!-- <a> More <a-icon type="down" /> </a>-->
|
|
||||||
<!-- </a-dropdown>-->
|
|
||||||
<!-- </span>-->
|
|
||||||
<!-- </a-table>-->
|
|
||||||
</a-table>
|
</a-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -164,6 +161,7 @@ import ManageProducerAuth from "@/views/acl/ManageProducerAuth";
|
|||||||
import ManageConsumerAuth from "@/views/acl/ManageConsumerAuth";
|
import ManageConsumerAuth from "@/views/acl/ManageConsumerAuth";
|
||||||
import AddAuth from "@/views/acl/AddAuth";
|
import AddAuth from "@/views/acl/AddAuth";
|
||||||
import AclDetail from "@/views/acl/AclDetail";
|
import AclDetail from "@/views/acl/AclDetail";
|
||||||
|
import UserDetail from "@/views/acl/UserDetail";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Acl",
|
name: "Acl",
|
||||||
@@ -173,14 +171,13 @@ export default {
|
|||||||
ManageConsumerAuth,
|
ManageConsumerAuth,
|
||||||
AddAuth,
|
AddAuth,
|
||||||
AclDetail,
|
AclDetail,
|
||||||
|
UserDetail,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
queryParam: {},
|
queryParam: {},
|
||||||
data: [],
|
data: [],
|
||||||
columns,
|
columns,
|
||||||
innerColumns,
|
|
||||||
innerData,
|
|
||||||
selectRow: {},
|
selectRow: {},
|
||||||
form: this.$form.createForm(this, { name: "advanced_search" }),
|
form: this.$form.createForm(this, { name: "advanced_search" }),
|
||||||
showUpdateUser: false,
|
showUpdateUser: false,
|
||||||
@@ -189,6 +186,7 @@ export default {
|
|||||||
openManageConsumerAuthDialog: false,
|
openManageConsumerAuthDialog: false,
|
||||||
openAddAuthDialog: false,
|
openAddAuthDialog: false,
|
||||||
openAclDetailDialog: false,
|
openAclDetailDialog: false,
|
||||||
|
openUserDetailDialog: false,
|
||||||
selectDetail: {
|
selectDetail: {
|
||||||
resourceName: "",
|
resourceName: "",
|
||||||
resourceType: "",
|
resourceType: "",
|
||||||
@@ -273,6 +271,10 @@ export default {
|
|||||||
this.selectDetail.username = username;
|
this.selectDetail.username = username;
|
||||||
this.openAclDetailDialog = true;
|
this.openAclDetailDialog = true;
|
||||||
},
|
},
|
||||||
|
onUserDetail(username) {
|
||||||
|
this.selectDetail.username = username;
|
||||||
|
this.openUserDetailDialog = true;
|
||||||
|
},
|
||||||
closeManageProducerAuthDialog() {
|
closeManageProducerAuthDialog() {
|
||||||
this.openManageProducerAuthDialog = false;
|
this.openManageProducerAuthDialog = false;
|
||||||
getAclList(this.data, this.queryParam);
|
getAclList(this.data, this.queryParam);
|
||||||
@@ -289,6 +291,9 @@ export default {
|
|||||||
this.openAclDetailDialog = false;
|
this.openAclDetailDialog = false;
|
||||||
getAclList(this.data, this.queryParam);
|
getAclList(this.data, this.queryParam);
|
||||||
},
|
},
|
||||||
|
closeUserDetailDialog() {
|
||||||
|
this.openUserDetailDialog = false;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
getAclList(this.data, this.queryParam);
|
getAclList(this.data, this.queryParam);
|
||||||
@@ -329,7 +334,14 @@ function getAclList(data, requestParameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: "用户名", dataIndex: "username", key: "username", width: 200 },
|
{
|
||||||
|
title: "用户名",
|
||||||
|
dataIndex: "username",
|
||||||
|
key: "username",
|
||||||
|
width: 300,
|
||||||
|
slots: { title: "username" },
|
||||||
|
scopedSlots: { customRender: "username" },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "topic列表",
|
title: "topic列表",
|
||||||
dataIndex: "topicList",
|
dataIndex: "topicList",
|
||||||
@@ -348,32 +360,9 @@ const columns = [
|
|||||||
title: "操作",
|
title: "操作",
|
||||||
key: "operation",
|
key: "operation",
|
||||||
scopedSlots: { customRender: "operation" },
|
scopedSlots: { customRender: "operation" },
|
||||||
width: 350,
|
width: 500,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const innerColumns = [
|
|
||||||
{ title: "Date", dataIndex: "date", key: "date" },
|
|
||||||
{ title: "Name", dataIndex: "name", key: "name" },
|
|
||||||
{ title: "Status", key: "state", scopedSlots: { customRender: "status" } },
|
|
||||||
{ title: "Upgrade Status", dataIndex: "upgradeNum", key: "upgradeNum" },
|
|
||||||
{
|
|
||||||
title: "Action",
|
|
||||||
dataIndex: "operation",
|
|
||||||
key: "operation",
|
|
||||||
scopedSlots: { customRender: "operation" },
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const innerData = [];
|
|
||||||
for (let i = 0; i < 3; ++i) {
|
|
||||||
innerData.push({
|
|
||||||
key: i,
|
|
||||||
date: "2014-12-24 23:12:00",
|
|
||||||
name: "This is production name",
|
|
||||||
upgradeNum: "Upgraded: 56",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -422,6 +411,6 @@ for (let i = 0; i < 3; ++i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.operation-btn {
|
.operation-btn {
|
||||||
margin-right: 1%;
|
margin-right: 3%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
51
ui/src/views/acl/UserDetail.vue
Normal file
51
ui/src/views/acl/UserDetail.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
title="用户详情"
|
||||||
|
:visible="show"
|
||||||
|
:width="800"
|
||||||
|
:mask="false"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:footer="null"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import { KafkaAclApi } from "@/utils/api";
|
||||||
|
// import request from "@/utils/request";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UserDetail",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
// KafkaAclApi, request,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
formLayout: "horizontal",
|
||||||
|
show: this.visible,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(v) {
|
||||||
|
this.show = v;
|
||||||
|
if (this.show) {
|
||||||
|
this.getAclDetail();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleCancel() {
|
||||||
|
this.$emit("userDetailDialog", {});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
Reference in New Issue
Block a user