2023-11-20 12:34:46 +00:00
#!/usr/bin/env python
import os
import sys
import datetime
import yaml
def contexts ( device , config_contexts ) :
# print(f'device: {device}')
all_config_contexts = { }
def remove_meta ( data ) :
try :
del data [ ' _metadata ' ]
except KeyError :
pass
return data
# get device context
try :
with open ( f ' ./config_contexts/device/ { device } .yml ' , ' r ' ) as file :
data = yaml . safe_load ( file )
all_config_contexts . update ( { ' device ' : { ' weight ' : 0 , ' content ' : remove_meta ( data ) } } )
except :
pass
# get config_contexts
for k , v in config_contexts . items ( ) :
islist = False
if isinstance ( v , list ) :
islist = True
vlist = v
else :
vlist = [ v ]
for i in vlist :
try :
if islist :
context_name = f ' { k } _ { i } '
else :
context_name = k
with open ( f ' ./config_contexts/ { k } / { i } .yml ' , ' r ' ) as file :
data = yaml . safe_load ( file )
if data [ ' _metadata ' ] [ ' weight ' ] and data [ ' _metadata ' ] [ ' is_active ' ] :
all_config_contexts . update ( { context_name : { ' weight ' : data [ ' _metadata ' ] [ ' weight ' ] , ' content ' : remove_meta ( data ) } } )
except :
pass
# get the all context
all_weight = sorted ( [ all_config_contexts [ k ] [ ' weight ' ] for k , v in all_config_contexts . items ( ) ] , reverse = True )
dupe_weight = list ( set ( [ x for x in all_weight if all_weight . count ( x ) > 1 ] ) )
max_weight = all_weight [ 0 ] + 1
try :
with open ( ' ./config_contexts/all.yml ' , ' r ' ) as file :
data = yaml . safe_load ( file )
if data [ ' _metadata ' ] [ ' is_active ' ] :
all_config_contexts . update ( { ' all ' : { ' weight ' : max_weight , ' content ' : remove_meta ( data ) } } )
except :
pass
# print(yaml.dump(all_config_contexts))
# check for equally weighted clashing keys
equal_weight = { }
for i in dupe_weight :
equal_weight . update ( { i : [ ] } )
for k in all_config_contexts . keys ( ) :
if all_config_contexts [ k ] [ ' weight ' ] == i :
equal_weight [ i ] . append ( k )
# print(f'equal weight contexts: {equal_weight}')
# list all keys in equally weighted contexts
keys_list = [ ]
for k in equal_weight . keys ( ) :
for i in equal_weight [ k ] :
for k in all_config_contexts [ i ] [ ' content ' ] . keys ( ) :
keys_list . append ( k )
keys_list = list ( set ( keys_list ) )
# print(f'all keys in equal weight contexts: {keys_list}')
# check each equally weighted context for clashing keys
equal_weight_key_clash_errors = [ ]
for w in equal_weight :
for k in keys_list :
key_occurance = [ ]
for i in equal_weight [ w ] :
if k in all_config_contexts [ i ] [ ' content ' ] :
key_occurance . append ( i )
if len ( key_occurance ) > 1 :
equal_weight_key_clash_errors . append ( f ' clashing key found in equally weighted contexts: \n key: { k } \n contexts: { key_occurance } ' )
if len ( equal_weight_key_clash_errors ) > 0 :
error_log = f ' device config_context render issue: { device } \n '
for i in equal_weight_key_clash_errors :
error_log = error_log + f ' \n { i } \n '
print ( error_log )
return
# reorder all_config_contexts by weight, update the config_context with each context in order of precedence, overwriting keys where they exist (the last context being the lowest weight and highest precedence)
config_context = { }
all_config_contexts = { k : v for k , v in sorted ( all_config_contexts . items ( ) , key = lambda x : x [ 1 ] [ ' weight ' ] , reverse = True ) }
for k , v in all_config_contexts . items ( ) :
config_context = { * * config_context , * * v [ ' content ' ] }
config_context = dict ( sorted ( config_context . items ( ) ) )
print ( yaml . dump ( config_context ) )
return config_context
def main ( ) :
with open ( ' ./inventory.yml ' , ' r ' ) as file :
data = yaml . safe_load ( file )
for i in data . keys ( ) :
contexts ( i , data [ i ] [ ' config_contexts ' ] )
if __name__ == " __main__ " :
main ( )
# what does this need to do?
# render a config_context
# render a jinja2 template
2023-11-20 16:26:05 +00:00
# print out a rendered context for someone when writing jinja2 templates