contenido
Manipulación de archivos YAML en Python
1. Resumen
Al desarrollar el sistema de publicación de contenedores, dado que necesita llamar a la API de k8s, es necesario lidiar con los formatos de contenido YAML, como la implementación y el servicio de k8s.
Primero introduzcamos YAML
Nombre completo de YAML YAML no es lenguaje de marcado, el objetivo principal del diseño es una alta legibilidad humana.
YAML 1.2 es un superconjunto de JSON, lo que significa que el JSON legal lanzado al analizador YAML 1.2 se puede analizar perfectamente
1. reglas del archivo yaml
- distingue mayúsculas y minúsculas;
- Use sangría para indicar relaciones jerárquicas;
- Aplicar sangría con la barra espaciadora en lugar de la tecla de tabulación
- El número de espacios sangrados no es fijo, solo los elementos del mismo nivel deben alinearse a la izquierda;
- Las cadenas en el archivo no necesitan estar marcadas con comillas, pero si las cadenas contienen caracteres especiales, necesitan estar marcadas con comillas;
- Los comentarios están marcados con #
2. estructura de datos del archivo yaml
- Objeto: una colección de pares clave-valor ("mapa o diccionario" para abreviar)
- El par clave-valor está representado por una estructura de dos puntos ":", y los dos puntos y el valor deben estar separados por un espacio
- Array: Un conjunto ordenado de valores ("secuencia o lista" para abreviar)
- La matriz está precedida por un símbolo "-", y el símbolo y el valor deben estar separados por un espacio
- escalares: valores únicos e indivisibles (como cadenas, booleanos, enteros, flotantes, horas, fechas, nulos, etc.)
- El valor de Ninguno se puede representar por nulo y ~
3. Escenarios de uso
YAML En términos generales, existen muchos escenarios para la serialización y los archivos de configuración.
Además, YAML se puede convertir a formato Json
En segundo lugar, el uso de Python
Hay dos formas de operar yaml en Python:
- pyyaml
pip3 install pyyaml
- ruamel (recomendado):
pip3 install ruamel.yaml
1. pyyaml
pyyaml es el paquete oficial que viene con python, el documento oficial es: https://pyyaml.org/wiki/PyYAML
Instalar en pc:
pip3 install pyyaml
Leer:yaml.load
import yaml
# 读取yaml内容
yaml_content = yaml.load("""
name: Vorlin Laruknuzum
sex: Male
class: Priest
title: Acolyte
hp: [32, 71]
sp: [1, 13]
gold: 423
inventory:
- a Holy Book of Prayers (Words of Wisdom)
- an Azure Potion of Cure Light Wounds
- a Silver Wand of Wonder
""", Loader=yaml.FullLoader)
print(yaml_content['name'])
# 读取yaml文件
with open(r'test.yaml', 'r') as f:
yaml.load(f, Loader=yaml.FullLoader)
escribe:yaml.dump
import yaml
# 读取yaml内容
yaml_content = yaml.load("""
name: Vorlin Laruknuzum
sex: Male
class: Priest
title: Acolyte
hp: [32, 71]
sp: [1, 13]
gold: 423
inventory:
- a Holy Book of Prayers (Words of Wisdom)
- an Azure Potion of Cure Light Wounds
- a Silver Wand of Wonder
""", Loader=yaml.FullLoader)
yaml_content['name'] = 'New Name'
new_yaml = yaml.dump(yaml_content)
print(new_yaml)
Sin embargo, hay yaml.dump
un problema:
- No se pueden manejar los datos del diccionario anidado del diccionario
- Después de guardar, no es la forma estándar de yaml
- se pierden las comillas dobles
Por ejemplo aquí hay un ejemplo:
El contenido de yaml es:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
annotations:
creator: admin
description: mbs-statement-service
owner_name: mbs-statement-service
sidecar.istio.io/inject: "false"
creationTimestamp: null
labels:
app: mbs-statement-service
version: "07071418"
name: mbs-statement-service-07071418
namespace: bankapp
spec:
replicas: 1
selector:
matchLabels:
app: mbs-statement-service
version: "07071418"
strategy: {}
template:
metadata:
annotations:
creator: admin
description: mbs-statement-service
owner_name: mbs-statement-service
sidecar.istio.io/inject: "false"
creationTimestamp: null
labels:
app: mbs-statement-service
version: "07071418"
name: mbs-statement-service-07071418
namespace: bankapp
spec:
containers:
- command:
- /bin/sh
- -c
- /usr/local/jdk1.8.0_172/bin/java -jar $(JAVA_OPTS) $(GCLOG_OPTS) $(SHOOTING_OPTS)
$(APOLLO_OPTS)
mbs-statement-service.jar
image: vb-harbor.in.xx/xxx/mbs-statement-service:uat_20200528_v2
imagePullPolicy: IfNotPresent
Usando PyYaml para procesar:
import yaml
deployment_obj = yaml.load(yaml_content, Loader=yaml.FullLoader)
for key, containers in enumerate(deployment_obj['spec']['template']['spec']['containers']):
deployment_obj['spec']['template']['spec']['containers'][key]['image'] = "$IMAGE_URL"
k8s_deployment = yaml.dump(deployment_obj)
print(k8s_deployment)
Después de imprimirlo, hay un problema con el formato, faltan las comillas dobles para la versión:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
annotations:
creator: admin
description: mbs-statement-service
owner_name: mbs-statement-service
sidecar.istio.io/inject: 'false'
creationTimestamp: null
labels:
app: mbs-statement-service
version: 07071418
name: mbs-statement-service-07071418
namespace: bankapp
spec:
replicas: 1
selector:
matchLabels:
app: mbs-statement-service
version: 07071418
strategy: {}
template:
metadata:
annotations:
creator: admin
description: mbs-statement-service
owner_name: mbs-statement-service
sidecar.istio.io/inject: 'false'
creationTimestamp: null
labels:
app: mbs-statement-service
version: 07071418
name: mbs-statement-service-07071418
namespace: bankapp
spec:
containers:
- command:
- /bin/sh
- -c
- /usr/local/jdk1.8.0_172/bin/java -jar $(JAVA_OPTS) $(GCLOG_OPTS) $(SHOOTING_OPTS)
$(APOLLO_OPTS) mbs-statement-service.jar
image: $IMAGE_URL
imagePullPolicy: IfNotPresent
usar default_style
para procesar
import yaml
deployment_obj = yaml.load(yaml_content, Loader=yaml.FullLoader)
for key, containers in enumerate(deployment_obj['spec']['template']['spec']['containers']):
deployment_obj['spec']['template']['spec']['containers'][key]['image'] = "$IMAGE_URL"
k8s_deployment = yaml.dump(deployment_obj, default_style='"')
print(k8s_deployment)
Imprime que el problema es mayor, aparecerá:"replicas": !!int "1"
"apiVersion": "apps/v1beta1"
"kind": "Deployment"
"metadata":
"annotations":
"creator": "admin"
"description": "mbs-statement-service"
"owner_name": "mbs-statement-service"
"sidecar.istio.io/inject": "false"
"creationTimestamp": !!null "null"
"labels":
"app": "mbs-statement-service"
"version": "07071418"
"name": "mbs-statement-service-07071418"
"namespace": "bankapp"
"spec":
"replicas": !!int "1"
"selector":
"matchLabels":
"app": "mbs-statement-service"
"version": "07071418"
"strategy": {}
"template":
"metadata":
"annotations":
"creator": "admin"
"description": "mbs-statement-service"
"owner_name": "mbs-statement-service"
"sidecar.istio.io/inject": "false"
"creationTimestamp": !!null "null"
"labels":
"app": "mbs-statement-service"
"version": "07071418"
"name": "mbs-statement-service-07071418"
"namespace": "bankapp"
"spec":
"containers":
- "command":
- "/bin/sh"
- "-c"
- "/usr/local/jdk1.8.0_172/bin/java -jar $(JAVA_OPTS) $(GCLOG_OPTS) $(SHOOTING_OPTS)\
\ $(APOLLO_OPTS) mbs-statement-service.jar"
"image": "$IMAGE_URL"
"imagePullPolicy": "IfNotPresent"
Por lo tanto, debe usar el siguiente ruamel.Usar el siguiente ruamel no eliminará las comillas después de la versión
2. Ruamel
PyYaml es el más utilizado, pero la API encapsulada no es lo suficientemente simple y no admite la última versión de YAML 1.2, por lo que puede usar ruamel en su lugar, ruamel.yaml es un derivado de PyYaml, la API empaquetada es simple y admite la última versión de YAML 1.2
El uso es básicamente el mismo que PyYAML
Instalar en pc
pip3 install ruamel.yaml
Leer:yaml.load
from ruamel import yaml
# 读取yaml内容
yaml_content = yaml.load("""
name: Vorlin Laruknuzum
sex: Male
class: Priest
title: Acolyte
hp: [32, 71]
sp: [1, 13]
gold: 423
inventory:
- a Holy Book of Prayers (Words of Wisdom)
- an Azure Potion of Cure Light Wounds
- a Silver Wand of Wonder
""", Loader=yaml.Loader)
print(yaml_content['name'])
# 读取yaml文件
with open(r'test.yaml', 'r') as f:
yaml.load(f, Loader=yaml.Loader)
escribe:yaml.dump
from ruamel import yaml
# 读取yaml内容
yaml_content = yaml.load("""
name: Vorlin Laruknuzum
sex: Male
class: Priest
title: Acolyte
hp: [32, 71]
sp: [1, 13]
gold: 423
inventory:
- a Holy Book of Prayers (Words of Wisdom)
- an Azure Potion of Cure Light Wounds
- a Silver Wand of Wonder
""", Loader=yaml.Loader)
yaml_content['name'] = 'New Name'
new_yaml = yaml.dump(yaml_content, Dumper=yaml.RoundTripDumper)
print(new_yaml)