美文网首页
golang 实现 ldif 数据转成 json 初探

golang 实现 ldif 数据转成 json 初探

作者: 阿兵云原生 | 来源:发表于2023-04-18 20:05 被阅读0次

    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     string
        Path     string
        Children []*lNode
        User     []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 文件中实现一下,代码结构是这样的

    [图片上传失败...(image-8307fc-1681905703465)]

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

    [图片上传失败...(image-986a64-1681905703466)]

    处理 ldap 响应的数据

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

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

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

    [图片上传失败...(image-ef5653-1681905703466)]

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

    [图片上传失败...(image-addda5-1681905703466)]

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

    // 创建一棵树
    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 里面具体的实现是遍历 ldap 的所有 entry,并调用 ProcessDN 函数来解析 dn 数据,且根据 dn 来生成对应的多叉树片段

    具体处理 DN 数据

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

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

    [图片上传失败...(image-4b1340-1681905703466)]

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

    json 序列化

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

    [图片上传失败...(image-b76734-1681905703466)]

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

    [图片上传失败...(image-ba5b30-1681905703466)]

    整个 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"
        ]
    }
    

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

    欢迎点赞,关注,收藏

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

    [图片上传失败...(image-9485db-1681905703466)]

    好了,本次就到这里

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

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

    相关文章

      网友评论

          本文标题:golang 实现 ldif 数据转成 json 初探

          本文链接:https://www.haomeiwen.com/subject/gmhkjdtx.html