mirror of
https://github.com/yannh/kubeconform.git
synced 2026-02-11 05:59:22 +00:00
Update Go and Goreleaser to 1.20, update dependencies (#231)
This commit is contained in:
parent
13a78ebad8
commit
2e50b79b16
15 changed files with 217 additions and 69 deletions
|
|
@ -1,4 +1,4 @@
|
|||
FROM alpine:3.14 as certs
|
||||
FROM alpine:3.18.3 as certs
|
||||
RUN apk add ca-certificates
|
||||
|
||||
FROM scratch AS kubeconform
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM alpine:3.14 as certs
|
||||
FROM alpine:3.18.3
|
||||
LABEL org.opencontainers.image.authors="yann@mandragor.org" \
|
||||
org.opencontainers.image.source="https://github.com/yannh/kubeconform/" \
|
||||
org.opencontainers.image.description="A Kubernetes manifests validation tool" \
|
||||
|
|
|
|||
11
Makefile
11
Makefile
|
|
@ -8,6 +8,7 @@ local-test:
|
|||
go test -race ./...
|
||||
|
||||
local-build:
|
||||
git config --global --add safe.directory $$PWD
|
||||
go build -o bin/ ./...
|
||||
|
||||
local-build-static:
|
||||
|
|
@ -15,13 +16,13 @@ local-build-static:
|
|||
|
||||
# These only used for development. Release artifacts and docker images are produced by goreleaser.
|
||||
docker-test:
|
||||
docker run -t -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform golang:1.17 make local-test
|
||||
docker run -t -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform golang:1.20 make local-test
|
||||
|
||||
docker-build:
|
||||
docker run -t -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform golang:1.17 make local-build
|
||||
docker run -t -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform golang:1.20 make local-build
|
||||
|
||||
docker-build-static:
|
||||
docker run -t -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform golang:1.17 make local-build-static
|
||||
docker run -t -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform golang:1.20 make local-build-static
|
||||
|
||||
build-bats:
|
||||
docker build -t bats -f Dockerfile.bats .
|
||||
|
|
@ -31,11 +32,11 @@ docker-acceptance: build-bats
|
|||
docker run --network none -t bats -p acceptance-nonetwork.bats
|
||||
|
||||
goreleaser-build-static:
|
||||
docker run -t -e GOOS=linux -e GOARCH=amd64 -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform goreleaser/goreleaser:v1.11.5 build --single-target --skip-post-hooks --rm-dist --snapshot
|
||||
docker run -t -e GOOS=linux -e GOARCH=amd64 -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform goreleaser/goreleaser:v1.20.0 build --single-target --skip-post-hooks --rm-dist --snapshot
|
||||
cp dist/kubeconform_linux_amd64_v1/kubeconform bin/
|
||||
|
||||
release:
|
||||
docker run -e GITHUB_TOKEN -e GIT_OWNER -t -v /var/run/docker.sock:/var/run/docker.sock -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform goreleaser/goreleaser:v1.11.5 release --rm-dist
|
||||
docker run -e GITHUB_TOKEN -e GIT_OWNER -t -v /var/run/docker.sock:/var/run/docker.sock -v $$PWD:/go/src/github.com/yannh/kubeconform -w /go/src/github.com/yannh/kubeconform goreleaser/goreleaser:v1.20.0 release --rm-dist
|
||||
|
||||
update-deps:
|
||||
go get -u ./...
|
||||
|
|
|
|||
6
go.mod
6
go.mod
|
|
@ -1,10 +1,10 @@
|
|||
module github.com/yannh/kubeconform
|
||||
|
||||
go 1.17
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.1.1
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||
require gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
|
|
|||
9
go.sum
9
go.sum
|
|
@ -1,11 +1,10 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.1.1 h1:lEOLY2vyGIqKWUI9nzsOJRV3mb3WC9dXYORsLEUcoeY=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.1.1/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
|
|
|||
2
vendor/github.com/santhosh-tekuri/jsonschema/v5/.gitignore
generated
vendored
2
vendor/github.com/santhosh-tekuri/jsonschema/v5/.gitignore
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
jv
|
||||
cmd/jv/jv
|
||||
|
|
|
|||
3
vendor/github.com/santhosh-tekuri/jsonschema/v5/.gitmodules
generated
vendored
Normal file
3
vendor/github.com/santhosh-tekuri/jsonschema/v5/.gitmodules
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "testdata/JSON-Schema-Test-Suite"]
|
||||
path = testdata/JSON-Schema-Test-Suite
|
||||
url = https://github.com/json-schema-org/JSON-Schema-Test-Suite.git
|
||||
25
vendor/github.com/santhosh-tekuri/jsonschema/v5/README.md
generated
vendored
25
vendor/github.com/santhosh-tekuri/jsonschema/v5/README.md
generated
vendored
|
|
@ -1,10 +1,10 @@
|
|||
# jsonschema v5.1.1
|
||||
# jsonschema v5.3.1
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://pkg.go.dev/github.com/santhosh-tekuri/jsonschema/v5)
|
||||
[](https://goreportcard.com/report/github.com/santhosh-tekuri/jsonschema/v5)
|
||||
[](https://github.com/santhosh-tekuri/jsonschema/actions/workflows/go.yaml)
|
||||
[](https://codecov.io/github/santhosh-tekuri/jsonschema?branch=master)
|
||||
[](https://codecov.io/gh/santhosh-tekuri/jsonschema)
|
||||
|
||||
Package jsonschema provides json-schema compilation and validation.
|
||||
|
||||
|
|
@ -183,10 +183,10 @@ Prints:
|
|||
|
||||
## CLI
|
||||
|
||||
to install `go install github.com/santhosh-tekuri/jsonschema/v5/cmd/jv@latest`
|
||||
to install `go install github.com/santhosh-tekuri/jsonschema/cmd/jv@latest`
|
||||
|
||||
```bash
|
||||
jv [-draft INT] [-output FORMAT] [-assertformat] [-assertcontent] <json-schema> [<json-doc>]...
|
||||
jv [-draft INT] [-output FORMAT] [-assertformat] [-assertcontent] <json-schema> [<json-or-yaml-doc>]...
|
||||
-assertcontent
|
||||
enable content assertions with draft >= 2019
|
||||
-assertformat
|
||||
|
|
@ -197,19 +197,24 @@ jv [-draft INT] [-output FORMAT] [-assertformat] [-assertcontent] <json-schema>
|
|||
output format. valid values flag, basic, detailed
|
||||
```
|
||||
|
||||
if no `<json-doc>` arguments are passed, it simply validates the `<json-schema>`.
|
||||
if no `<json-or-yaml-doc>` arguments are passed, it simply validates the `<json-schema>`.
|
||||
if `$schema` attribute is missing in schema, it uses latest version. this can be overridden by passing `-draft` flag
|
||||
|
||||
exit-code is 1, if there are any validation errors
|
||||
|
||||
`jv` can also validate yaml files. It also accepts schema from yaml files.
|
||||
|
||||
## Validating YAML Documents
|
||||
|
||||
since yaml supports non-string keys, such yaml documents are rendered as invalid json documents.
|
||||
yaml parser returns `map[interface{}]interface{}` for object, whereas json parser returns `map[string]interface{}`.
|
||||
this package accepts only `map[string]interface{}`, so we need to manually convert them to `map[string]interface{}`
|
||||
|
||||
most yaml parser use `map[interface{}]interface{}` for object,
|
||||
whereas json parser uses `map[string]interface{}`.
|
||||
|
||||
so we need to manually convert them to `map[string]interface{}`.
|
||||
below code shows such conversion by `toStringKeys` function.
|
||||
|
||||
https://play.golang.org/p/Hhax3MrtD8r
|
||||
|
||||
the above example shows how to validate yaml document with jsonschema.
|
||||
the conversion explained above is implemented by `toStringKeys` function
|
||||
|
||||
NOTE: if you are using `gopkg.in/yaml.v3`, then you do not need such conversion. since this library
|
||||
returns `map[string]interface{}` if all keys are strings.
|
||||
55
vendor/github.com/santhosh-tekuri/jsonschema/v5/compiler.go
generated
vendored
55
vendor/github.com/santhosh-tekuri/jsonschema/v5/compiler.go
generated
vendored
|
|
@ -30,9 +30,21 @@ type Compiler struct {
|
|||
// If nil, package global LoadURL is used.
|
||||
LoadURL func(s string) (io.ReadCloser, error)
|
||||
|
||||
// Formats can be registered by adding to this map. Key is format name,
|
||||
// value is function that knows how to validate that format.
|
||||
Formats map[string]func(interface{}) bool
|
||||
|
||||
// AssertFormat for specifications >= draft2019-09.
|
||||
AssertFormat bool
|
||||
|
||||
// Decoders can be registered by adding to this map. Key is encoding name,
|
||||
// value is function that knows how to decode string in that format.
|
||||
Decoders map[string]func(string) ([]byte, error)
|
||||
|
||||
// MediaTypes can be registered by adding to this map. Key is mediaType name,
|
||||
// value is function that knows how to validate that mediaType.
|
||||
MediaTypes map[string]func([]byte) error
|
||||
|
||||
// AssertContent for specifications >= draft2019-09.
|
||||
AssertContent bool
|
||||
}
|
||||
|
|
@ -74,7 +86,14 @@ func MustCompileString(url, schema string) *Schema {
|
|||
// if '$schema' attribute is missing, it is treated as draft7. to change this
|
||||
// behavior change Compiler.Draft value
|
||||
func NewCompiler() *Compiler {
|
||||
return &Compiler{Draft: latest, resources: make(map[string]*resource), extensions: make(map[string]extension)}
|
||||
return &Compiler{
|
||||
Draft: latest,
|
||||
resources: make(map[string]*resource),
|
||||
Formats: make(map[string]func(interface{}) bool),
|
||||
Decoders: make(map[string]func(string) ([]byte, error)),
|
||||
MediaTypes: make(map[string]func([]byte) error),
|
||||
extensions: make(map[string]extension),
|
||||
}
|
||||
}
|
||||
|
||||
// AddResource adds in-memory resource to the compiler.
|
||||
|
|
@ -218,7 +237,7 @@ func (c *Compiler) compileRef(r *resource, stack []schemaRef, refPtr string, res
|
|||
// ensure root resource is always compiled first.
|
||||
// this is required to get schema.meta from root resource
|
||||
if r.schema == nil {
|
||||
r.schema = newSchema(r.url, r.floc, r.doc)
|
||||
r.schema = newSchema(r.url, r.floc, r.draft, r.doc)
|
||||
if _, err := c.compile(r, nil, schemaRef{"#", r.schema, false}, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -239,7 +258,7 @@ func (c *Compiler) compileRef(r *resource, stack []schemaRef, refPtr string, res
|
|||
return sr.schema, nil
|
||||
}
|
||||
|
||||
sr.schema = newSchema(r.url, sr.floc, sr.doc)
|
||||
sr.schema = newSchema(r.url, sr.floc, r.draft, sr.doc)
|
||||
return c.compile(r, stack, schemaRef{refPtr, sr.schema, false}, sr)
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +335,10 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re
|
|||
if r.draft.version >= 2019 {
|
||||
if r == res { // root schema
|
||||
if vocab, ok := m["$vocabulary"]; ok {
|
||||
for url := range vocab.(map[string]interface{}) {
|
||||
for url, reqd := range vocab.(map[string]interface{}) {
|
||||
if reqd, ok := reqd.(bool); ok && !reqd {
|
||||
continue
|
||||
}
|
||||
if !r.draft.isVocab(url) {
|
||||
return fmt.Errorf("jsonschema: unsupported vocab %q in %s", url, res)
|
||||
}
|
||||
|
|
@ -340,6 +362,13 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dref, ok := dref.(string); ok {
|
||||
_, frag := split(dref)
|
||||
if frag != "#" && !strings.HasPrefix(frag, "#/") {
|
||||
// frag is anchor
|
||||
s.dynamicRefAnchor = frag[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -635,7 +664,11 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re
|
|||
if format, ok := m["format"]; ok {
|
||||
s.Format = format.(string)
|
||||
if r.draft.version < 2019 || c.AssertFormat || r.schema.meta.hasVocab("format-assertion") {
|
||||
s.format, _ = Formats[s.Format]
|
||||
if format, ok := c.Formats[s.Format]; ok {
|
||||
s.format = format
|
||||
} else {
|
||||
s.format, _ = Formats[s.Format]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -658,11 +691,19 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re
|
|||
if r.draft.version >= 7 {
|
||||
if encoding, ok := m["contentEncoding"]; ok {
|
||||
s.ContentEncoding = encoding.(string)
|
||||
s.decoder, _ = Decoders[s.ContentEncoding]
|
||||
if decoder, ok := c.Decoders[s.ContentEncoding]; ok {
|
||||
s.decoder = decoder
|
||||
} else {
|
||||
s.decoder, _ = Decoders[s.ContentEncoding]
|
||||
}
|
||||
}
|
||||
if mediaType, ok := m["contentMediaType"]; ok {
|
||||
s.ContentMediaType = mediaType.(string)
|
||||
s.mediaType, _ = MediaTypes[s.ContentMediaType]
|
||||
if mediaType, ok := c.MediaTypes[s.ContentMediaType]; ok {
|
||||
s.mediaType = mediaType
|
||||
} else {
|
||||
s.mediaType, _ = MediaTypes[s.ContentMediaType]
|
||||
}
|
||||
if s.ContentSchema, err = loadSchema("contentSchema", stack); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
22
vendor/github.com/santhosh-tekuri/jsonschema/v5/draft.go
generated
vendored
22
vendor/github.com/santhosh-tekuri/jsonschema/v5/draft.go
generated
vendored
|
|
@ -1,6 +1,7 @@
|
|||
package jsonschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -16,6 +17,26 @@ type Draft struct {
|
|||
subschemas map[string]position
|
||||
}
|
||||
|
||||
func (d *Draft) URL() string {
|
||||
switch d.version {
|
||||
case 2020:
|
||||
return "https://json-schema.org/draft/2020-12/schema"
|
||||
case 2019:
|
||||
return "https://json-schema.org/draft/2019-09/schema"
|
||||
case 7:
|
||||
return "https://json-schema.org/draft-07/schema"
|
||||
case 6:
|
||||
return "https://json-schema.org/draft-06/schema"
|
||||
case 4:
|
||||
return "https://json-schema.org/draft-04/schema"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (d *Draft) String() string {
|
||||
return fmt.Sprintf("Draft%d", d.version)
|
||||
}
|
||||
|
||||
func (d *Draft) loadMeta(url, schema string) {
|
||||
c := NewCompiler()
|
||||
c.AssertFormat = true
|
||||
|
|
@ -264,6 +285,7 @@ func init() {
|
|||
subschemas["dependentSchemas"] = prop
|
||||
subschemas["unevaluatedProperties"] = self
|
||||
subschemas["unevaluatedItems"] = self
|
||||
subschemas["contentSchema"] = self
|
||||
Draft2019.subschemas = clone(subschemas)
|
||||
|
||||
subschemas["prefixItems"] = item
|
||||
|
|
|
|||
130
vendor/github.com/santhosh-tekuri/jsonschema/v5/schema.go
generated
vendored
130
vendor/github.com/santhosh-tekuri/jsonschema/v5/schema.go
generated
vendored
|
|
@ -4,9 +4,11 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/maphash"
|
||||
"math/big"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
|
@ -16,30 +18,32 @@ import (
|
|||
type Schema struct {
|
||||
Location string // absolute location
|
||||
|
||||
Draft *Draft // draft used by schema.
|
||||
meta *Schema
|
||||
vocab []string
|
||||
dynamicAnchors []*Schema
|
||||
|
||||
// type agnostic validations
|
||||
Format string
|
||||
format func(interface{}) bool
|
||||
Always *bool // always pass/fail. used when booleans are used as schemas in draft-07.
|
||||
Ref *Schema
|
||||
RecursiveAnchor bool
|
||||
RecursiveRef *Schema
|
||||
DynamicAnchor string
|
||||
DynamicRef *Schema
|
||||
Types []string // allowed types.
|
||||
Constant []interface{} // first element in slice is constant value. note: slice is used to capture nil constant.
|
||||
Enum []interface{} // allowed values.
|
||||
enumError string // error message for enum fail. captured here to avoid constructing error message every time.
|
||||
Not *Schema
|
||||
AllOf []*Schema
|
||||
AnyOf []*Schema
|
||||
OneOf []*Schema
|
||||
If *Schema
|
||||
Then *Schema // nil, when If is nil.
|
||||
Else *Schema // nil, when If is nil.
|
||||
Format string
|
||||
format func(interface{}) bool
|
||||
Always *bool // always pass/fail. used when booleans are used as schemas in draft-07.
|
||||
Ref *Schema
|
||||
RecursiveAnchor bool
|
||||
RecursiveRef *Schema
|
||||
DynamicAnchor string
|
||||
DynamicRef *Schema
|
||||
dynamicRefAnchor string
|
||||
Types []string // allowed types.
|
||||
Constant []interface{} // first element in slice is constant value. note: slice is used to capture nil constant.
|
||||
Enum []interface{} // allowed values.
|
||||
enumError string // error message for enum fail. captured here to avoid constructing error message every time.
|
||||
Not *Schema
|
||||
AllOf []*Schema
|
||||
AnyOf []*Schema
|
||||
OneOf []*Schema
|
||||
If *Schema
|
||||
Then *Schema // nil, when If is nil.
|
||||
Else *Schema // nil, when If is nil.
|
||||
|
||||
// object validations
|
||||
MinProperties int // -1 if not specified.
|
||||
|
|
@ -104,10 +108,11 @@ func (s *Schema) String() string {
|
|||
return s.Location
|
||||
}
|
||||
|
||||
func newSchema(url, floc string, doc interface{}) *Schema {
|
||||
func newSchema(url, floc string, draft *Draft, doc interface{}) *Schema {
|
||||
// fill with default values
|
||||
s := &Schema{
|
||||
Location: url + floc,
|
||||
Draft: draft,
|
||||
MinProperties: -1,
|
||||
MaxProperties: -1,
|
||||
MinItems: -1,
|
||||
|
|
@ -418,12 +423,39 @@ func (s *Schema) validate(scope []schemaRef, vscope int, spath string, v interfa
|
|||
errors = append(errors, validationError("maxItems", "maximum %d items required, but found %d items", s.MaxItems, len(v)))
|
||||
}
|
||||
if s.UniqueItems {
|
||||
for i := 1; i < len(v); i++ {
|
||||
for j := 0; j < i; j++ {
|
||||
if equals(v[i], v[j]) {
|
||||
errors = append(errors, validationError("uniqueItems", "items at index %d and %d are equal", j, i))
|
||||
if len(v) <= 20 {
|
||||
outer1:
|
||||
for i := 1; i < len(v); i++ {
|
||||
for j := 0; j < i; j++ {
|
||||
if equals(v[i], v[j]) {
|
||||
errors = append(errors, validationError("uniqueItems", "items at index %d and %d are equal", j, i))
|
||||
break outer1
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m := make(map[uint64][]int)
|
||||
var h maphash.Hash
|
||||
outer2:
|
||||
for i, item := range v {
|
||||
h.Reset()
|
||||
hash(item, &h)
|
||||
k := h.Sum64()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
arr, ok := m[k]
|
||||
if ok {
|
||||
for _, j := range arr {
|
||||
if equals(v[j], item) {
|
||||
errors = append(errors, validationError("uniqueItems", "items at index %d and %d are equal", j, i))
|
||||
break outer2
|
||||
}
|
||||
}
|
||||
}
|
||||
arr = append(arr, i)
|
||||
m[k] = arr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -614,7 +646,7 @@ func (s *Schema) validate(scope []schemaRef, vscope int, spath string, v interfa
|
|||
}
|
||||
if s.DynamicRef != nil {
|
||||
sch := s.DynamicRef
|
||||
if sch.DynamicAnchor != "" {
|
||||
if s.dynamicRefAnchor != "" && sch.DynamicAnchor == s.dynamicRefAnchor {
|
||||
// dynamicRef based on scope
|
||||
for i := len(scope) - 1; i >= 0; i-- {
|
||||
sr := scope[i]
|
||||
|
|
@ -708,13 +740,13 @@ func (s *Schema) validate(scope []schemaRef, vscope int, spath string, v interfa
|
|||
}
|
||||
}
|
||||
|
||||
// UnevaluatedProperties + UnevaluatedItems
|
||||
// unevaluatedProperties + unevaluatedItems
|
||||
switch v := v.(type) {
|
||||
case map[string]interface{}:
|
||||
if s.UnevaluatedProperties != nil {
|
||||
for pname := range result.unevalProps {
|
||||
if pvalue, ok := v[pname]; ok {
|
||||
if err := validate(s.UnevaluatedProperties, "UnevaluatedProperties", pvalue, escape(pname)); err != nil {
|
||||
if err := validate(s.UnevaluatedProperties, "unevaluatedProperties", pvalue, escape(pname)); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
|
@ -724,7 +756,7 @@ func (s *Schema) validate(scope []schemaRef, vscope int, spath string, v interfa
|
|||
case []interface{}:
|
||||
if s.UnevaluatedItems != nil {
|
||||
for i := range result.unevalItems {
|
||||
if err := validate(s.UnevaluatedItems, "UnevaluatedItems", v[i], strconv.Itoa(i)); err != nil {
|
||||
if err := validate(s.UnevaluatedItems, "unevaluatedItems", v[i], strconv.Itoa(i)); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
|
@ -818,6 +850,48 @@ func equals(v1, v2 interface{}) bool {
|
|||
}
|
||||
}
|
||||
|
||||
func hash(v interface{}, h *maphash.Hash) {
|
||||
switch v := v.(type) {
|
||||
case nil:
|
||||
h.WriteByte(0)
|
||||
case bool:
|
||||
h.WriteByte(1)
|
||||
if v {
|
||||
h.WriteByte(1)
|
||||
} else {
|
||||
h.WriteByte(0)
|
||||
}
|
||||
case json.Number, float32, float64, int, int8, int32, int64, uint, uint8, uint32, uint64:
|
||||
h.WriteByte(2)
|
||||
num, _ := new(big.Rat).SetString(fmt.Sprint(v))
|
||||
h.Write(num.Num().Bytes())
|
||||
h.Write(num.Denom().Bytes())
|
||||
case string:
|
||||
h.WriteByte(3)
|
||||
h.WriteString(v)
|
||||
case []interface{}:
|
||||
h.WriteByte(4)
|
||||
for _, item := range v {
|
||||
hash(item, h)
|
||||
}
|
||||
case map[string]interface{}:
|
||||
h.WriteByte(5)
|
||||
props := make([]string, 0, len(v))
|
||||
for prop := range v {
|
||||
props = append(props, prop)
|
||||
}
|
||||
sort.Slice(props, func(i, j int) bool {
|
||||
return props[i] < props[j]
|
||||
})
|
||||
for _, prop := range props {
|
||||
hash(prop, h)
|
||||
hash(v[prop], h)
|
||||
}
|
||||
default:
|
||||
panic(InvalidJSONTypeError(fmt.Sprintf("%T", v)))
|
||||
}
|
||||
}
|
||||
|
||||
// escape converts given token to valid json-pointer token
|
||||
func escape(token string) string {
|
||||
token = strings.ReplaceAll(token, "~", "~0")
|
||||
|
|
|
|||
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
|
|
@ -1,10 +1,10 @@
|
|||
# github.com/santhosh-tekuri/jsonschema/v5 v5.1.1
|
||||
## explicit; go 1.15
|
||||
# github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||
## explicit; go 1.19
|
||||
github.com/santhosh-tekuri/jsonschema/v5
|
||||
github.com/santhosh-tekuri/jsonschema/v5/httploader
|
||||
# gopkg.in/yaml.v2 v2.4.0
|
||||
## explicit; go 1.15
|
||||
gopkg.in/yaml.v2
|
||||
# sigs.k8s.io/yaml v1.2.0
|
||||
# sigs.k8s.io/yaml v1.3.0
|
||||
## explicit; go 1.12
|
||||
sigs.k8s.io/yaml
|
||||
|
|
|
|||
4
vendor/sigs.k8s.io/yaml/.gitignore
generated
vendored
4
vendor/sigs.k8s.io/yaml/.gitignore
generated
vendored
|
|
@ -6,6 +6,10 @@
|
|||
.project
|
||||
.settings/**
|
||||
|
||||
# Idea files
|
||||
.idea/**
|
||||
.idea/
|
||||
|
||||
# Emacs save files
|
||||
*~
|
||||
|
||||
|
|
|
|||
7
vendor/sigs.k8s.io/yaml/.travis.yml
generated
vendored
7
vendor/sigs.k8s.io/yaml/.travis.yml
generated
vendored
|
|
@ -1,8 +1,7 @@
|
|||
language: go
|
||||
dist: xenial
|
||||
go:
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
arch: arm64
|
||||
dist: focal
|
||||
go: 1.15.x
|
||||
script:
|
||||
- diff -u <(echo -n) <(gofmt -d *.go)
|
||||
- diff -u <(echo -n) <(golint $(go list -e ./...) | grep -v YAMLToJSON)
|
||||
|
|
|
|||
2
vendor/sigs.k8s.io/yaml/README.md
generated
vendored
2
vendor/sigs.k8s.io/yaml/README.md
generated
vendored
|
|
@ -107,8 +107,8 @@ func main() {
|
|||
}
|
||||
fmt.Println(string(y))
|
||||
/* Output:
|
||||
name: John
|
||||
age: 30
|
||||
name: John
|
||||
*/
|
||||
j2, err := yaml.YAMLToJSON(y)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue