使用python中的YAML的分层配置。
最新版本是:0.15.2
Python模块,可让您使用YAML语法合并层次结构配置文件。它提供了深层合并,可变的插值和秘密经理的秘密检索。
如果您想以避免重复的方式构建层次结构,这是理想的选择。您可以使用层次结构来定义配置的结构,例如环境/project/cluster/app。您要在此层次结构中使用哪些层。该工具将读取从根开始(默认值为)开始到叶子的所有YAML文件(最特定的值是在哪里,这将是优先级)。
主意来自木偶的hiera。
pipdocker映像dictpip pip install himldocker映像docker run ghcr.io/adobe/himl:latest himl-config-merger --help请参阅以下网址:https://github.com/adobe/himl/pkgs/container/himl/versions
git clone https://github.com/adobe/himl
cd himl
sudo python install -e .
这将合并简单/默认
from himl import ConfigProcessor
config_processor = ConfigProcessor ()
path = "examples/simple/production"
filters = () # can choose to output only specific keys
exclude_keys = () # can choose to remove specific keys
output_format = "yaml" # yaml/json
config_processor . process ( path = path , filters = filters , exclude_keys = exclude_keys ,
output_format = output_format , print_data = True )上面的示例将合并simple/default.yaml与simple/production/env.yaml :
$ tree examples/simple
examples/simple
├── default.yaml
└── production
└── env.yaml
该示例还展示了列表和地图的深入合并。
examples/simple/default.yaml
---
env : default
deep :
key1 : v1
key2 : v2
deep_list :
- item1
- item2 examples/simple/production/env.yaml
---
env : prod
deep :
key3 : v3
deep_list :
- item3结果:
env : prod
deep :
key1 : v1
key2 : v2
key3 : v3
deep_list :
- item1
- item2
- item3通过pip自动安装了称为himl的CLI工具。您可以使用它来解析YAML的树,它将以标准输出输出组合配置或将其写入文件。
usage: himl [-h] [--output-file OUTPUT_FILE] [--format OUTPUT_FORMAT]
[--filter FILTER] [--exclude EXCLUDE]
[--skip-interpolation-validation]
[--skip-interpolation-resolving] [--enclosing-key ENCLOSING_KEY]
[--cwd CWD]
[--list-merge-strategy {append,override,prepend,append_unique}]
pathhiml examples/complex/env=dev/region=us-east-1/cluster=cluster2基于示例/复杂文件夹的配置树,上述命令的输出将如下:
cluster:
description: 'This is cluster: cluster2. It is using c3.2xlarge instance type.'
name: cluster2
node_type: c3.2xlarge
region:
location: us-east-1
env: dev
示例文件夹看起来像这样的地方:
$ tree examples/complex
examples/complex
├── default.yaml
├── env=dev
│ ├── env.yaml
│ ├── region=us-east-1
│ │ ├── cluster=cluster1
│ │ │ └── cluster.yaml
│ │ ├── cluster=cluster2
│ │ │ └── cluster.yaml
│ │ └── region.yaml
│ └── region=us-west-2
│ ├── cluster=cluster1
│ │ └── cluster.yaml
│ └── region.yaml
└── env=prod
├── env.yaml
└── region=eu-west-2
├── cluster=ireland1
│ └── cluster.yaml
└── region.yaml
为了避免重复,我们希望使一个值一次定义一个值并在YAML配置的其他部分重复使用它。与YAML锚不同,这些插值在多个文件中起作用。
data/default.yaml :
allowed_roles :
- " arn:aws:iam::{{account.id}}:role/myrole " data/dev/env.yaml :
account:
id: "123456"
dict projects :
webapp1 :
tagging :
Owner : " Web Service Team "
Environment : " dev "
CostCenter : " 123 "
data-store :
Owner : " Backend Team "
Environment : " dev "
CostCenter : " 455 "
# this will copy the whole projects.webapp1.tagging dict to this key
tagging : " {{projects.webapp1.tagging}} "
# or even a double interpolation
tagging : " {{projects.{{project.name}}.tagging}} "可以在多个文件中具有相同的密钥(例如dict/list),并使用深层合并组合它们。在这里查看一个示例。
passphrase : " {{ssm.path(/key/coming/from/aws/secrets/store/manager).aws_profile(myprofile)}} " my_value : " {{s3.bucket(my-bucket).path(path/to/file.txt).base64encode(true).aws_profile(myprofile)}} " 使用Vault CLI通过LDAP身份验证后备方法。
从秘密中仅检索一个键值,路径尾部被用作钥匙:
my_value : " {{vault.key(/path/from/vault/key)}} "从保险库路径中检索所有密钥/值对:
my_dict : " {{vault.path(/path/from/vault)}} "为政策生成一个令牌:
my_token : " {{vault.token_policy(my_vault_policy)}} " # ## Terraform remote states ###
remote_states :
- name : cluster_composition
type : terraform
aws_profile : " my_aws_profile "
s3_bucket : " my_terraform_bucket "
s3_key : " mycluster.tfstate "
endpoint : " {{outputs.cluster_composition.output.value.redis_endpoint}} " kubeconfig_location : " {{env(KUBECONFIG)}} " himl-config-merger脚本包含合并层次配置目录并创建最终结果YAML文件的逻辑。
himl-config-merger examples/complex --output-dir merged_output --levels env region cluster --leaf-directories cluster INFO:__main__:Found input config directory: examples/complex/env=prod/region=eu-west-2/cluster=ireland1
INFO:__main__:Storing generated config to: merged_output/prod/eu-west-2/ireland1.yaml
INFO:__main__:Found input config directory: examples/complex/env=dev/region=us-west-2/cluster=cluster1
INFO:__main__:Storing generated config to: merged_output/dev/us-west-2/cluster1.yaml
INFO:__main__:Found input config directory: examples/complex/env=dev/region=us-east-1/cluster=cluster1
INFO:__main__:Storing generated config to: merged_output/dev/us-east-1/cluster1.yaml
INFO:__main__:Found input config directory: examples/complex/env=dev/region=us-east-1/cluster=cluster2
INFO:__main__:Storing generated config to: merged_output/dev/us-east-1/cluster2.yaml
输入示例:
> tree examples/complex
examples/complex
├── default.yaml
├── env=dev
│ ├── env.yaml
│ ├── region=us-east-1
│ │ ├── cluster=cluster1
│ │ │ └── cluster.yaml
│ │ ├── cluster=cluster2
│ │ │ └── cluster.yaml
│ │ └── region.yaml
│ └── region=us-west-2
│ ├── cluster=cluster1
│ │ └── cluster.yaml
│ └── region.yaml
└── env=prod
├── env.yaml
└── region=eu-west-2
├── cluster=ireland1
│ └── cluster.yaml
└── region.yaml
输出:
merged_output
├── dev
│ ├── us-east-1
│ │ ├── cluster1.yaml
│ │ └── cluster2.yaml
│ └── us-west-2
│ └── cluster1.yaml
└── prod
└── eu-west-2
└── ireland1.yaml
利用HIML,Config-Merger脚本加载了Configs Tree结构和深信息,并从从根路径到边缘找到的所有YAML文件中的所有键。对于每个叶子目录,将在--output-dir下创建一个文件。
在每个级别下,Config-Mererger都使用一个强制性的“级别密钥”来计算最终结果。该键应在每个级别下的一个文件之一中存在。 (例如,在Env下的Env.Yaml)。
在末尾(LEAF)结果中可能不需要在较高级别的目录树中指定的某些配置。因此,config-merger脚本可以应用一组通过--filter-rules-key参数指定的过滤器规则。该属性必须存在于配置中,并包含从输出中删除根级键的规则。如果选择器对象匹配输出键的子集,并且将在values列表中指定的键或匹配regex模式的键中指定的键,则将应用该过滤器。
# intermediate config after hierarchical merge
env : dev
cluster : cluster1
region : us-east-1
key1 : persisted
key2 : dropped
keep_1 : persisted
tags :
cost_center : 123
_filters :
- selector :
env : " dev "
keys :
values :
- key1
regex : " keep_.* "
- selector :
cluster :
regex : " cluster1 "
keys :
values :
- tags通过过滤构建输出:
himl-config-merger examples/filters --output-dir merged_output --levels env region cluster --leaf-directories cluster --filter-rules-key _filters # output after filtering
env : dev
cluster : cluster1
region : us-east-1
key1 : persisted
keep_1 : persisted
tags :
cost_center : 123 规则选择器和钥匙过滤仅在配置的根级别上起作用。无法过滤嵌套键。
除了在PyYaml库中找到的标准功能外, himl-config-merger组件还实现了一个自定义的YAML标签,称为!include
例子:
VA7 : !include configs/env=int/region=va7/kafka-brokers.yaml regionBrokers.VA7这将在插值后用regionbrokers.va7的值替换值。
可选的参数type_strategies可以将其传递到ConfigProcessor中,以定义自定义合并行为。可能是适合您需求的自定义功能。您的功能应采用(配置,路径,基础,NXT)的参数,并返回合并的结果。
例子:
from himl import ConfigProcessor
def strategy_merge_override ( config , path , base , nxt ):
"""merge list of dicts. if objects have same id, nxt replaces base."""
"""if remove flag is present in nxt item, remove base and not add nxt"""
result = deepcopy ( base )
for nxto in nxt :
for baseo in result :
# if list is not a list of dicts, bail out and let the next strategy to execute
if not isinstance ( baseo , dict ) or not isinstance ( nxto , dict ):
return STRATEGY_END
if 'id' in baseo and 'id' in nxto and baseo [ 'id' ] == nxto [ 'id' ]:
result . remove ( baseo ) #same id, remove previous item
if 'remove' not in nxto :
result . append ( nxto )
return result
config_processor = ConfigProcessor ()
path = "examples/simple/production"
filters = () # can choose to output only specific keys
exclude_keys = () # can choose to remove specific keys
output_format = "yaml" # yaml/json
config_processor . process ( path = path , filters = filters , exclude_keys = exclude_keys ,
output_format = output_format , print_data = True ,
type_strategies = [( list , [ strategy_merge_override , 'append' ]), ( dict , [ "merge" ])] ))