Search code examples
pythonjsonparsingsudoers

How to convert sudoers file into JSON data using Python?


I'm working on a parser for sudoers file into a format that is easier to read for the program I'm working on. I'm a beginner with Python and don't have enough experience to do what I need.

So far I have the following code:

#!/usr/bin/env python

import operator
import os
import sys
import re
import json

example_file = "./Sudoers_example.txt"
try:
    column1 = []
    column2 = []
    column3 = []

    with open(example_file) as f:
        for line in f:
            #result.append(re.split(r'\s+', line)[0:3])
            column1.append(re.split(r'\s+', line)[0])
            column2.append(re.split(r'\s+', line)[1])
            column3.append(re.split(r'\s+', line)[2])

        mergedDict = {'op':column1, 'runas':column2, 'cmds':column3}

        print(json.dumps(mergedDict, indent=4, sort_keys=False))

except Exception as ee:
    print(ee)
    sys.exit(-1)

This doesn't produce what I want. It is a work in progress.

Nonetheless, what I want to see is the following:

{
    "hostname": "host.moo.com",
    "sudoers": [
        {
            "op": "operator1",
            "runas": "ALL=(ALL)",
            "cmds": "ALL"
        },
        {
            "op": "operator2",
            "runas": "ALL=(ALL)",
            "cmds": "ALL"
        }

    ]
}

I'm not sure what the next step is. How should I proceed?

Edit, the example files looks like this (as per request):

root          ALL=(ALL) ALL
%group1 ALL=(ALL) ALL
operator1 ALL=(ALL) ALL
operator2 ALL=(ALL) ALL
%systems ALL=(ALL) ALL

Solution

  • You don't need to use re here, simply read each line from file and split it.

    import json
    
    
    js = {"hostname": "test", "sudoers":[]} # create json structure first
    with open("/home/sufiyan/a") as f:
        for line in f:
            line = line.split() # split on every space character
            js["sudoers"].append({"op": line[0], "runas": line[1], "cmds": line[2]})
    
    
    print(json.dumps(js))
    
    # output,
    
    {
      "sudoers": [
        {
          "runas": "ALL=(ALL)",
          "cmds": "ALL",
          "op": "root"
        },
        {
          "runas": "ALL=(ALL)",
          "cmds": "ALL",
          "op": "%group1"
        },
        {
          "runas": "ALL=(ALL)",
          "cmds": "ALL",
          "op": "operator1"
        },
        {
          "runas": "ALL=(ALL)",
          "cmds": "ALL",
          "op": "operator2"
        },
        {
          "runas": "ALL=(ALL)",
          "cmds": "ALL",
          "op": "%systems"
        }
      ],
      "hostname": "test"
    }