Het gedrag dat hier bijt is gespecificeerd, en niet toevallig: de YAML 1.2 specificatie definieert hoe een niet-geciteerde scalair wordt omgezet in een type.
Ik heb ooit een implementatie verzonden die een service naar versie heeft vastgezet 1.1 Wanneer het configuratiebestand duidelijk zei: 1.10. Geen typfout. Geen slechte vondst en vervangen. Het YAML-bestand, dat ik vier keer had gelezen, zei dit:
image_tag: 1.10
en de parser overhandigde mijn implementatiescript het nummer 1.1. aangezien 1.10 isn't een versiereeks naar YAML - it's a Letterlijk drijven, en praalwagens blijven geen nullen achterblijven. Tien wordt één-punt-één. Het bestand was 100% geldig YAML. De Linter was blij. CI was groen. De verkeerde container ging uit.
Dat is het ding dat niemand je vertelt over YAML-validatie: "Valid" is niet hetzelfde als "correct." Een syntaxiscontrole die alleen ja/nee beantwoordt, is het beantwoorden van de makkelijke vraag De moeilijke vraag - degene die daadwerkelijk deploys breekt - is Waar is mijn YAML veranderd in? Omdat YAML geen configuratieformaat is, is het een type-inferentie-engine die een configuratie-kleding draagt, en het neemt beslissingen over uw gegevens die u nooit hebt gevraagd.
de YAML-validator op Toolz.dev beantwoordt beide vragen Het vertelt je of het document parseert, en dan toont het je het geparseerde resultaat als JSON - de werkelijke datastructuur die je tooling zal ontvangen Die tweede helft is wat mij zou hebben gered. "image_tag": 1.1 In het uitvoervenster is het onmogelijk verkeerd te lezen.
tl;dr: Plak je yaml in de YAML-validator en lees de JSON-uitgang, niet alleen het groene vinkje. Dat is waar type dwang zich laat zien:
1.10→1.1,0123→123, niet-geciteerde waarden die stil getallen, booleans of null worden. Het draait volledig op JS-Yaml (Yaml 1.2) in uw browser, dus Kubernetes-geheimen en databasereferenties verlaten uw machine nooit. Citeer alles wat een string moet blijven. Als u het resultaat moet vergelijken met een JSON-configuratie, dan JSON-formatter en JSON-differentiatie vanaf daar ophalen.
Wat controleert een YAML-validator eigenlijk?
Twee verschillende dingen, en het is het waard om ze te scheiden omdat ze anders falen.
Syntaxisvalidatie vraagt: kan deze tekst überhaupt worden geparseerd? Tabs waar spaties thuishoren, een ontbrekende ruimte na een dubbele punt, een blok scalair waarvan het lichaam niet ingesprongen is, een niet-gesloten aanhalingsteken. dit zijn lawaaierig mislukkingen. Je parser gooit, je pijplijn wordt rood, je repareert het in twee minuten. Vervelend, niet gevaarlijk.
Semantische inspectie vraagt: wat heeft het ontleden? per? Hier leven de stille mislukkingen. Het document is geldig. De pijplijn is groen. De waarde is gewoon niet wat je dacht dat je schreef. Niemand komt erachter totdat de productie zich vreemd gedraagt, en tegen die tijd kijkt niemand naar het configuratiebestand, omdat het configuratiebestand "Fijn is."
De meeste online YAML-checkers doen alleen de eerste De Toolz.dev-validator doet de eerste en overhandigt u vervolgens het tweede - het geparseerde document, weergegeven als JSON, direct naast uw invoer Maak er een gewoonte van om dat deelvenster te lezen. It' is het verschil tussen & quot; het bestand is goed gevormd" en & quot; het bestand betekent wat ik bedoelde."
Welke YAML-fouten breken daadwerkelijk builds?
Dit is wat echt opduikt, gerangschikt op hoeveel van mijn leven elk me heeft gekost. Elk gedrag hieronder heb ik geverifieerd tegen JS-Gyl 4, de parser die de Toolz.dev-validator uitvoert en die de yaml 1.2 Spec.
1. Tabbladen. Altijd tabbladen.
YAML verbiedt tabtekens voor inspringen Niet & quot;discourages" - verbiedt De specificatie is expliciet en de foutmelding is verfrissend direct:
tab characters must not be used in indentation
De reden dat dit blijft gebeuren, is dat tabbladen onzichtbaar zijn. Je editor toont je een mooi uitgelijnd bestand; de parser ziet een besturingsteken. Fix het bij de bron: stel uw editor in op invoegen spaties en schakel "Render Whitespace" in voor YAML-bestanden. Twee ruimtes per niveau, wat de conventie is waar elk groot YAML-ecosysteem zich heeft gevestigd.
2. Dubbele sleutels
database:
host: localhost
port: 5432
host: production-db.example.com
host verschijnt twee keer. Wat gebeurt er? Het hangt volledig af van je parser, wat een gruwelijke zin is om over een configuratieformaat te schrijven.
JS-Gyam klankpiepsel duplicated mapping key. Goed. Dat' is het gewenste gedrag, en het' is wat de Toolz.dev-validator je zal laten zien. Maar PyYAML - waar Ansible, en veel Python-tooling, op zit - neemt stilletjes de voldoende zijn waarde en gaat verder. Geen waarschuwing. Uw databasehost is nu wat het laatste duplicaat zei, wat in een lang bestand dat u slecht hebt samengevoegd, driehonderd regels verwijderd kan zijn van waar u op zoek bent.
Dit is het enige beste argument voor het uitvoeren van configuraties via een strikte validator, zelfs wanneer uw productietooling ze accepteert. een validator die is strenger Dan is uw runtime een validator die bugs vindt.
3. Type dwang - degene die mij heeft gebracht
YAML leidt typen af uit niet-geciteerde scalaire bronnen. Het is erg zelfverzekerd en het is vaak verkeerd aan je intentie:
| jij schreef | je bedoelde | yaml 1.2 geeft je |
|---|---|---|
version: 1.10 |
de string "1.10" | de vlotter 1.1 |
pin: 0123 |
de string "0123" | het geheel 123 |
port: "8080" |
het nummer 8080 | het touw "8080" |
enabled: true |
booleaans | booleaans true - correct |
value: |
Lege snaar misschien? | null |
value: ~ |
een tilde | null |
dat 0123 rij is degene die I' d tattoo op mensen Postcodes, PIN's, accountnummers, zero-padded ID's - elke leidende nul die je schreef voor een reden wordt opgegeten Citeer ze.
De regel die me nooit in de steek heeft gelaten: Als de waarde een identifier, een versie, een code of iets anders is waar je nooit op rekent, zet het dan tussen aanhalingstekens. Poorten en replica-tellingen kunnen kaal blijven. alles wat slechts eruit zien Numeriek moet zijn "quoted".
4. De versie-afhankelijke Booleans (ook bekend als het Noorse probleem)
Deze is echt berucht en de details zijn belangrijker dan de meme.
volgens yaml 1.1, het Booleaanse type accepteert yes, no, on, off, y, nen hun kapitalisaties, naast true en false. ook weer country: NO - Noorwegen's ISO-landcode - parseert als Booleaans vals. volgens yaml 1.2, die dit alleen heeft opgeruimd true en false zijn booleeërs; NO is gewoon de touwtje "NO".
wat hetzelfde bestand betekent betekent verschillende dingen in verschillende toolspiepsel
country: NO
feature_flag: on
- JS-Yaml 4 (Yaml 1.2, en wat deze validator gebruikt):
{"country": "NO", "feature_flag": "on"}- snaren. - Pyyaml (YAML 1.1):
{"country": False, "feature_flag": True}- booleanen.
Zelfde bytes. verschillende gegevens. Als uw CI een Python-linter uitvoert via een configuratie die een node-service verbruikt, heeft u twee parsers die het niet eens zijn over uw bestand en geen van beide is verkeerd.
Dit is ook de oorsprong van GitHub Actions' raarste gril: de on: sleutel waarmee elke workflow begint met een booleaans naar een YAML 1.1-parser, dus scripts die lint-workflowbestanden in Python vinden, vinden een sleutel met de naam True in plaats van on. citeren ("on":) is legaal en lost het op.
De defensieve zet is hetzelfde als voorheen: Citeer het. country: "NO" inkomsten "NO" In elke parser die ooit heeft bestaan.
5. Blokkeer scalaire inkeping
description: |
This is not indented
de | (letterlijk) en > (gevouwen) blok-scalaires hebben hun inhoud nodig ten opzichte van de sleutel. Niet-geïnde inhoud beëindigt het blok onmiddellijk en de parser begint je proza te lezen als Yaml-sleutels, wat foutmeldingen produceert die niets met de daadwerkelijke fout te maken lijken te hebben.
De moeite waard om de kauwindicatoren te kennen terwijl je hier bent: | houdt een enkele achterstand aan, |- stript het, |+ houdt ze allemaal. Als je een privésleutel of een script inbedt en iets stroomafwaarts klaagt over een achterblijvende nieuwe regel, dan is dit je knop.
6. niet-geciteerde speciale tekens
Een dubbele punt binnen een niet-geciteerde waarde beëindigt de waarde en start een nieuwe sleutel. Dit bijt in foutmeldingen en URL's:
message: Error: file not found # parse error
regex: [a-z]+ # parsed as a LIST, not a string
time: "22:22" # quote it — in YAML 1.1 this was base-60!
[, {, #, &, *, !, |, >, %, @ Aan het begin van een scalair betekenen allemaal iets. Citeer eerst, stel later vragen.
Hoe valideer ik YAML op Toolz.dev?
- Open de YAML-validator. Geen account, geen upload.
- Plak uw document. Een Helm-waardenbestand, een docker-compose, een workflow - whatever's misdragen.
- Druk op valideren. Fouten komen terug met de exacte Lijn en kolom van de parser, plus de eigen redenreeks van de parser (
bad indentation of a mapping entry,duplicated mapping key, enzovoort). - Lees het JSON-uitvoervenster. Dit is de stap die mensen overslaan en het is degene die ertoe doet. Scan het voor de waarden die u belangrijk vindt. is
image_tagEen tekenreeks of een nummer? Is die poort geciteerd? Is een lege waarde geworden?null? - repareren, opnieuw valideren. Fouten kunnen elkaar maskeren - de parser stopt bij de eerste die het kan & # 39; T herstellen, dus het repareren van een onthult soms nog twee. Dat&# 39; is normaal, geen teken dat de zaken erger worden.
een bekende beperking, duidelijk vermeld
De validator ontleedt momenteel een enkel YAML-document. Als u een bestand met meerdere documenten plakt, worden verschillende Kubernetes-manifesten gescheiden door --- in één bestand, dat een uiterst gebruikelijk patroon is - zal het rapporteren
expected a single document in the stream, but found more
Dat is de 39;de parser die correct is, niet het bestand dat wordt verbroken. De tijdelijke oplossing vandaag is om elk document afzonderlijk te valideren: plak alles boven de ---, controleer het en plak dan de volgende brokken. Ondersteuning voor meerdere documenten staat op mijn lijst, juist omdat gebruikers van Kubernetes dit onmiddellijk raken, en ik zou je liever over de kloof vertellen dan je halverwege het ongeval te laten ontdekken.
yaml versus json: Wanneer moet ik welke gebruiken?
YAML 1.2 is een strikte superset van JSON - elk geldig JSON-document is geldig YAML, daarom kan de validator u überhaupt JSON-uitvoer overhandigen. Maar de formaten hebben tegengestelde persoonlijkheden.
| lijk heb- | Json | |
|---|---|---|
| Structuur gedefinieerd door | Inspringing (witte ruimte-significant) | Bretels en beugels (expliciet) |
| nadere beschouwing | Ja (#) |
heel weinig |
| Type gevolgtrekking | Agressief - leidt getallen af, booleans, nul, datums | Geen - aanhalingstekens betekenen altijd tekenreeks |
| met meerdere documenten | Ja (--- scheidingsteken) |
heel weinig |
| afbreken | ankers (&), aliassen (*), toetsen samenvoegen (<<) |
niet een |
| Falende modus | Stille verkeerde interpretatie | luide parseerfout |
| beste in | Bestanden die mensen schrijven en bewerken | Datamachines wisselen |
De handel is echt en gaat beide kanten op. YAML' De leesbaarheid en opmerkingen zijn precies waarom infrastructuurconfig daar woont - niemand wil een Kubernetes-manifest van 400 regels in JSON onderhouden zonder commentaar. JSON' Het totale gebrek aan slimheid is precies de reden waarom API's het gebruiken: "1.10" is "1.10" En er valt niets te bespreken.
Mijn regel: yaml voor bestanden die mensen bewerken, json voor datamachines passeren. En wanneer een YAML-bestand door een programma wordt gegenereerd in plaats van door een persoon te worden getypt, zal ' is een geur - machine-gegenereerde configuratie die niets van YAML's voordelen en al zijn risico's oplevert.
Als je tussen de twee beweegt, JSON naar YAML-converter verzorgt de transformatie en de JSON-formatter zal de andere kant opruimen.
Wat zijn ankers en aliassen, en moet ik ze gebruiken?
Met Yaml kunt u een blok één keer definiëren en opnieuw gebruiken. zich vermanen &, verwijs met *, samenvoegen tot een kaart met <<piepsel
defaults: &defaults
adapter: postgres
host: localhost
port: 5432
development:
<<: *defaults
database: myapp_dev
test:
<<: *defaults
database: myapp_test
allebei development en test kom naar buiten met de adapter, host en poort samengevoegd in. It's echt handig, en js-yaml verwerkt het - ik heb geverifieerd dat de samenvoeging correct is opgelost.
Toch twee waarschuwingen.
eerst, Samenvoegsleutels zijn een YAML 1.1-extensie, geen deel uitmakend van de YAML 1.2-kern Steun is wijdverbreid maar niet universeel, en - degene die mensen betrapt - GitHub-acties ondersteunen hen niet. Ankers in een werkstroombestand doen niet wat u wilt. Controleer uw consument voordat u hierop leunt.
Ten tweede maken ankers een bestand moeilijker om te lezen voor de volgende persoon, en in Config ben jij meestal om 2 uur 's nachts. Ik gebruik ze voor echt herhaalde blokken en nooit voor slimheid.
Terwijl we aan de gevaarlijke kant van YAML zijn: het formaat ondersteunt aangepaste tags die sommige parsers gebruiken om willekeurige objecten te construeren. yaml.load() was beroemd op deze manier, en daarom yaml.safe_load() bestaat en waarom je het - altijd - zou moeten gebruiken op elke YAML die van buiten je team kwam. js-yaml's load() In V4 is standaard veilig (het zal geen willekeurige typen construeren), wat hier nog een minder ding is om je zorgen over te maken.
Hoe stop ik in de eerste plaats met het schrijven van gebroken yaml?
Preventie verslaat validatie, en het meeste is editorconfiguratie:
- Twee spaties, nooit tabbladen. Stel het per bestandstype in zodat je het niet kunt vergeten.
- Schakel witruimte-weergave in om
.yml/.yaml. Als u het tabblad kunt zien, zult u het tabblad niet vastleggen. - Installeer een YAML-taalserver. Realtime schemavalidatie tegen Kubernetes, GitHub-acties en Docker-compose-schema's vangt een hele klasse van fouten op die syntaxisvalidatie kan: GA WELDER met een verkeerd gespelde sleutel.
- Citaat standaard bij twijfel. De kosten van een onnodige offerte zijn nul. De kosten van een ontbrekende zijn een implementatie.
- valideren voordat u pusht, niet nadat CI faalt. Plakjes in een browsertabblad plakken duurt acht seconden; een mislukte pijplijn duurt acht minuten.
- Voor Kubernetes, leg de cheques. Syntaxisvalidatie vangt structuur;
kubectl apply --dry-run=clientschema vangt. Ze vinden verschillende bugs en jij wilt beide.
En de gewoonte die dingen voor mij eigenlijk veranderde: wanneer een door een config gestuurde implementatie iets onverklaarbaars doet, Kijk naar de geparseerde output voordat je naar iets anders kijkt. niet het bestand. de geparseerde uitvoer. Het bestand is een verhaal over wat je bedoelde. De geparseerde output is wat er werkelijk is gebeurd.
Dat is hetzelfde instinct dat alles in mijn API-foutopsporingswerkstroom - lees de gegevens, niet de code - en het is net zo goed van toepassing op configuraties als op reacties. Als je de bredere rondleiding wilt van wat er nog meer in die gereedschapskist leeft, dan is de Handleiding voor coderingshulpmiddelen dekt het af.
Veelgestelde vragen
Waarom valideert mijn YAML maar toch mijn implementatie?
Omdat syntaxisvaliditeit en semantische correctheid verschillende dingen zijn. Yaml leidt typen af van niet-geciteerde waarden, dus 1.10 wordt de vlotter 1.1, 0123 wordt het gehele getal 123, en een lege waarde wordt null - alles in een perfect geldig document Lees de geparseerde JSON-uitvoer, niet alleen het resultaat van de pass/fail, en citeer elke waarde die een tekenreeks moet blijven.
Waarom verandert YAML mijn versienummer in een ander nummer?
1.10 is een drijfletter die letterlijk voor YAML is, en praalwagens behouden geen achterstand nullen, dus het lost op 1.1. Elke versie, buildnummer of nul-padded identifier moet worden geciteerd: version: "1.10". Dit is een van de duurste YAML-fouten omdat het bestand er goed uitziet en de parse slaagt.
Wat is het Noorse probleem in YAML?
In YAML 1.1 zijn de waarden no, NO, off, en yes zijn Booleans, dus de landcode van Noorwegen NO parsen als false. YAML 1.2 heeft dit alleen opgelost true en false zijn booleans - maar veel tools (met name PyYAML, dat Ansible gebruikt) implementeren nog steeds 1.1. hetzelfde bestand kan dus verschillende dingen betekenen in verschillende tools De waarde citeren (country: "NO") maakt het overal een touwtje.
Kan ik tabbladen gebruiken voor inspringing in yaml?
Nee. De YAML-specificatie verbiedt tabtekens bij inspringen, en parsers weigeren ze met een fout zoals " tabtekens mogen niet worden gebruikt bij inspringen." Configureer uw editor om spaties in te voegen voor YAML-bestanden - twee spaties per niveau is de standaardconventie.
Ondersteunt de Toolz.dev yaml-validator multi-documentbestanden?
Momenteel niet. het valideert een enkel document, dus een bestand met meerdere Kubernetes-manifesten gescheiden door --- Retouren "Verwachte een enkel document in de stream." Valideer elk document afzonderlijk als een tijdelijke oplossing. Ondersteuning voor meerdere documenten is gepland.
Zijn dubbele sleutels toegestaan in YAML?
De specificatie zegt dat mapping sleutels uniek moeten zijn, maar parsers zijn het in de praktijk niet eens. js-yaml - die deze validator gebruikt - gooit een & quot; duplicated mapping key" fout PyYAML houdt stil de laatste waarde, wat betekent dat een duplicaat stilletjes uw configuratie zonder enige waarschuwing kan overschrijven Het uitvoeren van uw configuratie door een strikte validator vangt dit op voordat uw looptijd het stilletjes accepteert.
Is het veilig om Kubernetes-geheimen en referenties online te valideren?
Met de Toolz.dev validator gebeurt het parseren volledig in uw browser via JavaScript en wordt er niets naar een server verzonden U kunt dit zelf bevestigen door uw browser te openen' s Netwerktab terwijl u valideert en waarneemt dat er geen verzoek wordt gedaan Pas diezelfde controle toe op een online tool voordat u de configuratie van de infrastructuur erin plakt.
Wat is het verschil tussen .yml en .yaml?
Niets functioneels - beide extensies worden door elke YAML-parser herkend. De officiële aanbeveling is .yaml; .yml Overleeft uit het tijdperk van extensies met drie tekens en blijft uiterst gebruikelijk (Docker Compose en GitHub-acties zijn beide standaard). Kies er een en blijf consistent binnen een project.
Hoe converteer ik YAML naar JSON?
Plak de YAML in de validator en lees het uitvoervenster - het geeft het geparseerde document weer als JSON, wat de conversie is Omdat YAML 1.2 een superset is van JSON, heeft elk geldig YAML-document een JSON-equivalent, maar type-inferentie wordt eerst toegepast, dus een niet-geciteerde 1.10 komt als 1.1 en 0123 even 123. Citeer die waarden eerst als je ze als strings wilt bewaren.
Hoe valideer ik YAML tegen een schema?
Deze validator controleert de syntaxis en toont het geparseerde resultaat, maar het valideert niet aan de hand van een schema - dat is een afzonderlijke controle die bevestigt dat uw sleutels en waardetypen overeenkomen met wat een tool als Kubernetes of GitHub Actions verwacht Voor schemavalidatie gebruikt u een YAML-taalserver in uw editor, of een schemabewuste CLI zoals kubeconform voor kubernetes of kubectl apply --dry-run=client. Syntaxis en schemavalidatie vangen verschillende bugs, dus voer beide uit.



