Обновление файла Yaml с новыми полями с использованием ruamel - PullRequest
0 голосов
/ 18 апреля 2019

Я пытаюсь обновить файл yaml, используя ruamel python.

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.

1 Ответ

1 голос
/ 18 апреля 2019

В вашем файле YAML ваша корневая коллекция является отображением, а значение ключа spec в этом отображении само является отображением.Оба этих отображения загружаются как dict -подобные объекты, используя ruamel.yaml с именем CommentedMap.

Как и в случае обычных dict s, вы можете добавлять пары ключ-значение, удаленные ключи (и их значения)и обновите значения для ключа, но метода .append() нет, как в случае со списком (т. е. добавляется дополнительный элемент в список).

Ваш вывод немного краткий, но, конечно,Вы не можете просто добавить nodeSelector к чему-либо (список / последовательность, ни dict / mapping) и ожидать, что оно автоматически добавит kubernetes.io/hostname: kubew1 (отображение само по себе).

Ваша попытка:

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

не может работать, потому что нет слова result['spec']['nodeSelector'], в которое можно добавить ключ kubernetes.io/hostname.

Сначала вам нужно будет создать ключ со значением emtpy в качестве значения:

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 не очень ясное утверждение, хотя, конечно, контекст часто предоставляет достаточно информации окакую библиотеку вы на самом деле используете.

...