ceph-csi/e2e/vendor/github.com/google/gnostic-models/jsonschema/operations.go
Niels de Vos f87d06ed85 build: move e2e dependencies into e2e/go.mod
Several packages are only used while running the e2e suite. These
packages are less important to update, as the they can not influence the
final executable that is part of the Ceph-CSI container-image.

By moving these dependencies out of the main Ceph-CSI go.mod, it is
easier to identify if a reported CVE affects Ceph-CSI, or only the
testing (like most of the Kubernetes CVEs).

Signed-off-by: Niels de Vos <ndevos@ibm.com>
2025-03-04 17:43:49 +01:00

395 lines
11 KiB
Go

// Copyright 2017 Google LLC. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package jsonschema
import (
"fmt"
"log"
"strings"
)
//
// OPERATIONS
// The following methods perform operations on Schemas.
//
// IsEmpty returns true if no members of the Schema are specified.
func (schema *Schema) IsEmpty() bool {
return (schema.Schema == nil) &&
(schema.ID == nil) &&
(schema.MultipleOf == nil) &&
(schema.Maximum == nil) &&
(schema.ExclusiveMaximum == nil) &&
(schema.Minimum == nil) &&
(schema.ExclusiveMinimum == nil) &&
(schema.MaxLength == nil) &&
(schema.MinLength == nil) &&
(schema.Pattern == nil) &&
(schema.AdditionalItems == nil) &&
(schema.Items == nil) &&
(schema.MaxItems == nil) &&
(schema.MinItems == nil) &&
(schema.UniqueItems == nil) &&
(schema.MaxProperties == nil) &&
(schema.MinProperties == nil) &&
(schema.Required == nil) &&
(schema.AdditionalProperties == nil) &&
(schema.Properties == nil) &&
(schema.PatternProperties == nil) &&
(schema.Dependencies == nil) &&
(schema.Enumeration == nil) &&
(schema.Type == nil) &&
(schema.AllOf == nil) &&
(schema.AnyOf == nil) &&
(schema.OneOf == nil) &&
(schema.Not == nil) &&
(schema.Definitions == nil) &&
(schema.Title == nil) &&
(schema.Description == nil) &&
(schema.Default == nil) &&
(schema.Format == nil) &&
(schema.Ref == nil)
}
// IsEqual returns true if two schemas are equal.
func (schema *Schema) IsEqual(schema2 *Schema) bool {
return schema.String() == schema2.String()
}
// SchemaOperation represents a function that can be applied to a Schema.
type SchemaOperation func(schema *Schema, context string)
// Applies a specified function to a Schema and all of the Schemas that it contains.
func (schema *Schema) applyToSchemas(operation SchemaOperation, context string) {
if schema.AdditionalItems != nil {
s := schema.AdditionalItems.Schema
if s != nil {
s.applyToSchemas(operation, "AdditionalItems")
}
}
if schema.Items != nil {
if schema.Items.SchemaArray != nil {
for _, s := range *(schema.Items.SchemaArray) {
s.applyToSchemas(operation, "Items.SchemaArray")
}
} else if schema.Items.Schema != nil {
schema.Items.Schema.applyToSchemas(operation, "Items.Schema")
}
}
if schema.AdditionalProperties != nil {
s := schema.AdditionalProperties.Schema
if s != nil {
s.applyToSchemas(operation, "AdditionalProperties")
}
}
if schema.Properties != nil {
for _, pair := range *(schema.Properties) {
s := pair.Value
s.applyToSchemas(operation, "Properties")
}
}
if schema.PatternProperties != nil {
for _, pair := range *(schema.PatternProperties) {
s := pair.Value
s.applyToSchemas(operation, "PatternProperties")
}
}
if schema.Dependencies != nil {
for _, pair := range *(schema.Dependencies) {
schemaOrStringArray := pair.Value
s := schemaOrStringArray.Schema
if s != nil {
s.applyToSchemas(operation, "Dependencies")
}
}
}
if schema.AllOf != nil {
for _, s := range *(schema.AllOf) {
s.applyToSchemas(operation, "AllOf")
}
}
if schema.AnyOf != nil {
for _, s := range *(schema.AnyOf) {
s.applyToSchemas(operation, "AnyOf")
}
}
if schema.OneOf != nil {
for _, s := range *(schema.OneOf) {
s.applyToSchemas(operation, "OneOf")
}
}
if schema.Not != nil {
schema.Not.applyToSchemas(operation, "Not")
}
if schema.Definitions != nil {
for _, pair := range *(schema.Definitions) {
s := pair.Value
s.applyToSchemas(operation, "Definitions")
}
}
operation(schema, context)
}
// CopyProperties copies all non-nil properties from the source Schema to the schema Schema.
func (schema *Schema) CopyProperties(source *Schema) {
if source.Schema != nil {
schema.Schema = source.Schema
}
if source.ID != nil {
schema.ID = source.ID
}
if source.MultipleOf != nil {
schema.MultipleOf = source.MultipleOf
}
if source.Maximum != nil {
schema.Maximum = source.Maximum
}
if source.ExclusiveMaximum != nil {
schema.ExclusiveMaximum = source.ExclusiveMaximum
}
if source.Minimum != nil {
schema.Minimum = source.Minimum
}
if source.ExclusiveMinimum != nil {
schema.ExclusiveMinimum = source.ExclusiveMinimum
}
if source.MaxLength != nil {
schema.MaxLength = source.MaxLength
}
if source.MinLength != nil {
schema.MinLength = source.MinLength
}
if source.Pattern != nil {
schema.Pattern = source.Pattern
}
if source.AdditionalItems != nil {
schema.AdditionalItems = source.AdditionalItems
}
if source.Items != nil {
schema.Items = source.Items
}
if source.MaxItems != nil {
schema.MaxItems = source.MaxItems
}
if source.MinItems != nil {
schema.MinItems = source.MinItems
}
if source.UniqueItems != nil {
schema.UniqueItems = source.UniqueItems
}
if source.MaxProperties != nil {
schema.MaxProperties = source.MaxProperties
}
if source.MinProperties != nil {
schema.MinProperties = source.MinProperties
}
if source.Required != nil {
schema.Required = source.Required
}
if source.AdditionalProperties != nil {
schema.AdditionalProperties = source.AdditionalProperties
}
if source.Properties != nil {
schema.Properties = source.Properties
}
if source.PatternProperties != nil {
schema.PatternProperties = source.PatternProperties
}
if source.Dependencies != nil {
schema.Dependencies = source.Dependencies
}
if source.Enumeration != nil {
schema.Enumeration = source.Enumeration
}
if source.Type != nil {
schema.Type = source.Type
}
if source.AllOf != nil {
schema.AllOf = source.AllOf
}
if source.AnyOf != nil {
schema.AnyOf = source.AnyOf
}
if source.OneOf != nil {
schema.OneOf = source.OneOf
}
if source.Not != nil {
schema.Not = source.Not
}
if source.Definitions != nil {
schema.Definitions = source.Definitions
}
if source.Title != nil {
schema.Title = source.Title
}
if source.Description != nil {
schema.Description = source.Description
}
if source.Default != nil {
schema.Default = source.Default
}
if source.Format != nil {
schema.Format = source.Format
}
if source.Ref != nil {
schema.Ref = source.Ref
}
}
// TypeIs returns true if the Type of a Schema includes the specified type
func (schema *Schema) TypeIs(typeName string) bool {
if schema.Type != nil {
// the schema Type is either a string or an array of strings
if schema.Type.String != nil {
return (*(schema.Type.String) == typeName)
} else if schema.Type.StringArray != nil {
for _, n := range *(schema.Type.StringArray) {
if n == typeName {
return true
}
}
}
}
return false
}
// ResolveRefs resolves "$ref" elements in a Schema and its children.
// But if a reference refers to an object type, is inside a oneOf, or contains a oneOf,
// the reference is kept and we expect downstream tools to separately model these
// referenced schemas.
func (schema *Schema) ResolveRefs() {
rootSchema := schema
count := 1
for count > 0 {
count = 0
schema.applyToSchemas(
func(schema *Schema, context string) {
if schema.Ref != nil {
resolvedRef, err := rootSchema.resolveJSONPointer(*(schema.Ref))
if err != nil {
log.Printf("%+v", err)
} else if resolvedRef.TypeIs("object") {
// don't substitute for objects, we'll model the referenced schema with a class
} else if context == "OneOf" {
// don't substitute for references inside oneOf declarations
} else if resolvedRef.OneOf != nil {
// don't substitute for references that contain oneOf declarations
} else if resolvedRef.AdditionalProperties != nil {
// don't substitute for references that look like objects
} else {
schema.Ref = nil
schema.CopyProperties(resolvedRef)
count++
}
}
}, "")
}
}
// resolveJSONPointer resolves JSON pointers.
// This current implementation is very crude and custom for OpenAPI 2.0 schemas.
// It panics for any pointer that it is unable to resolve.
func (schema *Schema) resolveJSONPointer(ref string) (result *Schema, err error) {
parts := strings.Split(ref, "#")
if len(parts) == 2 {
documentName := parts[0] + "#"
if documentName == "#" && schema.ID != nil {
documentName = *(schema.ID)
}
path := parts[1]
document := schemas[documentName]
pathParts := strings.Split(path, "/")
// we currently do a very limited (hard-coded) resolution of certain paths and log errors for missed cases
if len(pathParts) == 1 {
return document, nil
} else if len(pathParts) == 3 {
switch pathParts[1] {
case "definitions":
dictionary := document.Definitions
for _, pair := range *dictionary {
if pair.Name == pathParts[2] {
result = pair.Value
}
}
case "properties":
dictionary := document.Properties
for _, pair := range *dictionary {
if pair.Name == pathParts[2] {
result = pair.Value
}
}
default:
break
}
}
}
if result == nil {
return nil, fmt.Errorf("unresolved pointer: %+v", ref)
}
return result, nil
}
// ResolveAllOfs replaces "allOf" elements by merging their properties into the parent Schema.
func (schema *Schema) ResolveAllOfs() {
schema.applyToSchemas(
func(schema *Schema, context string) {
if schema.AllOf != nil {
for _, allOf := range *(schema.AllOf) {
schema.CopyProperties(allOf)
}
schema.AllOf = nil
}
}, "resolveAllOfs")
}
// ResolveAnyOfs replaces all "anyOf" elements with "oneOf".
func (schema *Schema) ResolveAnyOfs() {
schema.applyToSchemas(
func(schema *Schema, context string) {
if schema.AnyOf != nil {
schema.OneOf = schema.AnyOf
schema.AnyOf = nil
}
}, "resolveAnyOfs")
}
// return a pointer to a copy of a passed-in string
func stringptr(input string) (output *string) {
return &input
}
// CopyOfficialSchemaProperty copies a named property from the official JSON Schema definition
func (schema *Schema) CopyOfficialSchemaProperty(name string) {
*schema.Properties = append(*schema.Properties,
NewNamedSchema(name,
&Schema{Ref: stringptr("http://json-schema.org/draft-04/schema#/properties/" + name)}))
}
// CopyOfficialSchemaProperties copies named properties from the official JSON Schema definition
func (schema *Schema) CopyOfficialSchemaProperties(names []string) {
for _, name := range names {
schema.CopyOfficialSchemaProperty(name)
}
}