Fix dependencies

This commit is contained in:
TwinProduction
2020-12-25 03:00:08 -05:00
parent 10ab9265d9
commit 416178fb28
1449 changed files with 7770 additions and 474390 deletions
go.modgo.sum
vendor
github.com
go-logr
googleapis
modern-go
prometheus
spf13
golang.org
x
crypto
net
AUTHORSCONTRIBUTORSLICENSEPATENTS
bpf
context
http
http2
icmp
idna
internal
iana
socket
cmsghdr.gocmsghdr_bsd.gocmsghdr_linux_32bit.gocmsghdr_linux_64bit.gocmsghdr_solaris_64bit.gocmsghdr_stub.gocmsghdr_unix.gocmsghdr_zos_s390x.goempty.serror_unix.goerror_windows.goiovec_32bit.goiovec_64bit.goiovec_solaris_64bit.goiovec_stub.gommsghdr_stub.gommsghdr_unix.gomsghdr_bsd.gomsghdr_bsdvar.gomsghdr_linux.gomsghdr_linux_32bit.gomsghdr_linux_64bit.gomsghdr_openbsd.gomsghdr_solaris_64bit.gomsghdr_stub.gomsghdr_zos_s390x.gonorace.gorace.gorawconn.gorawconn_mmsg.gorawconn_msg.gorawconn_nommsg.gorawconn_nomsg.gosocket.gosys.gosys_bsd.gosys_const_unix.gosys_const_zos.gosys_linkname.gosys_linux.gosys_linux_386.gosys_linux_386.ssys_linux_amd64.gosys_linux_arm.gosys_linux_arm64.gosys_linux_mips.gosys_linux_mips64.gosys_linux_mips64le.gosys_linux_mipsle.gosys_linux_ppc64.gosys_linux_ppc64le.gosys_linux_riscv64.gosys_linux_s390x.gosys_linux_s390x.ssys_netbsd.gosys_posix.gosys_solaris.gosys_solaris_amd64.ssys_stub.gosys_unix.gosys_windows.gosys_zos_s390x.gosys_zos_s390x.szsys_aix_ppc64.gozsys_darwin_386.gozsys_darwin_amd64.gozsys_darwin_arm.gozsys_darwin_arm64.gozsys_dragonfly_amd64.gozsys_freebsd_386.gozsys_freebsd_amd64.gozsys_freebsd_arm.gozsys_freebsd_arm64.gozsys_linux_386.gozsys_linux_amd64.gozsys_linux_arm.gozsys_linux_arm64.gozsys_linux_mips.gozsys_linux_mips64.gozsys_linux_mips64le.gozsys_linux_mipsle.gozsys_linux_ppc64.gozsys_linux_ppc64le.gozsys_linux_riscv64.gozsys_linux_s390x.gozsys_netbsd_386.gozsys_netbsd_amd64.gozsys_netbsd_arm.gozsys_netbsd_arm64.gozsys_openbsd_386.gozsys_openbsd_amd64.gozsys_openbsd_arm.gozsys_openbsd_arm64.gozsys_openbsd_mips64.gozsys_solaris_amd64.gozsys_zos_s390x.go
ipv4
ipv6
oauth2
sys
AUTHORSCONTRIBUTORSLICENSEPATENTS
internal
unsafeheader
plan9
unix
.gitignoreREADME.mdaffinity_linux.goaliases.goasm_aix_ppc64.sasm_darwin_386.sasm_darwin_amd64.sasm_darwin_arm.sasm_darwin_arm64.sasm_dragonfly_amd64.sasm_freebsd_386.sasm_freebsd_amd64.sasm_freebsd_arm.sasm_freebsd_arm64.sasm_linux_386.sasm_linux_amd64.sasm_linux_arm.sasm_linux_arm64.sasm_linux_mips64x.sasm_linux_mipsx.sasm_linux_ppc64x.sasm_linux_riscv64.sasm_linux_s390x.sasm_netbsd_386.sasm_netbsd_amd64.sasm_netbsd_arm.sasm_netbsd_arm64.sasm_openbsd_386.sasm_openbsd_amd64.sasm_openbsd_arm.sasm_openbsd_arm64.sasm_openbsd_mips64.sasm_solaris_amd64.sbluetooth_linux.gocap_freebsd.goconstants.godev_aix_ppc.godev_aix_ppc64.godev_darwin.godev_dragonfly.godev_freebsd.godev_linux.godev_netbsd.godev_openbsd.godirent.goendian_big.goendian_little.goenv_unix.goerrors_freebsd_386.goerrors_freebsd_amd64.goerrors_freebsd_arm.goerrors_freebsd_arm64.gofcntl.gofcntl_darwin.gofcntl_linux_32bit.gofdset.gogccgo.gogccgo_c.cgccgo_linux_amd64.goioctl.gomkall.shmkerrors.shpagesize_unix.gopledge_openbsd.goptrace_darwin.goptrace_ios.gorace.gorace0.goreaddirent_getdents.goreaddirent_getdirentries.gosockcmsg_dragonfly.gosockcmsg_linux.gosockcmsg_unix.gosockcmsg_unix_other.gostr.gosyscall.gosyscall_aix.gosyscall_aix_ppc.gosyscall_aix_ppc64.gosyscall_bsd.gosyscall_darwin.1_12.gosyscall_darwin.1_13.gosyscall_darwin.gosyscall_darwin_386.gosyscall_darwin_amd64.gosyscall_darwin_arm.gosyscall_darwin_arm64.gosyscall_darwin_libSystem.gosyscall_dragonfly.gosyscall_dragonfly_amd64.gosyscall_freebsd.gosyscall_freebsd_386.gosyscall_freebsd_amd64.gosyscall_freebsd_arm.gosyscall_freebsd_arm64.gosyscall_illumos.gosyscall_linux.gosyscall_linux_386.gosyscall_linux_amd64.gosyscall_linux_amd64_gc.gosyscall_linux_arm.gosyscall_linux_arm64.gosyscall_linux_gc.gosyscall_linux_gc_386.gosyscall_linux_gc_arm.gosyscall_linux_gccgo_386.gosyscall_linux_gccgo_arm.gosyscall_linux_mips64x.gosyscall_linux_mipsx.gosyscall_linux_ppc64x.gosyscall_linux_riscv64.gosyscall_linux_s390x.gosyscall_linux_sparc64.gosyscall_netbsd.gosyscall_netbsd_386.gosyscall_netbsd_amd64.gosyscall_netbsd_arm.gosyscall_netbsd_arm64.gosyscall_openbsd.gosyscall_openbsd_386.gosyscall_openbsd_amd64.gosyscall_openbsd_arm.gosyscall_openbsd_arm64.gosyscall_openbsd_mips64.gosyscall_solaris.gosyscall_solaris_amd64.gosyscall_unix.gosyscall_unix_gc.gosyscall_unix_gc_ppc64x.gotimestruct.gounveil_openbsd.goxattr_bsd.gozerrors_aix_ppc.gozerrors_aix_ppc64.gozerrors_darwin_386.gozerrors_darwin_amd64.gozerrors_darwin_arm.gozerrors_darwin_arm64.gozerrors_dragonfly_amd64.gozerrors_freebsd_386.gozerrors_freebsd_amd64.gozerrors_freebsd_arm.gozerrors_freebsd_arm64.gozerrors_netbsd_arm.gozerrors_netbsd_arm64.gozerrors_openbsd_386.gozerrors_openbsd_amd64.gozerrors_openbsd_arm.gozerrors_openbsd_arm64.gozerrors_openbsd_mips64.gozerrors_solaris_amd64.gozptrace_armnn_linux.gozptrace_linux_arm64.gozptrace_mipsnn_linux.gozptrace_mipsnnle_linux.gozptrace_x86_linux.gozsyscall_aix_ppc.gozsyscall_aix_ppc64.gozsyscall_aix_ppc64_gc.gozsyscall_aix_ppc64_gccgo.gozsyscall_darwin_386.1_13.gozsyscall_darwin_386.1_13.szsyscall_darwin_386.gozsyscall_darwin_386.szsyscall_darwin_amd64.1_13.gozsyscall_darwin_amd64.1_13.szsyscall_darwin_amd64.gozsyscall_darwin_amd64.szsyscall_darwin_arm.1_13.gozsyscall_darwin_arm.1_13.szsyscall_darwin_arm.gozsyscall_darwin_arm.szsyscall_darwin_arm64.1_13.gozsyscall_darwin_arm64.1_13.szsyscall_darwin_arm64.gozsyscall_darwin_arm64.szsyscall_dragonfly_amd64.gozsyscall_freebsd_386.gozsyscall_freebsd_amd64.gozsyscall_freebsd_arm.gozsyscall_freebsd_arm64.gozsyscall_illumos_amd64.gozsyscall_linux.gozsyscall_linux_386.gozsyscall_linux_amd64.gozsyscall_linux_arm.gozsyscall_linux_arm64.gozsyscall_linux_mips.gozsyscall_linux_mips64.gozsyscall_linux_mips64le.gozsyscall_linux_mipsle.gozsyscall_linux_ppc64.gozsyscall_linux_ppc64le.gozsyscall_linux_riscv64.gozsyscall_linux_s390x.gozsyscall_linux_sparc64.gozsyscall_netbsd_386.gozsyscall_netbsd_amd64.gozsyscall_netbsd_arm.gozsyscall_netbsd_arm64.gozsyscall_openbsd_386.gozsyscall_openbsd_amd64.gozsyscall_openbsd_arm.gozsyscall_openbsd_arm64.gozsyscall_openbsd_mips64.gozsyscall_solaris_amd64.gozsysctl_openbsd_386.gozsysctl_openbsd_amd64.gozsysctl_openbsd_arm.gozsysctl_openbsd_arm64.gozsysctl_openbsd_mips64.gozsysnum_darwin_386.gozsysnum_darwin_amd64.gozsysnum_darwin_arm.gozsysnum_darwin_arm64.gozsysnum_dragonfly_amd64.gozsysnum_freebsd_386.gozsysnum_freebsd_amd64.gozsysnum_freebsd_arm.gozsysnum_freebsd_arm64.gozsysnum_linux_386.gozsysnum_linux_amd64.gozsysnum_linux_arm.gozsysnum_linux_arm64.gozsysnum_linux_mips.gozsysnum_linux_mips64.gozsysnum_linux_mips64le.gozsysnum_linux_mipsle.gozsysnum_linux_ppc64.gozsysnum_linux_ppc64le.gozsysnum_linux_riscv64.gozsysnum_linux_s390x.gozsysnum_linux_sparc64.gozsysnum_netbsd_386.gozsysnum_netbsd_amd64.gozsysnum_netbsd_arm.gozsysnum_netbsd_arm64.gozsysnum_openbsd_386.gozsysnum_openbsd_amd64.gozsysnum_openbsd_arm.gozsysnum_openbsd_arm64.gozsysnum_openbsd_mips64.goztypes_aix_ppc.goztypes_aix_ppc64.goztypes_darwin_386.goztypes_darwin_amd64.goztypes_darwin_arm.goztypes_darwin_arm64.goztypes_dragonfly_amd64.goztypes_freebsd_386.goztypes_freebsd_amd64.goztypes_freebsd_arm.goztypes_freebsd_arm64.goztypes_linux.goztypes_linux_386.goztypes_linux_amd64.goztypes_linux_arm.goztypes_linux_arm64.goztypes_linux_mips.goztypes_linux_mips64.goztypes_linux_mips64le.goztypes_linux_mipsle.goztypes_linux_ppc64.goztypes_linux_ppc64le.goztypes_linux_riscv64.goztypes_linux_s390x.goztypes_linux_sparc64.goztypes_netbsd_386.goztypes_netbsd_amd64.goztypes_netbsd_arm.goztypes_netbsd_arm64.goztypes_openbsd_386.goztypes_openbsd_amd64.goztypes_openbsd_arm.goztypes_openbsd_arm64.goztypes_openbsd_mips64.goztypes_solaris_amd64.go
windows
term
text
time
google.golang.org
appengine
protobuf
AUTHORSCONTRIBUTORSLICENSEPATENTS
encoding
internal
proto
reflect
runtime
types
known
anypb
durationpb
timestamppb
gopkg.in
k8s.io
api
LICENSE
admissionregistration
apps
authentication
authorization
autoscaling
batch
certificates
coordination
core
discovery
events
extensions
flowcontrol
networking
node
policy
rbac
scheduling
storage
apimachinery
client-go
klog
modules.txt
sigs.k8s.io

@ -1,4 +1,3 @@
# Compiler support code
This directory contains compiler support code used by Gnostic and Gnostic
extensions.
This directory contains compiler support code used by Gnostic and Gnostic extensions.

@ -1,4 +1,4 @@
// Copyright 2017 Google LLC. All Rights Reserved.
// Copyright 2017 Google Inc. 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.
@ -14,36 +14,30 @@
package compiler
import (
yaml "gopkg.in/yaml.v3"
)
// Context contains state of the compiler as it traverses a document.
type Context struct {
Parent *Context
Name string
Node *yaml.Node
ExtensionHandlers *[]ExtensionHandler
}
// NewContextWithExtensions returns a new object representing the compiler state
func NewContextWithExtensions(name string, node *yaml.Node, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: extensionHandlers}
func NewContextWithExtensions(name string, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
return &Context{Name: name, Parent: parent, ExtensionHandlers: extensionHandlers}
}
// NewContext returns a new object representing the compiler state
func NewContext(name string, node *yaml.Node, parent *Context) *Context {
func NewContext(name string, parent *Context) *Context {
if parent != nil {
return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}
return &Context{Name: name, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}
}
return &Context{Name: name, Parent: parent, ExtensionHandlers: nil}
}
// Description returns a text description of the compiler state
func (context *Context) Description() string {
name := context.Name
if context.Parent != nil {
name = context.Parent.Description() + "." + name
return context.Parent.Description() + "." + context.Name
}
return name
return context.Name
}

@ -1,4 +1,4 @@
// Copyright 2017 Google LLC. All Rights Reserved.
// Copyright 2017 Google Inc. 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.
@ -14,8 +14,6 @@
package compiler
import "fmt"
// Error represents compiler errors and their location in the document.
type Error struct {
Context *Context
@ -27,19 +25,12 @@ func NewError(context *Context, message string) *Error {
return &Error{Context: context, Message: message}
}
func (err *Error) locationDescription() string {
if err.Context.Node != nil {
return fmt.Sprintf("[%d,%d] %s", err.Context.Node.Line, err.Context.Node.Column, err.Context.Description())
}
return err.Context.Description()
}
// Error returns the string value of an Error.
func (err *Error) Error() string {
if err.Context == nil {
return err.Message
return "ERROR " + err.Message
}
return err.locationDescription() + " " + err.Message
return "ERROR " + err.Context.Description() + " " + err.Message
}
// ErrorGroup is a container for groups of Error values.

@ -0,0 +1,101 @@
// Copyright 2017 Google Inc. 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 compiler
import (
"bytes"
"fmt"
"os/exec"
"strings"
"errors"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/any"
ext_plugin "github.com/googleapis/gnostic/extensions"
yaml "gopkg.in/yaml.v2"
)
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
type ExtensionHandler struct {
Name string
}
// HandleExtension calls a binary extension handler.
func HandleExtension(context *Context, in interface{}, extensionName string) (bool, *any.Any, error) {
handled := false
var errFromPlugin error
var outFromPlugin *any.Any
if context != nil && context.ExtensionHandlers != nil && len(*(context.ExtensionHandlers)) != 0 {
for _, customAnyProtoGenerator := range *(context.ExtensionHandlers) {
outFromPlugin, errFromPlugin = customAnyProtoGenerator.handle(in, extensionName)
if outFromPlugin == nil {
continue
} else {
handled = true
break
}
}
}
return handled, outFromPlugin, errFromPlugin
}
func (extensionHandlers *ExtensionHandler) handle(in interface{}, extensionName string) (*any.Any, error) {
if extensionHandlers.Name != "" {
binary, _ := yaml.Marshal(in)
request := &ext_plugin.ExtensionHandlerRequest{}
version := &ext_plugin.Version{}
version.Major = 0
version.Minor = 1
version.Patch = 0
request.CompilerVersion = version
request.Wrapper = &ext_plugin.Wrapper{}
request.Wrapper.Version = "v2"
request.Wrapper.Yaml = string(binary)
request.Wrapper.ExtensionName = extensionName
requestBytes, _ := proto.Marshal(request)
cmd := exec.Command(extensionHandlers.Name)
cmd.Stdin = bytes.NewReader(requestBytes)
output, err := cmd.Output()
if err != nil {
fmt.Printf("Error: %+v\n", err)
return nil, err
}
response := &ext_plugin.ExtensionHandlerResponse{}
err = proto.Unmarshal(output, response)
if err != nil {
fmt.Printf("Error: %+v\n", err)
fmt.Printf("%s\n", string(output))
return nil, err
}
if !response.Handled {
return nil, nil
}
if len(response.Error) != 0 {
message := fmt.Sprintf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Error, ","))
return nil, errors.New(message)
}
return response.Value, nil
}
return nil, nil
}

@ -1,85 +0,0 @@
// 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 compiler
import (
"bytes"
"fmt"
"os/exec"
"strings"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/any"
extensions "github.com/googleapis/gnostic/extensions"
yaml "gopkg.in/yaml.v3"
)
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
type ExtensionHandler struct {
Name string
}
// CallExtension calls a binary extension handler.
func CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *any.Any, err error) {
if context == nil || context.ExtensionHandlers == nil {
return false, nil, nil
}
handled = false
for _, handler := range *(context.ExtensionHandlers) {
response, err = handler.handle(in, extensionName)
if response == nil {
continue
} else {
handled = true
break
}
}
return handled, response, err
}
func (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*any.Any, error) {
if extensionHandlers.Name != "" {
yamlData, _ := yaml.Marshal(in)
request := &extensions.ExtensionHandlerRequest{
CompilerVersion: &extensions.Version{
Major: 0,
Minor: 1,
Patch: 0,
},
Wrapper: &extensions.Wrapper{
Version: "unknown", // TODO: set this to the type/version of spec being parsed.
Yaml: string(yamlData),
ExtensionName: extensionName,
},
}
requestBytes, _ := proto.Marshal(request)
cmd := exec.Command(extensionHandlers.Name)
cmd.Stdin = bytes.NewReader(requestBytes)
output, err := cmd.Output()
if err != nil {
return nil, err
}
response := &extensions.ExtensionHandlerResponse{}
err = proto.Unmarshal(output, response)
if err != nil || !response.Handled {
return nil, err
}
if len(response.Errors) != 0 {
return nil, fmt.Errorf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Errors, ","))
}
return response.Value, nil
}
return nil, nil
}

@ -1,4 +1,4 @@
// Copyright 2017 Google LLC. All Rights Reserved.
// Copyright 2017 Google Inc. 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.
@ -16,63 +16,56 @@ package compiler
import (
"fmt"
"gopkg.in/yaml.v2"
"regexp"
"sort"
"strconv"
"github.com/googleapis/gnostic/jsonschema"
"gopkg.in/yaml.v3"
)
// compiler helper functions, usually called from generated code
// UnpackMap gets a *yaml.Node if possible.
func UnpackMap(in *yaml.Node) (*yaml.Node, bool) {
if in == nil {
return nil, false
// UnpackMap gets a yaml.MapSlice if possible.
func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
m, ok := in.(yaml.MapSlice)
if ok {
return m, true
}
return in, true
// do we have an empty array?
a, ok := in.([]interface{})
if ok && len(a) == 0 {
// if so, return an empty map
return yaml.MapSlice{}, true
}
return nil, false
}
// SortedKeysForMap returns the sorted keys of a yamlv2.MapSlice.
func SortedKeysForMap(m *yaml.Node) []string {
// SortedKeysForMap returns the sorted keys of a yaml.MapSlice.
func SortedKeysForMap(m yaml.MapSlice) []string {
keys := make([]string, 0)
if m.Kind == yaml.MappingNode {
for i := 0; i < len(m.Content); i += 2 {
keys = append(keys, m.Content[i].Value)
}
for _, item := range m {
keys = append(keys, item.Key.(string))
}
sort.Strings(keys)
return keys
}
// MapHasKey returns true if a yamlv2.MapSlice contains a specified key.
func MapHasKey(m *yaml.Node, key string) bool {
if m == nil {
return false
}
if m.Kind == yaml.MappingNode {
for i := 0; i < len(m.Content); i += 2 {
itemKey := m.Content[i].Value
if key == itemKey {
return true
}
// MapHasKey returns true if a yaml.MapSlice contains a specified key.
func MapHasKey(m yaml.MapSlice, key string) bool {
for _, item := range m {
itemKey, ok := item.Key.(string)
if ok && key == itemKey {
return true
}
}
return false
}
// MapValueForKey gets the value of a map value for a specified key.
func MapValueForKey(m *yaml.Node, key string) *yaml.Node {
if m == nil {
return nil
}
if m.Kind == yaml.MappingNode {
for i := 0; i < len(m.Content); i += 2 {
itemKey := m.Content[i].Value
if key == itemKey {
return m.Content[i+1]
}
func MapValueForKey(m yaml.MapSlice, key string) interface{} {
for _, item := range m {
itemKey, ok := item.Key.(string)
if ok && key == itemKey {
return item.Value
}
}
return nil
@ -90,118 +83,8 @@ func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {
return stringArray
}
// SequenceNodeForNode returns a node if it is a SequenceNode.
func SequenceNodeForNode(node *yaml.Node) (*yaml.Node, bool) {
if node.Kind != yaml.SequenceNode {
return nil, false
}
return node, true
}
// BoolForScalarNode returns the bool value of a node.
func BoolForScalarNode(node *yaml.Node) (bool, bool) {
if node == nil {
return false, false
}
if node.Kind == yaml.DocumentNode {
return BoolForScalarNode(node.Content[0])
}
if node.Kind != yaml.ScalarNode {
return false, false
}
if node.Tag != "!!bool" {
return false, false
}
v, err := strconv.ParseBool(node.Value)
if err != nil {
return false, false
}
return v, true
}
// IntForScalarNode returns the integer value of a node.
func IntForScalarNode(node *yaml.Node) (int64, bool) {
if node == nil {
return 0, false
}
if node.Kind == yaml.DocumentNode {
return IntForScalarNode(node.Content[0])
}
if node.Kind != yaml.ScalarNode {
return 0, false
}
if node.Tag != "!!int" {
return 0, false
}
v, err := strconv.ParseInt(node.Value, 10, 64)
if err != nil {
return 0, false
}
return v, true
}
// FloatForScalarNode returns the float value of a node.
func FloatForScalarNode(node *yaml.Node) (float64, bool) {
if node == nil {
return 0.0, false
}
if node.Kind == yaml.DocumentNode {
return FloatForScalarNode(node.Content[0])
}
if node.Kind != yaml.ScalarNode {
return 0.0, false
}
if (node.Tag != "!!int") && (node.Tag != "!!float") {
return 0.0, false
}
v, err := strconv.ParseFloat(node.Value, 64)
if err != nil {
return 0.0, false
}
return v, true
}
// StringForScalarNode returns the string value of a node.
func StringForScalarNode(node *yaml.Node) (string, bool) {
if node == nil {
return "", false
}
if node.Kind == yaml.DocumentNode {
return StringForScalarNode(node.Content[0])
}
switch node.Kind {
case yaml.ScalarNode:
switch node.Tag {
case "!!int":
return node.Value, true
case "!!str":
return node.Value, true
case "!!timestamp":
return node.Value, true
case "!!null":
return "", true
default:
return "", false
}
default:
return "", false
}
}
// StringArrayForSequenceNode converts a sequence node to an array of strings, if possible.
func StringArrayForSequenceNode(node *yaml.Node) []string {
stringArray := make([]string, 0)
for _, item := range node.Content {
v, ok := StringForScalarNode(item)
if ok {
stringArray = append(stringArray, v)
}
}
return stringArray
}
// MissingKeysInMap identifies which keys from a list of required keys are not in a map.
func MissingKeysInMap(m *yaml.Node, requiredKeys []string) []string {
func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
missingKeys := make([]string, 0)
for _, k := range requiredKeys {
if !MapHasKey(m, k) {
@ -212,109 +95,64 @@ func MissingKeysInMap(m *yaml.Node, requiredKeys []string) []string {
}
// InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns.
func InvalidKeysInMap(m *yaml.Node, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
invalidKeys := make([]string, 0)
if m == nil || m.Kind != yaml.MappingNode {
return invalidKeys
}
for i := 0; i < len(m.Content); i += 2 {
key := m.Content[i].Value
found := false
// does the key match an allowed key?
for _, allowedKey := range allowedKeys {
if key == allowedKey {
found = true
break
}
}
if !found {
// does the key match an allowed pattern?
for _, allowedPattern := range allowedPatterns {
if allowedPattern.MatchString(key) {
for _, item := range m {
itemKey, ok := item.Key.(string)
if ok {
key := itemKey
found := false
// does the key match an allowed key?
for _, allowedKey := range allowedKeys {
if key == allowedKey {
found = true
break
}
}
if !found {
invalidKeys = append(invalidKeys, key)
// does the key match an allowed pattern?
for _, allowedPattern := range allowedPatterns {
if allowedPattern.MatchString(key) {
found = true
break
}
}
if !found {
invalidKeys = append(invalidKeys, key)
}
}
}
}
return invalidKeys
}
// NewNullNode creates a new Null node.
func NewNullNode() *yaml.Node {
node := &yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!null",
// DescribeMap describes a map (for debugging purposes).
func DescribeMap(in interface{}, indent string) string {
description := ""
m, ok := in.(map[string]interface{})
if ok {
keys := make([]string, 0)
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := m[k]
description += fmt.Sprintf("%s%s:\n", indent, k)
description += DescribeMap(v, indent+" ")
}
return description
}
return node
}
// NewMappingNode creates a new Mapping node.
func NewMappingNode() *yaml.Node {
return &yaml.Node{
Kind: yaml.MappingNode,
Content: make([]*yaml.Node, 0),
}
}
// NewSequenceNode creates a new Sequence node.
func NewSequenceNode() *yaml.Node {
node := &yaml.Node{
Kind: yaml.SequenceNode,
Content: make([]*yaml.Node, 0),
}
return node
}
// NewScalarNodeForString creates a new node to hold a string.
func NewScalarNodeForString(s string) *yaml.Node {
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!str",
Value: s,
}
}
// NewSequenceNodeForStringArray creates a new node to hold an array of strings.
func NewSequenceNodeForStringArray(strings []string) *yaml.Node {
node := &yaml.Node{
Kind: yaml.SequenceNode,
Content: make([]*yaml.Node, 0),
}
for _, s := range strings {
node.Content = append(node.Content, NewScalarNodeForString(s))
}
return node
}
// NewScalarNodeForBool creates a new node to hold a bool.
func NewScalarNodeForBool(b bool) *yaml.Node {
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!bool",
Value: fmt.Sprintf("%t", b),
}
}
// NewScalarNodeForFloat creates a new node to hold a float.
func NewScalarNodeForFloat(f float64) *yaml.Node {
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!float",
Value: fmt.Sprintf("%g", f),
}
}
// NewScalarNodeForInt creates a new node to hold an integer.
func NewScalarNodeForInt(i int64) *yaml.Node {
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!int",
Value: fmt.Sprintf("%d", i),
a, ok := in.([]interface{})
if ok {
for i, v := range a {
description += fmt.Sprintf("%s%d:\n", indent, i)
description += DescribeMap(v, indent+" ")
}
return description
}
description += fmt.Sprintf("%s%+v\n", indent, in)
return description
}
// PluralProperties returns the string "properties" pluralized.
@ -357,40 +195,3 @@ func StringValue(item interface{}) (value string, ok bool) {
}
return "", false
}
// Description returns a human-readable represention of an item.
func Description(item interface{}) string {
value, ok := item.(*yaml.Node)
if ok {
return jsonschema.Render(value)
}
return fmt.Sprintf("%+v", item)
}
// Display returns a description of a node for use in error messages.
func Display(node *yaml.Node) string {
switch node.Kind {
case yaml.ScalarNode:
switch node.Tag {
case "!!str":
return fmt.Sprintf("%s (string)", node.Value)
}
}
return fmt.Sprintf("%+v (%T)", node, node)
}
// Marshal creates a yaml version of a structure in our preferred style
func Marshal(in *yaml.Node) []byte {
clearStyle(in)
//bytes, _ := yaml.Marshal(&yaml.Node{Kind: yaml.DocumentNode, Content: []*yaml.Node{in}})
bytes, _ := yaml.Marshal(in)
return bytes
}
func clearStyle(node *yaml.Node) {
node.Style = 0
for _, c := range node.Content {
clearStyle(c)
}
}

@ -1,4 +1,4 @@
// Copyright 2017 Google LLC. All Rights Reserved.
// Copyright 2017 Google Inc. 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.

@ -1,4 +1,4 @@
// Copyright 2017 Google LLC. All Rights Reserved.
// Copyright 2017 Google Inc. 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.
@ -15,36 +15,22 @@
package compiler
import (
"errors"
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"net/http"
"net/url"
"path/filepath"
"strings"
"sync"
yaml "gopkg.in/yaml.v3"
)
var verboseReader = false
var fileCache map[string][]byte
var infoCache map[string]*yaml.Node
var infoCache map[string]interface{}
var count int64
var fileCacheEnable = true
var infoCacheEnable = true
// These locks are used to synchronize accesses to the fileCache and infoCache
// maps (above). They are global state and can throw thread-related errors
// when modified from separate goroutines. The general strategy is to protect
// all public functions in this file with mutex Lock() calls. As a result, to
// avoid deadlock, these public functions should not call other public
// functions, so some public functions have private equivalents.
// In the future, we might consider replacing the maps with sync.Map and
// eliminating these mutexes.
var fileCacheMutex sync.Mutex
var infoCacheMutex sync.Mutex
var verboseReader = false
func initializeFileCache() {
if fileCache == nil {
@ -54,122 +40,33 @@ func initializeFileCache() {
func initializeInfoCache() {
if infoCache == nil {
infoCache = make(map[string]*yaml.Node, 0)
infoCache = make(map[string]interface{}, 0)
}
}
// EnableFileCache turns on file caching.
func EnableFileCache() {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
fileCacheEnable = true
}
// EnableInfoCache turns on parsed info caching.
func EnableInfoCache() {
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
infoCacheEnable = true
}
// DisableFileCache turns off file caching.
func DisableFileCache() {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
fileCacheEnable = false
}
// DisableInfoCache turns off parsed info caching.
func DisableInfoCache() {
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
infoCacheEnable = false
}
// RemoveFromFileCache removes an entry from the file cache.
func RemoveFromFileCache(fileurl string) {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
if !fileCacheEnable {
return
}
initializeFileCache()
delete(fileCache, fileurl)
}
// RemoveFromInfoCache removes an entry from the info cache.
func RemoveFromInfoCache(filename string) {
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
if !infoCacheEnable {
return
}
initializeInfoCache()
delete(infoCache, filename)
}
// GetInfoCache returns the info cache map.
func GetInfoCache() map[string]*yaml.Node {
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
if infoCache == nil {
initializeInfoCache()
}
return infoCache
}
// ClearFileCache clears the file cache.
func ClearFileCache() {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
fileCache = make(map[string][]byte, 0)
}
// ClearInfoCache clears the info cache.
func ClearInfoCache() {
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
infoCache = make(map[string]*yaml.Node)
}
// ClearCaches clears all caches.
func ClearCaches() {
ClearFileCache()
ClearInfoCache()
}
// FetchFile gets a specified file from the local filesystem or a remote location.
func FetchFile(fileurl string) ([]byte, error) {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
return fetchFile(fileurl)
}
func fetchFile(fileurl string) ([]byte, error) {
var bytes []byte
initializeFileCache()
if fileCacheEnable {
bytes, ok := fileCache[fileurl]
if ok {
if verboseReader {
log.Printf("Cache hit %s", fileurl)
}
return bytes, nil
}
bytes, ok := fileCache[fileurl]
if ok {
if verboseReader {
log.Printf("Fetching %s", fileurl)
log.Printf("Cache hit %s", fileurl)
}
return bytes, nil
}
if verboseReader {
log.Printf("Fetching %s", fileurl)
}
response, err := http.Get(fileurl)
if err != nil {
return nil, err
}
defer response.Body.Close()
if response.StatusCode != 200 {
return nil, fmt.Errorf("Error downloading %s: %s", fileurl, response.Status)
return nil, errors.New(fmt.Sprintf("Error downloading %s: %s", fileurl, response.Status))
}
defer response.Body.Close()
bytes, err = ioutil.ReadAll(response.Body)
if fileCacheEnable && err == nil {
if err == nil {
fileCache[fileurl] = bytes
}
return bytes, err
@ -177,17 +74,11 @@ func fetchFile(fileurl string) ([]byte, error) {
// ReadBytesForFile reads the bytes of a file.
func ReadBytesForFile(filename string) ([]byte, error) {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
return readBytesForFile(filename)
}
func readBytesForFile(filename string) ([]byte, error) {
// is the filename a url?
fileurl, _ := url.Parse(filename)
if fileurl.Scheme != "" {
// yes, fetch it
bytes, err := fetchFile(filename)
bytes, err := FetchFile(filename)
if err != nil {
return nil, err
}
@ -201,46 +92,32 @@ func readBytesForFile(filename string) ([]byte, error) {
return bytes, nil
}
// ReadInfoFromBytes unmarshals a file as a *yaml.Node.
func ReadInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) {
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
return readInfoFromBytes(filename, bytes)
}
func readInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) {
// ReadInfoFromBytes unmarshals a file as a yaml.MapSlice.
func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
initializeInfoCache()
if infoCacheEnable {
cachedInfo, ok := infoCache[filename]
if ok {
if verboseReader {
log.Printf("Cache hit info for file %s", filename)
}
return cachedInfo, nil
}
cachedInfo, ok := infoCache[filename]
if ok {
if verboseReader {
log.Printf("Reading info for file %s", filename)
log.Printf("Cache hit info for file %s", filename)
}
return cachedInfo, nil
}
var info yaml.Node
if verboseReader {
log.Printf("Reading info for file %s", filename)
}
var info yaml.MapSlice
err := yaml.Unmarshal(bytes, &info)
if err != nil {
return nil, err
}
if infoCacheEnable && len(filename) > 0 {
infoCache[filename] = &info
}
return &info, nil
infoCache[filename] = info
return info, nil
}
// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref.
func ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) {
fileCacheMutex.Lock()
defer fileCacheMutex.Unlock()
infoCacheMutex.Lock()
defer infoCacheMutex.Unlock()
func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
initializeInfoCache()
if infoCacheEnable {
{
info, ok := infoCache[ref]
if ok {
if verboseReader {
@ -248,46 +125,37 @@ func ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) {
}
return info, nil
}
if verboseReader {
log.Printf("Reading info for ref %s#%s", basefile, ref)
}
}
if verboseReader {
log.Printf("Reading info for ref %s#%s", basefile, ref)
}
count = count + 1
basedir, _ := filepath.Split(basefile)
parts := strings.Split(ref, "#")
var filename string
if parts[0] != "" {
filename = parts[0]
if _, err := url.ParseRequestURI(parts[0]); err != nil {
// It is not an URL, so the file is local
filename = basedir + parts[0]
}
filename = basedir + parts[0]
} else {
filename = basefile
}
bytes, err := readBytesForFile(filename)
bytes, err := ReadBytesForFile(filename)
if err != nil {
return nil, err
}
info, err := readInfoFromBytes(filename, bytes)
if info != nil && info.Kind == yaml.DocumentNode {
info = info.Content[0]
}
info, err := ReadInfoFromBytes(filename, bytes)
if err != nil {
log.Printf("File error: %v\n", err)
} else {
if info == nil {
return nil, NewError(nil, fmt.Sprintf("could not resolve %s", ref))
}
if len(parts) > 1 {
path := strings.Split(parts[1], "/")
for i, key := range path {
if i > 0 {
m := info
if true {
m, ok := info.(yaml.MapSlice)
if ok {
found := false
for i := 0; i < len(m.Content); i += 2 {
if m.Content[i].Value == key {
info = m.Content[i+1]
for _, section := range m {
if section.Key == key {
info = section.Value
found = true
}
}
@ -300,8 +168,6 @@ func ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) {
}
}
}
if infoCacheEnable {
infoCache[ref] = info
}
infoCache[ref] = info
return info, nil
}