使用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" ])] ))