golang實現(xiàn)ldif數(shù)據(jù)轉(zhuǎn)成json初探
theme: Chinese-red
「這是我參與11月更文挑戰(zhàn)的第 8 天,活動詳情查看:
2021最后一次更文挑戰(zhàn)
」
上一篇我們分享了如何將 ldif 格式的數(shù)據(jù),轉(zhuǎn)換成 json 數(shù)據(jù)的思路并畫相應的簡圖 這一次,我們就來實現(xiàn)一下 實現(xiàn)方式如下: 連接服務器,查詢 ldap 服務器上數(shù)據(jù)結(jié)構(gòu) ,
goalng 如何獲取 ldap 服務器的數(shù)據(jù)?
有說到
遍歷每一條 entry
處理每一條 entry 的時候,從右到左獲取相應的 rdn(對應的鍵和值),
并給每一個 rdn 創(chuàng)建一個 多叉樹的 節(jié)點
basedn 對應的節(jié)點 和 每一個 ou 對應的節(jié)點地址,
存放到一個 map(key 是 string,value 是節(jié)點的地址)
中便于后續(xù)遍歷處理其他 entry 的時候,直接通過 ou 名字獲取對應節(jié)點地址即可
對于一個節(jié)點下面的用戶,
直接掛到這個節(jié)點上即可
來一起看看數(shù)據(jù)結(jié)構(gòu)和 main 函數(shù)
數(shù)據(jù)結(jié)構(gòu)為節(jié)點的必要信息
//?節(jié)點信息
type
?lNode?
struct
?{ ?Name?????
string
?Path?????
string
?Children?[]*lNode ?User?????[]
string
}
//?新建一個節(jié)點
func
?
NewNode
(name,?path?
string
)
?*
lNode
?{ ?
return
?&lNode{ ??Name:?????name, ??Path:?????path, ??Children:?[]*lNode{}, ??User:?????[]
string
{}, ?} }
main 函數(shù)的執(zhí)行流程具體如下:
連接ldap 服務器并查詢對應數(shù)據(jù)
處理數(shù)據(jù)并生成一顆樹 (默認 dc 為 根節(jié)點, / )
將樹轉(zhuǎn)成 json 格式,進行打印輸出
func
?
main
()
?{ ?data?:=?connectLdap( ??
"ldap://xxxx"
, ??
"dc=xiaomotong,dc=com"
, ??
"cn=admin,dc=xiaomotong,dc=com"
, ??
"123123"
, ??
"(&(objectClass=*))"
) ?
if
?
len
(data)?<=?
0
?{ ??fmt.Println(
"search?no?data?!!"
) ?} ?mp?:=?
make
(
map
[
string
]*lNode) ?root?:=?NewNode(
"dc=xiaomotong,dc=com"
,?
"/"
) ?mp[
"dc=xiaomotong,dc=com"
]?=?root ?
//?生成一顆樹
?CreateLdapTree(mp,?data,?
"dc=xiaomotong,dc=com"
) ?b,?err?:=?json.Marshal(root) ?
if
?err?!=?
nil
?{ ??fmt.Println(
"json.Marshal?error?!!!"
) ??
return
?} ?fmt.Println(
string
(b)) } 從 ldap 服務器上獲取數(shù)據(jù)
我們簡單就在 一個
main.go
文件中實現(xiàn)一下,代碼結(jié)構(gòu)是這樣的 func connectLdap(addr, baseDB, username, passwd, filter string) []*ldap.Entry { 函數(shù)的具體實現(xiàn),在文章
goalng 如何獲取 ldap 服務器的數(shù)據(jù)?
有體現(xiàn),我們這一次只是將參數(shù)調(diào)整了一下 處理 ldap 響應的數(shù)據(jù)
ldap 返回的數(shù)據(jù)是以 ldif 格式返回的,會返回0條到多條 entry,我們需要逐個的來解析每一個 entry 里面的數(shù)據(jù)
一個 entry 就是一個 DN ,一個 DN 里面有多個 RDN,一個 RDN 就是一個鍵值對
創(chuàng)建根節(jié)點,信息是 BASEDN :dc=xiaomotong,dc=com , 并將信息放到 map 中
開始解析數(shù)據(jù)每一條 dn,dn 中的 每一個 rdn 創(chuàng)建對應的節(jié)點,并通過dn 從右到左的順序,將 rdn 連接起來
一個組里面有子組,就放在 node 的 Children 里面, 一個組里面的 用戶就放在 User里面,當前節(jié)點的名字 放在 name中,當前節(jié)點的絕對路徑就放在 path 中
來看看 func CreateLdapTree(mp map[string]*lNode, Entries []*ldap.Entry, BASEDN string) { 函數(shù)
//?創(chuàng)建一棵樹
func
?
CreateLdapTree
(mp?
map
[
string
]*lNode,?Entries?[]*ldap.Entry,?BASEDN?
string
)
?{ ?
//?遍歷?Entries
?
for
?_,?Entry?:=?
range
?Entries?{ ??
if
?BASEDN?==?Entry.DN?{ ???
continue
??} ??ProcessDN(Entry.DN,?mp,?BASEDN) ?} } CreateLdapTree 里面具體的實現(xiàn)是遍歷 ldap 的所有 entry,并調(diào)用 ProcessDN 函數(shù)來解析 dn 數(shù)據(jù),且根據(jù) dn 來生成對應的多叉樹片段 具體處理 DN 數(shù)據(jù) func ProcessDN(DN string, mp map[string]*lNode, BASEDN string) { 是具體處理 DN 數(shù)據(jù)的主要函數(shù) 主要做的是解析一條 DN 數(shù)據(jù),
并生成一個多叉樹的片段
ou 的節(jié)點地址會相應放到 map 中進行記錄,便于后續(xù)使用
處理的邏輯,會去判斷 rdn 的 key 是 dc,cn,ou,來做相應的處理,
如果是 ou 就創(chuàng)建節(jié)點,并將節(jié)點的地址記錄在 map 中
json 序列化
最后將數(shù)據(jù)結(jié)構(gòu)序列化成 json,并以字符串的方式打印出來 上述代碼邏輯也比較簡單,就是將 ldif 轉(zhuǎn)成樹而已,代碼流程是 整個
main.go 文件
,執(zhí)行之后,結(jié)果如下,
成功將 ldif 轉(zhuǎn)成多叉樹,且已 json 的方式展現(xiàn)出來
{ ????
"Name"
:?
"dc=xiaomotong,dc=com"
, ????
"Path"
:?
"/"
, ????
"Children"
:?[ ????????{ ????????????
"Name"
:?
"People"
, ????????????
"Path"
:?
"/People/"
, ????????????
"Children"
:?[], ????????????
"User"
:?[ ????????????????
"xiaozhupeiqi"
????????????] ????????}, ????????{ ????????????
"Name"
:?
"dev"
, ????????????
"Path"
:?
"/dev/"
, ????????????
"Children"
:?[ ????????????????{ ????????????????????
"Name"
:?
"golang"
, ????????????????????
"Path"
:?
"/dev/golang/"
, ????????????????????
"Children"
:?[], ????????????????????
"User"
:?[ ????????????????????????
"xiaoppp"
????????????????????] ????????????????}, ????????????????{ ????????????????????
"Name"
:?
"clang"
, ????????????????????
"Path"
:?
"/dev/clang/"
, ????????????????????
"Children"
:?[ ????????????????????????{ ????????????????????????????
"Name"
:?
"woshixiaozhu"
, ????????????????????????????
"Path"
:?
"/dev/clang/woshixiaozhu/"
, ????????????????????????????
"Children"
:?[], ????????????????????????????
"User"
:?[ ????????????????????????????????
"xiaopang2"
????????????????????????????] ????????????????????????} ????????????????????], ????????????????????
"User"
:?[] ????????????????}, ????????????????{ ????????????????????
"Name"
:?
"java"
, ????????????????????
"Path"
:?
"/dev/java/"
, ????????????????????
"Children"
:?[], ????????????????????
"User"
:?[] ????????????????} ????????????], ????????????
"User"
:?[] ????????} ????], ????
"User"
:?[ ????????
"admin"
, ????????
"zhangsan"
, ????????
"xiaopang"
, ????????
"xiaopang2"
????] }
學習所得,如有偏差,還請不吝賜教,細心的朋友會發(fā)現(xiàn)上述邏輯有坑,下次見
歡迎點贊,關注,收藏
朋友們,你的支持和鼓勵,是我堅持分享,提高質(zhì)量的動力 好了,本次就到這里 技術是開放的,我們的心態(tài),更應是開放的。擁抱變化,向陽而生,努力向前行。 我是
小魔童哪吒
,歡迎點贊關注收藏,下次見~