使用ruamel更新Yaml文件,使用新字段

问题描述 投票:0回答:1

我正在尝试使用ruamel python更新yaml文件。

proc=subprocess.Popen(['kubectl','get','pod','web3','-o','yaml','--export'], stdout=subprocess.PIPE)
rein=proc.stdout.read()
result, indent, block_seq_indent = ruamel.yaml.util.load_yaml_guess_indent(rein, preserve_quotes=True)

到目前为止,我尝试过:

result['spec'].append('nodeSelector')

这给出了错误:

result['spec'].append('nodeSelector')
AttributeError: 'CommentedMap' object has no attribute 'append'

也试过这样:

result['spec']['nodeSelector']['kubernetes.io/hostname']='kubew1'

给出:

result['spec']['nodeSelector']['kubernetes.io/hostname']='kubew1'
File "/usr/local/lib/python3.6/dist-packages/ruamel/yaml/comments.py", line 752, in __getitem__
return ordereddict.__getitem__(self, key)
KeyError: 'nodeSelector'

我的初始Yaml文件是:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    app: demo
    name: web
  name: web3
  selfLink: /api/v1/namespaces/default/pods/web3
spec:
  containers:
  - image: aexlab/flask-sample-one
    imagePullPolicy: Always
    name: web
    ports:
    - containerPort: 5000
      name: http
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-7bcc9
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true

我希望在'spec'中添加的预期字段是:

  nodeSelector:
    kubernetes.io/hostname: kubew1

任何想法如何用ruamel库实现这一点。

yaml pyyaml ruamel.yaml
1个回答
1
投票

在您的YAML文件中,您的根级别集合是一个映射,该映射中的密钥spec的值本身就是一个映射。使用名为dictruamel.yaml将这两个映射作为CommentedMap类对象加载。

与普通的dicts一样,你可以添加键值对,删除的键(及其值),以及更新键的值,但是没有.append()方法,因为有一个列表(即在列表中附加一个额外的项) 。

你的输出有点简洁,但当然你不能只将nodeSelector添加到任何东西(列表/序列或dict / mapping),并期望自动添加kubernetes.io/hostname: kubew1(一个映射本身)。

你的尝试:

result['spec']['nodeSelector']['kubernetes.io/hostname'] = 'kubew1'

不能工作,因为没有字母result['spec']['nodeSelector'],你可以添加密钥kubernetes.io/hostname

您首先必须使用空dict创建一个键作为值:

result['spec']['nodeSelector'] = {}
result['spec']['nodeSelector']['kubernetes.io/hostname'] = 'kubew1'

或者做

result['spec']['nodeSelector'] = {'kubernetes.io/hostname']: 'kubew1'}

请注意,上面与ruamel.yaml没什么关系,这只是基本的Python数据结构操作。另请注意,ruamel命名空间中有超过100个库,其中ruamel.yaml只是作为开源源发布的几个库中的一个,因此使用ruamel的语句不是很清楚,尽管当然上下文通常提供了关于您实际上库的足够信息使用。

© www.soinside.com 2019 - 2024. All rights reserved.