2020-09-21 16:41:58 +02:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import logging
import argparse
2021-10-18 13:06:43 +02:00
from lookyloo . default import get_homedir
2020-09-21 16:41:58 +02:00
def validate_generic_config_file ( ) :
2021-12-22 10:55:46 +01:00
sample_config = get_homedir ( ) / ' config ' / ' generic.json.sample '
with sample_config . open ( ) as f :
2020-09-21 16:41:58 +02:00
generic_config_sample = json . load ( f )
# Check documentation
for key in generic_config_sample . keys ( ) :
if key == ' _notes ' :
continue
if key not in generic_config_sample [ ' _notes ' ] :
raise Exception ( f ' ###### - Documentation missing for { key } ' )
2021-12-22 10:55:46 +01:00
user_config = get_homedir ( ) / ' config ' / ' generic.json '
if not user_config . exists ( ) :
# The config file was never created, copy the sample.
with user_config . open ( ' w ' ) as _fw :
json . dump ( generic_config_sample , _fw )
with user_config . open ( ) as f :
generic_config = json . load ( f )
2020-09-21 16:41:58 +02:00
# Check all entries in the sample files are in the user file, and they have the same type
for key in generic_config_sample . keys ( ) :
if key == ' _notes ' :
continue
if generic_config . get ( key ) is None :
logger . warning ( f ' Entry missing in user config file: { key } . Will default to: { generic_config_sample [ key ] } ' )
continue
if not isinstance ( generic_config [ key ] , type ( generic_config_sample [ key ] ) ) :
raise Exception ( f ' Invalid type for { key } . Got: { type ( generic_config [ key ] ) } ( { generic_config [ key ] } ), expected: { type ( generic_config_sample [ key ] ) } ( { generic_config_sample [ key ] } ) ' )
if isinstance ( generic_config [ key ] , dict ) :
# Check entries
for sub_key in generic_config_sample [ key ] . keys ( ) :
2021-05-27 17:03:03 +02:00
if sub_key not in generic_config [ key ] :
raise Exception ( f ' { sub_key } is missing in generic_config[key]. Default from sample file: { generic_config_sample [ key ] [ sub_key ] } ' )
2020-09-21 16:41:58 +02:00
if not isinstance ( generic_config [ key ] [ sub_key ] , type ( generic_config_sample [ key ] [ sub_key ] ) ) :
raise Exception ( f ' Invalid type for { sub_key } in { key } . Got: { type ( generic_config [ key ] [ sub_key ] ) } ( { generic_config [ key ] [ sub_key ] } ), expected: { type ( generic_config_sample [ key ] [ sub_key ] ) } ( { generic_config_sample [ key ] [ sub_key ] } ) ' )
# Make sure the user config file doesn't have entries missing in the sample config
for key in generic_config . keys ( ) :
if key not in generic_config_sample :
2021-12-22 10:55:46 +01:00
raise Exception ( f ' { key } is missing in the sample config file. You need to compare { user_config } with { sample_config } . ' )
2020-09-21 16:41:58 +02:00
2020-09-28 13:32:19 +02:00
return True
2020-09-21 16:41:58 +02:00
def validate_modules_config_file ( ) :
with ( get_homedir ( ) / ' config ' / ' modules.json ' ) . open ( ) as f :
modules_config = json . load ( f )
with ( get_homedir ( ) / ' config ' / ' modules.json.sample ' ) . open ( ) as f :
modules_config_sample = json . load ( f )
for key in modules_config_sample . keys ( ) :
if key == ' _notes ' :
continue
if not modules_config . get ( key ) :
logger . warning ( f ' Entry missing in user config file: { key } . Will default to: { json . dumps ( modules_config_sample [ key ] , indent = 2 ) } ' )
continue
2020-09-28 13:32:19 +02:00
return True
2020-09-21 16:41:58 +02:00
def update_user_configs ( ) :
for file_name in [ ' generic ' , ' modules ' ] :
with ( get_homedir ( ) / ' config ' / f ' { file_name } .json ' ) . open ( ) as f :
try :
generic_config = json . load ( f )
except Exception :
generic_config = { }
with ( get_homedir ( ) / ' config ' / f ' { file_name } .json.sample ' ) . open ( ) as f :
generic_config_sample = json . load ( f )
has_new_entry = False
for key in generic_config_sample . keys ( ) :
if key == ' _notes ' :
continue
if generic_config . get ( key ) is None :
print ( f ' { key } was missing in { file_name } , adding it. ' )
2020-09-28 13:32:19 +02:00
print ( f " Description: { generic_config_sample [ ' _notes ' ] [ key ] } " )
2020-09-21 16:41:58 +02:00
generic_config [ key ] = generic_config_sample [ key ]
has_new_entry = True
2021-05-27 17:03:03 +02:00
elif isinstance ( generic_config [ key ] , dict ) :
for sub_key in generic_config_sample [ key ] . keys ( ) :
if sub_key not in generic_config [ key ] :
print ( f ' { sub_key } was missing in { key } from { file_name } , adding it. ' )
generic_config [ key ] [ sub_key ] = generic_config_sample [ key ] [ sub_key ]
has_new_entry = True
2020-09-21 16:41:58 +02:00
if has_new_entry :
with ( get_homedir ( ) / ' config ' / f ' { file_name } .json ' ) . open ( ' w ' ) as fw :
json . dump ( generic_config , fw , indent = 2 , sort_keys = True )
2020-09-28 13:32:19 +02:00
return has_new_entry
2020-09-21 16:41:58 +02:00
if __name__ == ' __main__ ' :
logger = logging . getLogger ( ' Lookyloo - Config validator ' )
parser = argparse . ArgumentParser ( description = ' Check the config files. ' )
parser . add_argument ( ' --check ' , default = False , action = ' store_true ' , help = ' Check if the sample config and the user config are in-line ' )
parser . add_argument ( ' --update ' , default = False , action = ' store_true ' , help = ' Update the user config with the entries from the sample config if entries are missing ' )
args = parser . parse_args ( )
if args . check :
2020-09-28 13:32:19 +02:00
if validate_generic_config_file ( ) :
print ( f " The entries in { get_homedir ( ) / ' config ' / ' generic.json ' } are valid. " )
if validate_modules_config_file ( ) :
print ( f " The entries in { get_homedir ( ) / ' config ' / ' modules.json ' } are valid. " )
2020-09-21 16:41:58 +02:00
if args . update :
2020-09-28 13:32:19 +02:00
if not update_user_configs ( ) :
print ( f " No updates needed in { get_homedir ( ) / ' config ' / ' generic.json ' } . " )