coreos / butane

Butane translates human-readable Butane Configs into machine-readable Ignition Configs.
https://coreos.github.io/butane/
Apache License 2.0
249 stars 70 forks source link

Generate JSON Schema for External Validation #363

Open oxr463 opened 2 years ago

oxr463 commented 2 years ago

I would like to take this file https://github.com/coreos/butane/blob/main/config/flatcar/v1_1_exp/schema.go and generate a JSON schema for validating generated Ignition configs,

jbirch-atlassian commented 2 years ago

I'd like to throw my vote behind this feature also, but for slightly different outcomes.

A machine-readable schema of all specifications in https://coreos.github.io/butane/specs/ will allow me to use my IDE to tell me what I can and can't write, as well as what I must write, instead of me as a human continually referencing the documentation with my fallible eyes and fallible brain. The existing documentation is fantastic for purpose and semantic intent, but machine-readable documentation would be fantastic for speeding up my development — That is, preventing me entirely from writing something invalid, rather than finding out at ignition generation time.

For other readers, in the interim I am generating the schema I need myself, using github.com/invopop/jsonschema. You may find the following snippet helpful if you choose to go down this path also:

package main

import (
    "encoding/json"
    "fmt"
    "os"

    "github.com/coreos/butane/config/fcos/v1_4"
    "github.com/invopop/jsonschema"
)

func main() {
    s := jsonschema.Reflect(v1_4.Config{})
    data, err := json.MarshalIndent(s, "", "  ")
    if err != nil {
        panic(err.Error())
    }

    file, err := os.OpenFile("fcos.v1_4.schema.json", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
    if err != nil {
        panic(err.Error())
    }
    defer file.Close()

    _, err = fmt.Fprintf(file, string(data))
    if err != nil {
        panic(err.Error())
    }
}

Note that this isn't quite the same, as default struct values in Golang are doing a lot of heavy lifting. For example, using jsonschema will generate a document that vaguely suggests that something like KernelArguments is required because it's a KernelArguments not *KernelArguments in the Config struct. If you add this into any schema validation you have in your local development environment, you'll still get stuff yelling at you.

SRv6d commented 1 week ago

Could schema generation be added to internal/doc/main.go so this can be automated? On first glance it doesn't look to be too much work when using invopop/jsonschema as @jbirch-atlassian suggested.