.github
alerting
client
config
controller
core
docs
examples
jsonpath
k8s
k8stest
metric
pattern
security
storage
util
vendor
cloud.google.com
github.com
TwinProduction
beorn7
cespare
davecgh
go-ping
gogo
golang
google
googleapis
gnostic
OpenAPIv2
compiler
README.md
context.go
error.go
extension-handler.go
helpers.go
main.go
reader.go
extensions
LICENSE
gorilla
imdario
json-iterator
kballard
mattn
matttproud
miekg
modern-go
prometheus
remyoudompheng
spf13
go.etcd.io
golang.org
google.golang.org
gopkg.in
k8s.io
lukechampine.com
modernc.org
sigs.k8s.io
modules.txt
watchdog
web
.dockerignore
.gitattributes
.gitignore
Dockerfile
LICENSE.md
Makefile
README.md
config.yaml
go.mod
go.sum
main.go
198 lines
4.9 KiB
Go
198 lines
4.9 KiB
Go
// 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 (
|
|
"fmt"
|
|
"gopkg.in/yaml.v2"
|
|
"regexp"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
// compiler helper functions, usually called from generated code
|
|
|
|
// UnpackMap gets a yaml.MapSlice if possible.
|
|
func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
|
|
m, ok := in.(yaml.MapSlice)
|
|
if ok {
|
|
return m, 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 yaml.MapSlice.
|
|
func SortedKeysForMap(m yaml.MapSlice) []string {
|
|
keys := make([]string, 0)
|
|
for _, item := range m {
|
|
keys = append(keys, item.Key.(string))
|
|
}
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|
|
|
|
// 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.MapSlice, key string) interface{} {
|
|
for _, item := range m {
|
|
itemKey, ok := item.Key.(string)
|
|
if ok && key == itemKey {
|
|
return item.Value
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ConvertInterfaceArrayToStringArray converts an array of interfaces to an array of strings, if possible.
|
|
func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {
|
|
stringArray := make([]string, 0)
|
|
for _, item := range interfaceArray {
|
|
v, ok := item.(string)
|
|
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.MapSlice, requiredKeys []string) []string {
|
|
missingKeys := make([]string, 0)
|
|
for _, k := range requiredKeys {
|
|
if !MapHasKey(m, k) {
|
|
missingKeys = append(missingKeys, k)
|
|
}
|
|
}
|
|
return missingKeys
|
|
}
|
|
|
|
// InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns.
|
|
func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {
|
|
invalidKeys := make([]string, 0)
|
|
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 {
|
|
// 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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
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.
|
|
func PluralProperties(count int) string {
|
|
if count == 1 {
|
|
return "property"
|
|
}
|
|
return "properties"
|
|
}
|
|
|
|
// StringArrayContainsValue returns true if a string array contains a specified value.
|
|
func StringArrayContainsValue(array []string, value string) bool {
|
|
for _, item := range array {
|
|
if item == value {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// StringArrayContainsValues returns true if a string array contains all of a list of specified values.
|
|
func StringArrayContainsValues(array []string, values []string) bool {
|
|
for _, value := range values {
|
|
if !StringArrayContainsValue(array, value) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// StringValue returns the string value of an item.
|
|
func StringValue(item interface{}) (value string, ok bool) {
|
|
value, ok = item.(string)
|
|
if ok {
|
|
return value, ok
|
|
}
|
|
intValue, ok := item.(int)
|
|
if ok {
|
|
return strconv.Itoa(intValue), true
|
|
}
|
|
return "", false
|
|
}
|