> 文章列表 > golang 实现 ldif 数据转成 json 初探

golang 实现 ldif 数据转成 json 初探

golang 实现 ldif 数据转成 json 初探


theme: Chinese-red

「这是我参与11月更文挑战的第 8 天,活动详情查看:2021最后一次更文挑战」

上一篇我们分享了如何将 ldif 格式的数据,转换成 json 数据的思路并画相应的简图

这一次,我们就来实现一下

实现方式如下:

  • 连接服务器,查询 ldap 服务器上数据结构 ,goalng 如何获取 ldap 服务器的数据? 有说到

  • 遍历每一条 entry

  • 处理每一条 entry 的时候,从右到左获取相应的 rdn(对应的键和值),并给每一个 rdn 创建一个 多叉树的 节点

  • basedn 对应的节点 和 每一个 ou 对应的节点地址,存放到一个 map(key 是 string,value 是节点的地址) 中便于后续遍历处理其他 entry 的时候,直接通过 ou 名字获取对应节点地址即可

  • 对于一个节点下面的用户,直接挂到这个节点上即可

来一起看看数据结构和 main 函数

数据结构为节点的必要信息

// 节点信息
type lNode struct {Name     stringPath     stringChildren []*lNodeUser     []string
}
// 新建一个节点
func NewNode(name, path string) *lNode {return &lNode{Name:     name,Path:     path,Children: []*lNode{},User:     []string{},}
}

main 函数的执行流程具体如下:

  • 连接ldap 服务器并查询对应数据
  • 处理数据并生成一颗树 (默认 dc 为 根节点, / )
  • 将树转成 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 服务器上获取数据

我们简单就在 一个 main.go 文件中实现一下,代码结构是这样的

golang 实现 ldif 数据转成 json 初探

func connectLdap(addr, baseDB, username, passwd, filter string) []*ldap.Entry { 函数的具体实现,在文章 goalng 如何获取 ldap 服务器的数据? 有体现,我们这一次只是将参数调整了一下

golang 实现 ldif 数据转成 json 初探

处理 ldap 响应的数据

ldap 返回的数据是以 ldif 格式返回的,会返回0条到多条 entry,我们需要逐个的来解析每一个 entry 里面的数据

一个 entry 就是一个 DN ,一个 DN 里面有多个 RDN,一个 RDN 就是一个键值对

  • 创建根节点,信息是 BASEDN :dc=xiaomotong,dc=com , 并将信息放到 map 中

golang 实现 ldif 数据转成 json 初探

  • 开始解析数据每一条 dn,dn 中的 每一个 rdn 创建对应的节点,并通过dn 从右到左的顺序,将 rdn 连接起来
  • 一个组里面有子组,就放在 node 的 Children 里面, 一个组里面的 用户就放在 User里面,当前节点的名字 放在 name中,当前节点的绝对路径就放在 path 中

golang 实现 ldif 数据转成 json 初探

来看看 func CreateLdapTree(mp map[string]*lNode, Entries []*ldap.Entry, BASEDN string) { 函数

// 创建一棵树
func CreateLdapTree(mp map[string]*lNode, Entries []*ldap.Entry, BASEDN string) {// 遍历 Entriesfor _, Entry := range Entries {if BASEDN == Entry.DN {continue}ProcessDN(Entry.DN, mp, BASEDN)}
}

CreateLdapTree 里面具体的实现是遍历 ldap 的所有 entry,并调用 ProcessDN 函数来解析 dn 数据,且根据 dn 来生成对应的多叉树片段

具体处理 DN 数据

func ProcessDN(DN string, mp map[string]*lNode, BASEDN string) { 是具体处理 DN 数据的主要函数

  • 主要做的是解析一条 DN 数据,并生成一个多叉树的片段
  • ou 的节点地址会相应放到 map 中进行记录,便于后续使用

golang 实现 ldif 数据转成 json 初探

处理的逻辑,会去判断 rdn 的 key 是 dc,cn,ou,来做相应的处理,如果是 ou 就创建节点,并将节点的地址记录在 map 中

json 序列化

最后将数据结构序列化成 json,并以字符串的方式打印出来

golang 实现 ldif 数据转成 json 初探

上述代码逻辑也比较简单,就是将 ldif 转成树而已,代码流程是

golang 实现 ldif 数据转成 json 初探

整个 main.go 文件,执行之后,结果如下,成功将 ldif 转成多叉树,且已 json 的方式展现出来

{"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"]
}

学习所得,如有偏差,还请不吝赐教,细心的朋友会发现上述逻辑有坑,下次见

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

golang 实现 ldif 数据转成 json 初探

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~