MaxGeneGrim
MaxGeneGrim

Reputation: 203

How do I use Perl to add additional data to a JSON-format config file?

I'm doing a script who retrieve some info from a MySQL DB to generate static reservation in a dhcp conf file. The dhcp conf file is in JSON format.

So I have this kind of info :

"subnet4": [
    {   
        "subnet": "192.168.2.0/24",
        "pools": [ 
           { "pool": "192.168.2.10 - 192.168.2.20" }
        ]
    }
 ]

And I want something like this :

"subnet4": [
    {
        "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
        "subnet": "192.0.2.0/24",
        "interface": "eth0",
        "reservations": [
            {
                "hw-address": "1a:1b:1c:1d:1e:1f",
                "ip-address": "192.0.2.202"
            },
            {
                "hw-address": "0a:0b:0c:0d:0e:0f",
                "ip-address": "192.0.2.100",
            }
        ]
    }
]

To reach that, for now I can generate the "reservations" filed and I got this :

[{"ip-address":"192.0.2.202","hw-address":"1a:1b:1c:1d:1e:1f"},{"ip-address":"192.0.2.100","hw-address":"0a:0b:0c:0d:0e:0f"}]

I'm doing this through a perl script, and now I wanted to add this to the dhcp.conf file via a loop you read line by line my file to add the field "reservations" and every info in it but I don't succed to match a pettern to add this as I wanted. Because I have different subnet set so I can't use info in my subnet field to match a patern and add reservations after it...

Do someone have an idea ?

Thank you !

Upvotes: 0

Views: 134

Answers (2)

MaxGeneGrim
MaxGeneGrim

Reputation: 203

Ok I find a solution,

open(my $json_fh, "<:encoding(UTF-8)", $kea_conf_file_path)
  or die("Can't open \$kea_conf_file_path\": $!\n");
my $json_text;
while (my $line = <$json_fh>) {
        unless($line =~ m/^#/){
                $json_text .= $line; 
        }
}
my $json = decode_json($json_text);
my $reservations = $json->{"Dhcp4"}->{"subnet4"}->[0]->{'reservations'} = [];
push @$reservations, @reservation_from_db;
print Dumper $json;

Big thanks to @Sobrique, it's really more readable and clean like that.

Upvotes: 0

Sobrique
Sobrique

Reputation: 53508

This question is tagged as regex. Don't use regex for this task, it's nasty. Use the JSON module instead. Like this:

#!/usr/bin/env perl
use strict;
use warnings;
use JSON;
use Data::Dumper;

my $raw_text = '{"subnet4": [
    {   
        "subnet": "192.168.2.0/24",
        "pools": [ 
           { "pool": "192.168.2.10 - 192.168.2.20" }
        ]
    }
 ]}';

my $json = decode_json($raw_text);

$json->{'subnet4'}->[0]->{"interface"} = "eth0";
my $reservations = $json->{"subnet4"}->[0]->{'reservations'} = [];

push(
    @$reservations,
    {   "hw_address" => "1a:1b:1c:1d:1e:1f",
        "ip-address" => "192.0.2.202"
    }
);
push(
    @$reservations,
    {   "hw_address" => "0a:0b:0c:0d:0e:0f",
        "ip-address" => "192.0.2.100"
    }
);

print Dumper $json;

print "JSON Result:\n";

print to_json($json, {'pretty' => 1 } );

This generates:

{
   "subnet4" : [
      {
         "reservations" : [
            {
               "ip-address" : "192.0.2.202",
               "hw_address" : "1a:1b:1c:1d:1e:1f"
            },
            {
               "ip-address" : "192.0.2.100",
               "hw_address" : "0a:0b:0c:0d:0e:0f"
            }
         ],
         "subnet" : "192.168.2.0/24",
         "pools" : [
            {
               "pool" : "192.168.2.10 - 192.168.2.20"
            }
         ],
         "interface" : "eth0"
      }
   ]
}

Upvotes: 5

Related Questions