Я экспериментирую с написанием механизма переменных конфигурации, который принимает файл YAML (содержащий переменные конфигурации AWS) в качестве входных данных и преобразует их в JSON, чтобы он мог быть загружен в API k/v HTTP (например, Consul). Функция, с которой я столкнулся, позволит разработчику «включить» наборы ключей (обозначенные символом подчеркивания, которые опущены в конечной полезной нагрузке) в последующих ключах. Образец выглядит следующим образом:Как я могу переписать через словарь и динамически обновлять значения, чтобы впоследствии их можно было называть?
# Region
us-east-1:
# Any key preceded by an underscore (_) is considered a "tag group" and will not be uploaded to Consul KV unless explicitly included.
_taggroup1:
key1: value1
key2: value2
key3: value3
_taggroup2:
key4: value1
key5: value2
key6: value3
dev:
_include: us-east-1/_taggroup1
qa:
_include:
- us-east-1/_taggroup1
- us-east-1/_taggroup2
key6: baz
prod:
_include:
- us-east-1/_taggroup1
- us-east-1/_taggroup2
us-west-1:
_taggroup1:
key1: value1
key2: value2
key3: value3
_taggroup2:
key4: value1
key5: value2
key6: value3
dev:
_include:
- us-west-1/_taggroup1
qa:
_include:
- us-west-1/_taggroup1
- us-west-1/_taggroup2
key2: foo
prod:
_include:
- us-west-1/_taggroup1
- us-west-1/_taggroup2
key4: foo
key5: bar
key1: undef
us-west-1a:
qa:
_include: us-west-1/qa
prod:
_include: us-west-1/prod
us-west-1b:
_include: us-west-1/us-west-1a
Как вы можете видеть, что я пытаюсь структурировать конфигурационный файл, который позволяет разработчикам группировать переменные и subsquently включать/переопределить их, если они пожелают.
Код я написал для этого эксперимента, до сих пор, по существу, ваша стандартная функция рекурсии с добавлением специфичных для данного применения:
# parse_input is a separate function that converts a YAML stream into
# an OrderedDict
original_dict = parse_input(stream1)
def print_dict(input_dict):
new_dict = collections.OrderedDict()
for key, value in input_dict.iteritems():
if key.startswith('_'):
if key == '_include':
if isinstance(value, list):
for item in value:
x = dpath.util.get(original_dict, item)
for k, v in x.iteritems():
new_dict[k] = v
else:
x = dpath.util.get(original_dict, value)
for k, v in x.iteritems():
new_dict[k] = v
else:
continue
continue
elif isinstance(value, dict):
new_dict[key] = print_dict(value)
else:
new_dict[key] = value
return new_dict
Выход так далеко, что я достиг как таковой:
{
"us-east-1": {
"dev": {
"key1": "value1",
"key2": "value2",
"key3": "value3"
},
"qa": {
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value1",
"key5": "value2",
"key6": "baz"
},
"prod": {
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value1",
"key5": "value2",
"key6": "value3"
}
},
"us-west-1": {
"dev": {
"key1": "value1",
"key2": "value2",
"key3": "value3"
},
"qa": {
"key1": "value1",
"key2": "foo",
"key3": "value3",
"key4": "value1",
"key5": "value2",
"key6": "value3"
},
"prod": {
"key1": "undef",
"key2": "value2",
"key3": "value3",
"key4": "foo",
"key5": "bar",
"key6": "value3"
},
"us-west-1a": {
"qa": {
"_include": [
"us-west-1/_taggroup1",
"us-west-1/_taggroup2"
],
"key2": "foo"
},
"prod": {
"_include": [
"us-west-1/_taggroup1",
"us-west-1/_taggroup2"
],
"key4": "foo",
"key5": "bar",
"key1": "undef"
}
},
"us-west-1b": {
"qa": {
"_include": "us-west-1/qa"
},
"prod": {
"_include": "us-west-1/prod"
}
}
}
}
Как видите, я оказываюсь на полпути. Моя проблема заключается в том, что в моем первоначальном эксперименте я получал благоприятные результаты, ссылаясь на переменную original_dict
в функции при ссылке на набор include (с помощью dpath
для возврата ключей). Это быстро превращается в проблему, так как функция рекурсирует глубже (т. Е. AZ-специфические переменные в этом случае), так как я не знаю, как динамически обновлять ключи в исходном dict или иначе отслеживать изменения, поэтому функция будет вводить ключ с _include
ключами и не может их повторно оценить.
Как устранить в зависимости от ссылки на оригинальный словарь и скорее динамически отслеживать изменения, чтобы ключи _include
были должным образом оценены глубже в дереве?
Это, кажется, работает! Спасибо, я (очевидно) еще не пробовал! :) – asdoylejr