保留 PyYaml 转储

Preserve a PyYaml dump

我正在尝试编辑一个 yaml 文件,但是当我编写新文件时,文件的整个结构都乱七八糟。

换行错误,一些缩进也是错误的,它甚至出于某种原因删除了我的一些参数。这是一个例子:

之前

AWSTemplateFormatVersion: "2010-09-09"
Metadata:
    Generator: "user"
Description: "CloudFormation blah blah"

Parameters:
  VPCEndpointServiceServiceName:
    Description: VPCEndpointServiceServiceName
    Type: String

Mappings:
  PrivateLink:
    EndPoint:
      EndPointName: test
      EndPointVpcId: vpc-123
      SecurityGroupIds: sg-123
      SubnetId1: subnet-123
      SubnetId2: subnet-123

Resources:
    EC2VPCEndpoint:
        Type: "AWS::EC2::VPCEndpoint"
        Properties:
            VpcEndpointType: "Interface"
            VpcId: !FindInMap [PrivateLink, EndPoint, EndPointVpcId]
            ServiceName: !Ref VPCEndpointServiceServiceName
            SubnetIds:
              - !FindInMap [PrivateLink, EndPoint, SubnetId1]
              - !FindInMap [PrivateLink, EndPoint, SubnetId2]
            PrivateDnsEnabled: false
            SecurityGroupIds:
              - !FindInMap [PrivateLink, EndPoint, SecurityGroupIds]

之后

AWSTemplateFormatVersion: '2010-09-09'
Metadata:
  Generator: user
Description: CloudFormation blah blah
Parameters:
  VPCEndpointServiceServiceName:
    Description: VPCEndpointServiceServiceName
    Type: String
Mappings:
  PrivateLink:
    EndPoint:
      EndPointName: test
      EndPointVpcId: vpc-123
      SecurityGroupIds: sg-123
      SubnetId1: subnet-123
      SubnetId2: subnet-123
Resources:
  EC2VPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: Interface
      VpcId:
      - PrivateLink
      - EndPoint
      - EndPointVpcId
      ServiceName: VPCEndpointServiceServiceName
      SubnetIds:
      - - PrivateLink
        - EndPoint
        - SubnetId1
      - - PrivateLink
        - EndPoint
        - SubnetId2
      PrivateDnsEnabled: 'false'
      SecurityGroupIds:
      - - PrivateLink
        - EndPoint
        - SecurityGroupIds

真正奇怪的是,它还删除了 !FindInMap!Ref 等参数。

这是我的函数:

def editEndpointTemplate(endpoint_tempplate_path):
    #read yaml file
    with open(endpoint_tempplate_path) as file:
        data = yaml.load(file, Loader=yaml.BaseLoader)

    data['Mappings']['PrivateLink']['EndPoint']['EndPointName'] = "New Name"

    #write yaml file and overwrite old one.
    with open(endpoint_tempplate_path, 'w') as file:
        yaml.dump(data, file, sort_keys=False)

我想原样保留文件,因为我所做的只是更新几个密钥。

我也遇到了文件按字母顺序排序的问题,但一个简单的 sort_keys=False 解决了这个问题。我想 PyYaml 的任何其他属性都可以解决这个问题,但我想不通。

如有任何帮助,我们将不胜感激。

找到解决方法。我没有使用 PyYamlcfn-tools,而是使用了 ruamel.yaml.

import sys
from ruamel.yaml import YAML

def editEndpointTemplate(endpoint_template_path):
    yaml = YAML()
    yaml.indent(mapping=3)

    #Load yaml file
    with open(endpoint_template_path) as fp:
        data = yaml.load(fp)

    #Change data
    data['Mappings']['PrivateLink']['EndPoint']['EndPointName'] = service_name

    #Dump it back to the same file
    # yaml.dump(data, sys.stdout)
    with open(endpoint_template_path, 'w') as fp:
        yaml.dump(data, fp)

新的 YAML 文件与我的模板完全一样,即使在编辑之后也是如此。