如何用Python为YAML文件添加缩进文本并替换探针配置
问题描述
我有一个YAML文件,想要从另一个YAML文件导入参数,添加并替换其中缺失的参数,但生成的最终文件出了问题:livenessProbe配置没有在正确的缩进位置,反而跑到了文件末尾。需要把该配置替换到对应位置并保持正确的缩进格式。
有问题的YAML文件
--- apiVersion: apps/v1 kind: Deployment metadata: name: ms spec: template: metadata: annotations: cluster-autoscaler.kubernetes.io/safe-to-evict: 'true' spec: containers: - name: ms command: [npm, run, start:prod] resources: requests: memory: 256Mi cpu: 150m limits: memory: 512Mi cpu: 150m readinessProbe: livenessProbe: livenessProbe: failureThreshold: 3 httpGet: path: /LIVENESS port: PORT scheme: HTTP initialDelaySeconds: 30 periodSeconds: 2 successThreshold: 1 timeoutSeconds: 1
当前使用的Python代码
from posixpath import abspath from ruamel.yaml import YAML import yaml import os import sys pathroot = os.getcwd() os.system('clear') text = "requests:" notext = "failureThreshold:" with open('template-live.yaml', 'r') as file: resourceslistlive = yaml.load(file, Loader=yaml.FullLoader) with open('template-ready.yaml', 'r') as file: resourceslistready = yaml.load(file, Loader=yaml.FullLoader) def searchText(path): findString = False with open(path, 'r', encoding='utf-8') as f: content = f.read() if text in content: findString = True if notext in content: findString = False f.close() if findString: with open(path, 'a') as fileA: yaml.dump(resourceslistlive, fileA) with open(path, 'a') as fileB: yaml.dump(resourceslistready, fileB) name = "patch-resources-limit.yaml" archivos = 0 for root, dirs, files in os.walk(pathroot): if name in files: searchText(os.path.join(root, name))
问题根源与修复方案
你的代码问题在于直接用yaml.dump()把内容追加到文件末尾,没有定位到YAML结构中containers下的对应位置,导致配置被放到了根层级,而非容器的子节点里。另外,你导入了ruamel.yaml却没用到,它比标准库yaml更适合处理YAML的结构和缩进保留。
修复步骤
- 用
ruamel.yaml处理YAML结构,保留原文件的缩进和注释,精准修改指定节点 - 定位到
spec.template.spec.containers下的目标容器,替换其中的readinessProbe和livenessProbe - 不再直接追加文件,而是加载原YAML的结构,修改后再写回文件
修改后的代码
import os import ruamel.yaml pathroot = os.getcwd() os.system('clear') # 加载探针配置 with open('template-live.yaml', 'r') as file: yaml = ruamel.yaml.YAML() liveness_probe = yaml.load(file) with open('template-ready.yaml', 'r') as file: readiness_probe = yaml.load(file) def update_yaml(path): # 加载目标YAML文件 yaml = ruamel.yaml.YAML() with open(path, 'r', encoding='utf-8') as f: doc = yaml.load(f) # 检查是否存在目标结构 if not doc or 'spec' not in doc or 'template' not in doc['spec']: return containers = doc['spec']['template']['spec'].get('containers', []) if not containers: return # 找到名为ms的容器,替换探针配置 for container in containers: if container.get('name') == 'ms': container['livenessProbe'] = liveness_probe container['readinessProbe'] = readiness_probe break # 写回修改后的内容 with open(path, 'w', encoding='utf-8') as f: yaml.dump(doc, f) target_file = "patch-resources-limit.yaml" for root, dirs, files in os.walk(pathroot): if target_file in files: update_yaml(os.path.join(root, target_file))
说明
- 使用
ruamel.yaml加载和保存YAML,完美保留原文件的缩进格式 - 直接定位到
containers下的ms容器,将探针配置赋值到对应节点,确保缩进正确 - 不再通过字符串匹配判断,而是直接检查YAML结构是否符合预期,逻辑更可靠
内容的提问来源于stack exchange,提问作者Luis A Delgado Lisińska
相关产品推荐
相关产品推荐

