GoogleContainerTools/skaffold

Skaffold should validate input file with our JSON schemas

Open

#5,420 opened on Feb 19, 2021

View on GitHub
 (0 comments) (0 reactions) (0 assignees)Go (1,416 forks)batch import
area/schemashelp wantedkind/feature-requestpriority/p2

Repository metrics

Stars
 (12,822 stars)
PR merge metrics
 (Avg merge 3d 6h) (16 merged PRs in 30d)

Description

Expected behavior

skaffold build -f skaffold.yaml should warn on invalid input skaffold.yaml.

Actual behavior

Skaffold does not validate the yamls, and may instead crash (#5363)


package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/qri-io/jsonschema"
	yaml "gopkg.in/yaml.v3"
)

func main() {
	if len(os.Args) != 3 {
		log.Fatalf("use: %s schema skaffold.yaml", os.Args[0])
	}
	ctx := context.Background()

	schemaData, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		log.Fatalf("could not read %q: %v", os.Args[1], err)
	}
	// workaround https://github.com/qri-io/jsonschema/issues/68 that has allowed 2019-09
	// changes to impact draft-07 validation
	schemaData = []byte(strings.ReplaceAll(
	    strings.ReplaceAll(string(schemaData), `"definitions":`, `"$defs":`),
	    `#/definitions/`, `#/$defs/`))

	// must remarshal the skaffold.yaml to JSON
	data, err := ioutil.ReadFile(os.Args[2])
	if err != nil {
	    log.Fatalf("could not read %q: %v", os.Args[2], err)
	    return
	}

	var document map[string]interface{}
	if err := yaml.Unmarshal(data, &document); err != nil {
		log.Fatalf("not valid yaml: %v", err)
	}

	data, err = json.Marshal(document)
	if err != nil {
		log.Fatalf("could not convert to JSON: %v", err)
	}
	fmt.Printf("%q as JSON:\n----\n%s\n----\n", os.Args[2], string(data))

	rs := &jsonschema.Schema{}
	if err := json.Unmarshal(schemaData, rs); err != nil {
		log.Fatal("unmarshal schema: " + err.Error())
	}
	//j, _ := rs.MarshalJSON()
	//fmt.Printf("schema as JSON: %s\n", j)

	errs, err := rs.ValidateBytes(ctx, data)
	if err != nil {
		panic(err)
	}

	if len(errs) > 0 {
		for _, e := range errs {
			fmt.Println(e.Error())
		}
	} else {
		fmt.Println("seems ok")
	}
}

Contributor guide