user detail
This commit is contained in:
@@ -40,4 +40,6 @@ public interface AclService {
|
||||
|
||||
ResponseData getOperationList();
|
||||
|
||||
ResponseData getUserDetail(String username);
|
||||
|
||||
}
|
||||
|
||||
@@ -181,6 +181,18 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
|
||||
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() {
|
||||
if (kafkaConfig.isAdminCreate()) {
|
||||
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 kafka.server.ConfigType
|
||||
import kafka.utils.Implicits.PropertiesOps
|
||||
import kafka.zk.{AdminZkClient, KafkaZkClient}
|
||||
import org.apache.kafka.clients.admin._
|
||||
import org.apache.kafka.common.security.scram.internals.{ScramCredentialUtils, ScramFormatter}
|
||||
import org.apache.kafka.common.utils.Time
|
||||
|
||||
/**
|
||||
* kafka-console-ui.
|
||||
@@ -51,27 +49,24 @@ class KafkaConfigConsole(config: KafkaConfig) extends KafkaConsole(config: Kafka
|
||||
}
|
||||
|
||||
def addOrUpdateUserWithZK(name: String, pass: String): Boolean = {
|
||||
withZKClient(adminZkClient => {
|
||||
try {
|
||||
val credential = new ScramFormatter(org.apache.kafka.common.security.scram.internals.ScramMechanism.forMechanismName(config.getSaslMechanism))
|
||||
.generateCredential(pass, defaultIterations)
|
||||
val credentialStr = ScramCredentialUtils.credentialToString(credential)
|
||||
|
||||
val zkClient = KafkaZkClient(config.getZookeeperAddr, false, 30000, 30000, Int.MaxValue, Time.SYSTEM)
|
||||
val adminZkClient = new AdminZkClient(zkClient)
|
||||
try {
|
||||
val credential = new ScramFormatter(org.apache.kafka.common.security.scram.internals.ScramMechanism.forMechanismName(config.getSaslMechanism))
|
||||
.generateCredential(pass, defaultIterations)
|
||||
val credentialStr = ScramCredentialUtils.credentialToString(credential)
|
||||
val userConfig: Properties = new Properties()
|
||||
userConfig.put(config.getSaslMechanism, credentialStr)
|
||||
|
||||
val userConfig: Properties = new Properties()
|
||||
userConfig.put(config.getSaslMechanism, credentialStr)
|
||||
|
||||
val configs = adminZkClient.fetchEntityConfig(ConfigType.User, name)
|
||||
userConfig ++= configs
|
||||
adminZkClient.changeConfigs(ConfigType.User, name, userConfig)
|
||||
true
|
||||
} catch {
|
||||
case e: Exception => log.error("addOrUpdateAdminWithZK error.", e)
|
||||
false
|
||||
} finally {
|
||||
zkClient.close()
|
||||
}
|
||||
val configs = adminZkClient.fetchEntityConfig(ConfigType.User, name)
|
||||
userConfig ++= configs
|
||||
adminZkClient.changeConfigs(ConfigType.User, name, userConfig)
|
||||
true
|
||||
} catch {
|
||||
case e: Exception => log.error("addOrUpdateAdminWithZK error.", e)
|
||||
false
|
||||
}
|
||||
}).asInstanceOf[Boolean]
|
||||
}
|
||||
|
||||
def deleteUser(name: String): (Boolean, String) = {
|
||||
|
||||
@@ -3,9 +3,11 @@ package kafka.console
|
||||
import java.util.Properties
|
||||
|
||||
import com.xuxd.kafka.console.config.KafkaConfig
|
||||
import kafka.zk.{AdminZkClient, KafkaZkClient}
|
||||
import org.apache.kafka.clients.CommonClientConfigs
|
||||
import org.apache.kafka.clients.admin.{Admin, AdminClientConfig}
|
||||
import org.apache.kafka.common.config.SaslConfigs
|
||||
import org.apache.kafka.common.utils.Time
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
val props: Properties = new Properties();
|
||||
props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, config.getBootstrapServer)
|
||||
|
||||
@@ -53,7 +53,23 @@
|
||||
></UpdateUser>
|
||||
</div>
|
||||
<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
|
||||
href="#"
|
||||
v-for="t in topicList"
|
||||
@@ -66,9 +82,9 @@
|
||||
:selectDetail="selectDetail"
|
||||
@aclDetailDialog="closeAclDetailDialog"
|
||||
></AclDetail>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a slot="groupList" slot-scope="groupList, record">
|
||||
<div slot="groupList" slot-scope="groupList, record">
|
||||
<a
|
||||
href="#"
|
||||
v-for="t in groupList"
|
||||
@@ -76,9 +92,9 @@
|
||||
@click="onGroupDetail(t, record.username)"
|
||||
><div style="border-bottom: 1px solid #e5e1e1">{{ t }}</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a
|
||||
<div
|
||||
slot="operation"
|
||||
slot-scope="record"
|
||||
v-show="!record.user || record.user.role != 'admin'"
|
||||
@@ -89,9 +105,12 @@
|
||||
cancel-text="取消"
|
||||
@confirm="onDeleteUser(record)"
|
||||
>
|
||||
<a href="javascript:;" class="operation-btn">删除</a>
|
||||
<a-button size="small" href="javascript:;" class="operation-btn"
|
||||
>删除</a-button
|
||||
>
|
||||
</a-popconfirm>
|
||||
<a
|
||||
<a-button
|
||||
size="small"
|
||||
href="javascript:;"
|
||||
class="operation-btn"
|
||||
@click="onManageProducerAuth(record)"
|
||||
@@ -101,9 +120,10 @@
|
||||
:record="selectRow"
|
||||
@manageProducerAuthDialog="closeManageProducerAuthDialog"
|
||||
></ManageProducerAuth>
|
||||
</a>
|
||||
</a-button>
|
||||
|
||||
<a
|
||||
<a-button
|
||||
size="small"
|
||||
href="javascript:;"
|
||||
class="operation-btn"
|
||||
@click="onManageConsumerAuth(record)"
|
||||
@@ -113,8 +133,9 @@
|
||||
:record="selectRow"
|
||||
@manageConsumerAuthDialog="closeManageConsumerAuthDialog"
|
||||
></ManageConsumerAuth>
|
||||
</a>
|
||||
<a
|
||||
</a-button>
|
||||
<a-button
|
||||
size="small"
|
||||
href="javascript:;"
|
||||
class="operation-btn"
|
||||
@click="onAddAuth(record)"
|
||||
@@ -124,32 +145,8 @@
|
||||
:record="selectRow"
|
||||
@addAuthDialog="closeAddAuthDialog"
|
||||
></AddAuth>
|
||||
</a>
|
||||
</a>
|
||||
<!-- <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-button>
|
||||
</div>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -164,6 +161,7 @@ import ManageProducerAuth from "@/views/acl/ManageProducerAuth";
|
||||
import ManageConsumerAuth from "@/views/acl/ManageConsumerAuth";
|
||||
import AddAuth from "@/views/acl/AddAuth";
|
||||
import AclDetail from "@/views/acl/AclDetail";
|
||||
import UserDetail from "@/views/acl/UserDetail";
|
||||
|
||||
export default {
|
||||
name: "Acl",
|
||||
@@ -173,14 +171,13 @@ export default {
|
||||
ManageConsumerAuth,
|
||||
AddAuth,
|
||||
AclDetail,
|
||||
UserDetail,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
queryParam: {},
|
||||
data: [],
|
||||
columns,
|
||||
innerColumns,
|
||||
innerData,
|
||||
selectRow: {},
|
||||
form: this.$form.createForm(this, { name: "advanced_search" }),
|
||||
showUpdateUser: false,
|
||||
@@ -189,6 +186,7 @@ export default {
|
||||
openManageConsumerAuthDialog: false,
|
||||
openAddAuthDialog: false,
|
||||
openAclDetailDialog: false,
|
||||
openUserDetailDialog: false,
|
||||
selectDetail: {
|
||||
resourceName: "",
|
||||
resourceType: "",
|
||||
@@ -273,6 +271,10 @@ export default {
|
||||
this.selectDetail.username = username;
|
||||
this.openAclDetailDialog = true;
|
||||
},
|
||||
onUserDetail(username) {
|
||||
this.selectDetail.username = username;
|
||||
this.openUserDetailDialog = true;
|
||||
},
|
||||
closeManageProducerAuthDialog() {
|
||||
this.openManageProducerAuthDialog = false;
|
||||
getAclList(this.data, this.queryParam);
|
||||
@@ -289,6 +291,9 @@ export default {
|
||||
this.openAclDetailDialog = false;
|
||||
getAclList(this.data, this.queryParam);
|
||||
},
|
||||
closeUserDetailDialog() {
|
||||
this.openUserDetailDialog = false;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
getAclList(this.data, this.queryParam);
|
||||
@@ -329,7 +334,14 @@ function getAclList(data, requestParameters) {
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{ title: "用户名", dataIndex: "username", key: "username", width: 200 },
|
||||
{
|
||||
title: "用户名",
|
||||
dataIndex: "username",
|
||||
key: "username",
|
||||
width: 300,
|
||||
slots: { title: "username" },
|
||||
scopedSlots: { customRender: "username" },
|
||||
},
|
||||
{
|
||||
title: "topic列表",
|
||||
dataIndex: "topicList",
|
||||
@@ -348,32 +360,9 @@ const columns = [
|
||||
title: "操作",
|
||||
key: "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>
|
||||
|
||||
<style scoped>
|
||||
@@ -422,6 +411,6 @@ for (let i = 0; i < 3; ++i) {
|
||||
}
|
||||
|
||||
.operation-btn {
|
||||
margin-right: 1%;
|
||||
margin-right: 3%;
|
||||
}
|
||||
</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