forked from github/multus-cni
Replace entrypoint script with initcontainers (#718)
* build: install the multus binary in an init container Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * build: generate kubeconfig via go Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * build: generate multus cni configuration via golang Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * build: provide a docker img for daemon based deployments We will have 2 different images (only on amd64 archs): - legacy entrypoint script based - daemonized process The `image-build` docker action is updated, to build these 2 images. There will be 2 different deployment specs, along with e2e test lanes, one for each of the aforementioned alternatives. Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * build: delegate CNI config watch loop via golang For the thick-plugin alternative, provide the watch loop for configuration regeneration via a golang binary. Over time, this binary is expected to run the control loop to watch out for pod updates. To enable current multus users to chose when they upgrade to this new deployment setup, these changes are provided in separate multus images, having a different yaml spec files. Both of these alternatives are tested e2e, since a new lane is introduced. The following libraries are introduced, along with the motivation for adding them: - dproxy: allows traversing the default network configuration arbitrarily, similar to what an X path / JSON path tool provides. Repo is available at [0]. - fsnotify: watch for changes in the default CNI configuration file. Repo is available at [1]. The config map providing the default network CNI configuration is not copied over, since originally, the user was not required to install a default network CNI plugin first, but, nowadays, this is a required step of multus. As such, it is no longer required to provide a default CNI configuration. [0] - https://github.com/koron/go-dproxy [1] - https://github.com/fsnotify/fsnotify Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * run gofmt Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * refactor: make the builder pattern more idiomatic to golang Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com> * build: update github actions to release new imgs Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com>
This commit is contained in:
committed by
GitHub
parent
b56dd5f67f
commit
8ba2accb9f
2
vendor/github.com/koron/go-dproxy/.gitignore
generated
vendored
Normal file
2
vendor/github.com/koron/go-dproxy/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/tags
|
||||
/tmp/
|
21
vendor/github.com/koron/go-dproxy/LICENSE
generated
vendored
Normal file
21
vendor/github.com/koron/go-dproxy/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
29
vendor/github.com/koron/go-dproxy/Makefile
generated
vendored
Normal file
29
vendor/github.com/koron/go-dproxy/Makefile
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
default: test
|
||||
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
test-full:
|
||||
go test -v -race ./...
|
||||
|
||||
lint:
|
||||
go vet ./...
|
||||
@echo ""
|
||||
golint ./...
|
||||
|
||||
cyclo:
|
||||
-gocyclo -top 10 -avg .
|
||||
|
||||
report:
|
||||
@echo "misspell"
|
||||
@find . -name "*.go" | xargs misspell
|
||||
@echo ""
|
||||
-errcheck ./...
|
||||
@echo ""
|
||||
-gocyclo -over 14 -avg .
|
||||
@echo ""
|
||||
go vet ./...
|
||||
@echo ""
|
||||
golint ./...
|
||||
|
||||
.PHONY: test test-full lint cyclo report
|
155
vendor/github.com/koron/go-dproxy/README.md
generated
vendored
Normal file
155
vendor/github.com/koron/go-dproxy/README.md
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
# dProxy - document proxy
|
||||
|
||||
[](https://godoc.org/github.com/koron/go-dproxy)
|
||||
[](https://circleci.com/gh/koron/go-dproxy/tree/master)
|
||||
[](https://goreportcard.com/report/github.com/koron/go-dproxy)
|
||||
|
||||
dProxy is a proxy to access `interface{}` (document) by simple query.
|
||||
It is intented to be used with `json.Unmarshal()` or `json.NewDecorder()`.
|
||||
|
||||
See codes for overview.
|
||||
|
||||
```go
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/koron/go-dproxy"
|
||||
)
|
||||
|
||||
var v interface{}
|
||||
json.Unmarshal([]byte(`{
|
||||
"cities": [ "tokyo", 100, "osaka", 200, "hakata", 300 ],
|
||||
"data": {
|
||||
"custom": [ "male", 23, "female", 24 ]
|
||||
}
|
||||
}`), &v)
|
||||
|
||||
// s == "tokyo", got a string.
|
||||
s, _ := dproxy.New(v).M("cities").A(0).String()
|
||||
|
||||
// err != nil, type not matched.
|
||||
_, err := dproxy.New(v).M("cities").A(0).Float64()
|
||||
|
||||
// n == 200, got a float64
|
||||
n, _ := dproxy.New(v).M("cities").A(3).Float64()
|
||||
|
||||
// can be chained.
|
||||
dproxy.New(v).M("data").M("custom").A(0).String()
|
||||
|
||||
// err.Error() == "not found: data.kustom", wrong query can be verified.
|
||||
_, err = dproxy.New(v).M("data").M("kustom").String()
|
||||
```
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
### Proxy
|
||||
|
||||
1. Wrap a value (`interface{}`) with `dproxy.New()` get `dproxy.Proxy`.
|
||||
|
||||
```go
|
||||
p := dproxy.New(v) // v should be a value of interface{}
|
||||
```
|
||||
|
||||
2. Query as a map (`map[string]interface{}`)by `M()`, returns `dproxy.Proxy`.
|
||||
|
||||
```go
|
||||
p.M("cities")
|
||||
```
|
||||
|
||||
3. Query as an array (`[]interface{}`) with `A()`, returns `dproxy.Proxy`.
|
||||
|
||||
```go
|
||||
p.A(3)
|
||||
```
|
||||
|
||||
4. Therefore, can be chained queries.
|
||||
|
||||
```go
|
||||
p.M("cities").A(3)
|
||||
```
|
||||
|
||||
5. Get a value finally.
|
||||
|
||||
```go
|
||||
n, _ := p.M("cities").A(3).Int64()
|
||||
```
|
||||
|
||||
6. You'll get an error when getting a value, if there were some mistakes.
|
||||
|
||||
```go
|
||||
// OOPS! "kustom" is typo, must be "custom"
|
||||
_, err := p.M("data").M("kustom").A(3).Int64()
|
||||
|
||||
// "not found: data.kustom"
|
||||
fmt.Println(err)
|
||||
```
|
||||
|
||||
7. If you tried to get a value as different type, get an error.
|
||||
|
||||
```go
|
||||
// OOPS! "cities[3]" (=200) should be float64 or int64.
|
||||
_, err := p.M("cities").A(3).String()
|
||||
|
||||
// "not matched types: expected=string actual=float64: cities[3]"
|
||||
fmt.Println(err)
|
||||
```
|
||||
|
||||
8. You can verify queries easily.
|
||||
|
||||
### Drain
|
||||
|
||||
Getting value and error from Proxy/ProxySet multiple times, is very awful.
|
||||
It must check error when every getting values.
|
||||
|
||||
```go
|
||||
p := dproxy.New(v)
|
||||
v1, err := p.M("cities").A(3).Int64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v2, err := p.M("data").M("kustom").A(3).Int64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v3, err := p.M("cities").A(3).String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
It can be rewrite as simple like below with `dproxy.Drain`
|
||||
|
||||
```go
|
||||
var d Drain
|
||||
p := dproxy.New(v)
|
||||
v1 := d.Int64(p.M("cities").A(3))
|
||||
v2 := d.Int64(p.M("data").M("kustom").A(3))
|
||||
v3 := d.String(p.M("cities").A(3))
|
||||
if err := d.CombineErrors(); err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Pointer
|
||||
|
||||
JSON Pointer can be used to query `interface{}`
|
||||
|
||||
```go
|
||||
v1, err := dproxy.New(v).P("/cities/0").Int64()
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```go
|
||||
v1, err := dproxy.Pointer(v, "/cities/0").Int64()
|
||||
```
|
||||
|
||||
See [RFC6901][1] for details of JSON Pointer.
|
||||
|
||||
|
||||
## LICENSE
|
||||
|
||||
MIT license. See LICENSE.
|
||||
|
||||
[1]: https://tools.ietf.org/html/rfc6901
|
150
vendor/github.com/koron/go-dproxy/drain.go
generated
vendored
Normal file
150
vendor/github.com/koron/go-dproxy/drain.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
package dproxy
|
||||
|
||||
import "bytes"
|
||||
|
||||
// Drain stores errors from Proxy or ProxySet.
|
||||
type Drain struct {
|
||||
errors []error
|
||||
}
|
||||
|
||||
// Has returns true if the drain stored some of errors.
|
||||
func (d *Drain) Has() bool {
|
||||
return d != nil && len(d.errors) > 0
|
||||
}
|
||||
|
||||
// First returns a stored error. Returns nil if there are no errors.
|
||||
func (d *Drain) First() error {
|
||||
if d == nil || len(d.errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
return d.errors[0]
|
||||
}
|
||||
|
||||
// All returns all errors which stored. Return nil if no errors stored.
|
||||
func (d *Drain) All() []error {
|
||||
if d == nil || len(d.errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
a := make([]error, 0, len(d.errors))
|
||||
return append(a, d.errors...)
|
||||
}
|
||||
|
||||
// CombineErrors returns an error which combined all stored errors. Return nil
|
||||
// if not erros stored.
|
||||
func (d *Drain) CombineErrors() error {
|
||||
if d == nil || len(d.errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
return drainError(d.errors)
|
||||
}
|
||||
|
||||
func (d *Drain) put(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
d.errors = append(d.errors, err)
|
||||
}
|
||||
|
||||
// Bool returns bool value and stores an error.
|
||||
func (d *Drain) Bool(p Proxy) bool {
|
||||
v, err := p.Bool()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// Int64 returns int64 value and stores an error.
|
||||
func (d *Drain) Int64(p Proxy) int64 {
|
||||
v, err := p.Int64()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// Float64 returns float64 value and stores an error.
|
||||
func (d *Drain) Float64(p Proxy) float64 {
|
||||
v, err := p.Float64()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// String returns string value and stores an error.
|
||||
func (d *Drain) String(p Proxy) string {
|
||||
v, err := p.String()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// Array returns []interface{} value and stores an error.
|
||||
func (d *Drain) Array(p Proxy) []interface{} {
|
||||
v, err := p.Array()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// Map returns map[string]interface{} value and stores an error.
|
||||
func (d *Drain) Map(p Proxy) map[string]interface{} {
|
||||
v, err := p.Map()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// BoolArray returns []bool value and stores an error.
|
||||
func (d *Drain) BoolArray(ps ProxySet) []bool {
|
||||
v, err := ps.BoolArray()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// Int64Array returns []int64 value and stores an error.
|
||||
func (d *Drain) Int64Array(ps ProxySet) []int64 {
|
||||
v, err := ps.Int64Array()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// Float64Array returns []float64 value and stores an error.
|
||||
func (d *Drain) Float64Array(ps ProxySet) []float64 {
|
||||
v, err := ps.Float64Array()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// StringArray returns []string value and stores an error.
|
||||
func (d *Drain) StringArray(ps ProxySet) []string {
|
||||
v, err := ps.StringArray()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// ArrayArray returns [][]interface{} value and stores an error.
|
||||
func (d *Drain) ArrayArray(ps ProxySet) [][]interface{} {
|
||||
v, err := ps.ArrayArray()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// MapArray returns []map[string]interface{} value and stores an error.
|
||||
func (d *Drain) MapArray(ps ProxySet) []map[string]interface{} {
|
||||
v, err := ps.MapArray()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
// ProxyArray returns []Proxy value and stores an error.
|
||||
func (d *Drain) ProxyArray(ps ProxySet) []Proxy {
|
||||
v, err := ps.ProxyArray()
|
||||
d.put(err)
|
||||
return v
|
||||
}
|
||||
|
||||
type drainError []error
|
||||
|
||||
func (derr drainError) Error() string {
|
||||
b := bytes.Buffer{}
|
||||
for i, err := range derr {
|
||||
if i > 0 {
|
||||
_, _ = b.WriteString("; ")
|
||||
}
|
||||
_, _ = b.WriteString(err.Error())
|
||||
}
|
||||
return b.String()
|
||||
}
|
253
vendor/github.com/koron/go-dproxy/error.go
generated
vendored
Normal file
253
vendor/github.com/koron/go-dproxy/error.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
package dproxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ErrorType is type of errors
|
||||
type ErrorType int
|
||||
|
||||
const (
|
||||
// Etype means expected type is not matched with actual.
|
||||
Etype ErrorType = iota + 1
|
||||
|
||||
// Enotfound means key or index doesn't exist.
|
||||
Enotfound
|
||||
|
||||
// EmapNorArray means target is not a map nor an array (for JSON Pointer)
|
||||
EmapNorArray
|
||||
|
||||
// EconvertFailure means value conversion is failed.
|
||||
EconvertFailure
|
||||
|
||||
// EinvalidIndex means token is invalid as index (for JSON Pointer)
|
||||
EinvalidIndex
|
||||
|
||||
// EinvalidQuery means query is invalid as JSON Pointer.
|
||||
EinvalidQuery
|
||||
|
||||
// ErequiredType means the type mismatch against user required one.
|
||||
// For example M() requires map, A() requires array.
|
||||
ErequiredType
|
||||
)
|
||||
|
||||
func (et ErrorType) String() string {
|
||||
switch et {
|
||||
case Etype:
|
||||
return "Etype"
|
||||
case Enotfound:
|
||||
return "Enotfound"
|
||||
case EmapNorArray:
|
||||
return "EmapNorArray"
|
||||
case EconvertFailure:
|
||||
return "EconvertFailure"
|
||||
case EinvalidIndex:
|
||||
return "EinvalidIndex"
|
||||
case EinvalidQuery:
|
||||
return "EinvalidQuery"
|
||||
case ErequiredType:
|
||||
return "ErequiredType"
|
||||
default:
|
||||
return "Eunknown"
|
||||
}
|
||||
}
|
||||
|
||||
// Error get detail information of the errror.
|
||||
type Error interface {
|
||||
// ErrorType returns type of error.
|
||||
ErrorType() ErrorType
|
||||
|
||||
// FullAddress returns query string where cause first error.
|
||||
FullAddress() string
|
||||
}
|
||||
|
||||
type errorProxy struct {
|
||||
errorType ErrorType
|
||||
parent frame
|
||||
label string
|
||||
|
||||
expected Type
|
||||
actual Type
|
||||
infoStr string
|
||||
}
|
||||
|
||||
// errorProxy implements error, Proxy and ProxySet.
|
||||
var (
|
||||
_ error = (*errorProxy)(nil)
|
||||
_ Proxy = (*errorProxy)(nil)
|
||||
_ ProxySet = (*errorProxy)(nil)
|
||||
)
|
||||
|
||||
func (p *errorProxy) Nil() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *errorProxy) Value() (interface{}, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Bool() (bool, error) {
|
||||
return false, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Int64() (int64, error) {
|
||||
return 0, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Float64() (float64, error) {
|
||||
return 0, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) String() (string, error) {
|
||||
return "", p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Array() ([]interface{}, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Map() (map[string]interface{}, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) A(n int) Proxy {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) M(k string) Proxy {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) P(q string) Proxy {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Empty() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *errorProxy) Len() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *errorProxy) BoolArray() ([]bool, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Int64Array() ([]int64, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Float64Array() ([]float64, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) StringArray() ([]string, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) ArrayArray() ([][]interface{}, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) MapArray() ([]map[string]interface{}, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) ProxyArray() ([]Proxy, error) {
|
||||
return nil, p
|
||||
}
|
||||
|
||||
func (p *errorProxy) ProxySet() ProxySet {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Q(k string) ProxySet {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) Qc(k string) ProxySet {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) findJPT(t string) Proxy {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *errorProxy) parentFrame() frame {
|
||||
return p.parent
|
||||
}
|
||||
|
||||
func (p *errorProxy) frameLabel() string {
|
||||
return p.label
|
||||
}
|
||||
|
||||
func (p *errorProxy) Error() string {
|
||||
switch p.errorType {
|
||||
case Etype:
|
||||
return fmt.Sprintf("not matched types: expected=%s actual=%s: %s",
|
||||
p.expected.String(), p.actual.String(), p.FullAddress())
|
||||
case Enotfound:
|
||||
return fmt.Sprintf("not found: %s", p.FullAddress())
|
||||
case EmapNorArray:
|
||||
// FIXME: better error message.
|
||||
return fmt.Sprintf("not map nor array: actual=%s: %s",
|
||||
p.actual.String(), p.FullAddress())
|
||||
case EconvertFailure:
|
||||
return fmt.Sprintf("convert error: %s: %s", p.infoStr, p.FullAddress())
|
||||
case EinvalidIndex:
|
||||
// FIXME: better error message.
|
||||
return fmt.Sprintf("invalid index: %s: %s", p.infoStr, p.FullAddress())
|
||||
case EinvalidQuery:
|
||||
// FIXME: better error message.
|
||||
return fmt.Sprintf("invalid query: %s: %s", p.infoStr, p.FullAddress())
|
||||
case ErequiredType:
|
||||
return fmt.Sprintf("not required types: required=%s actual=%s: %s",
|
||||
p.expected.String(), p.actual.String(), p.FullAddress())
|
||||
default:
|
||||
return fmt.Sprintf("unexpected: %s", p.FullAddress())
|
||||
}
|
||||
}
|
||||
|
||||
func (p *errorProxy) ErrorType() ErrorType {
|
||||
return p.errorType
|
||||
}
|
||||
|
||||
func (p *errorProxy) FullAddress() string {
|
||||
return fullAddress(p)
|
||||
}
|
||||
|
||||
func typeError(p frame, expected Type, actual interface{}) *errorProxy {
|
||||
return &errorProxy{
|
||||
errorType: Etype,
|
||||
parent: p,
|
||||
expected: expected,
|
||||
actual: detectType(actual),
|
||||
}
|
||||
}
|
||||
|
||||
func requiredTypeError(p frame, expected Type, actual interface{}) *errorProxy {
|
||||
return &errorProxy{
|
||||
errorType: ErequiredType,
|
||||
parent: p,
|
||||
expected: expected,
|
||||
actual: detectType(actual),
|
||||
}
|
||||
}
|
||||
|
||||
func elementTypeError(p frame, index int, expected Type, actual interface{}) *errorProxy {
|
||||
q := &simpleFrame{
|
||||
parent: p,
|
||||
label: "[" + strconv.Itoa(index) + "]",
|
||||
}
|
||||
return typeError(q, expected, actual)
|
||||
}
|
||||
|
||||
func notfoundError(p frame, address string) *errorProxy {
|
||||
return &errorProxy{
|
||||
errorType: Enotfound,
|
||||
parent: p,
|
||||
label: address,
|
||||
}
|
||||
}
|
42
vendor/github.com/koron/go-dproxy/frame.go
generated
vendored
Normal file
42
vendor/github.com/koron/go-dproxy/frame.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package dproxy
|
||||
|
||||
type frame interface {
|
||||
// parentFrame returns parent frame.
|
||||
parentFrame() frame
|
||||
// frameLabel return label of frame.
|
||||
frameLabel() string
|
||||
}
|
||||
|
||||
func fullAddress(f frame) string {
|
||||
x := 0
|
||||
for g := f; g != nil; g = g.parentFrame() {
|
||||
x += len(g.frameLabel())
|
||||
}
|
||||
if x == 0 {
|
||||
return "(root)"
|
||||
}
|
||||
b := make([]byte, x)
|
||||
for g := f; g != nil; g = g.parentFrame() {
|
||||
x -= len(g.frameLabel())
|
||||
copy(b[x:], g.frameLabel())
|
||||
}
|
||||
if b[0] == '.' {
|
||||
return string(b[1:])
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
type simpleFrame struct {
|
||||
parent frame
|
||||
label string
|
||||
}
|
||||
|
||||
var _ frame = (*simpleFrame)(nil)
|
||||
|
||||
func (f *simpleFrame) parentFrame() frame {
|
||||
return f.parent
|
||||
}
|
||||
|
||||
func (f *simpleFrame) frameLabel() string {
|
||||
return f.label
|
||||
}
|
3
vendor/github.com/koron/go-dproxy/go.mod
generated
vendored
Normal file
3
vendor/github.com/koron/go-dproxy/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/koron/go-dproxy
|
||||
|
||||
go 1.13
|
0
vendor/github.com/koron/go-dproxy/go.sum
generated
vendored
Normal file
0
vendor/github.com/koron/go-dproxy/go.sum
generated
vendored
Normal file
31
vendor/github.com/koron/go-dproxy/pointer.go
generated
vendored
Normal file
31
vendor/github.com/koron/go-dproxy/pointer.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package dproxy
|
||||
|
||||
import "strings"
|
||||
|
||||
var jptR = strings.NewReplacer("~1", "/", "~0", "~")
|
||||
|
||||
func unescapeJPT(t string) string {
|
||||
return jptR.Replace(t)
|
||||
}
|
||||
|
||||
func pointer(p Proxy, q string) Proxy {
|
||||
if len(q) == 0 {
|
||||
return p
|
||||
}
|
||||
if q[0] != '/' {
|
||||
return &errorProxy{
|
||||
errorType: EinvalidQuery,
|
||||
parent: p,
|
||||
infoStr: "not start with '/'",
|
||||
}
|
||||
}
|
||||
for _, t := range strings.Split(q[1:], "/") {
|
||||
p = p.findJPT(unescapeJPT(t))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Pointer returns a Proxy which pointed by JSON Pointer's query q
|
||||
func Pointer(v interface{}, q string) Proxy {
|
||||
return pointer(New(v), q)
|
||||
}
|
102
vendor/github.com/koron/go-dproxy/proxy.go
generated
vendored
Normal file
102
vendor/github.com/koron/go-dproxy/proxy.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package dproxy
|
||||
|
||||
// Proxy is a proxy to access a document (interface{}).
|
||||
type Proxy interface {
|
||||
// Nil returns true, if target value is nil.
|
||||
Nil() bool
|
||||
|
||||
// Value returns a proxied value. If there are no values, it returns
|
||||
// error.
|
||||
Value() (interface{}, error)
|
||||
|
||||
// Bool returns its value. If value isn't the type, it returns error.
|
||||
Bool() (bool, error)
|
||||
|
||||
// Int64 returns its value. If value isn't the type, it returns error.
|
||||
Int64() (int64, error)
|
||||
|
||||
// Float64 returns its value. If value isn't the type, it returns error.
|
||||
Float64() (float64, error)
|
||||
|
||||
// String returns its value. If value isn't the type, it returns error.
|
||||
String() (string, error)
|
||||
|
||||
// Array returns its value. If value isn't the type, it returns error.
|
||||
Array() ([]interface{}, error)
|
||||
|
||||
// Map returns its value. If value isn't the type, it returns error.
|
||||
Map() (map[string]interface{}, error)
|
||||
|
||||
// A returns an item from value treated as the array.
|
||||
A(n int) Proxy
|
||||
|
||||
// M returns an item from value treated as the map.
|
||||
M(k string) Proxy
|
||||
|
||||
// P returns which pointed by JSON Pointer's query q.
|
||||
P(q string) Proxy
|
||||
|
||||
// ProxySet returns a set which converted from its array value.
|
||||
ProxySet() ProxySet
|
||||
|
||||
// Q returns set of all items which property matchs with k.
|
||||
Q(k string) ProxySet
|
||||
|
||||
// findJPT returns a match of JSON Pointer's Token t.
|
||||
findJPT(t string) Proxy
|
||||
|
||||
// Proxy implements frame.
|
||||
frame
|
||||
}
|
||||
|
||||
// ProxySet proxies to access to set.
|
||||
type ProxySet interface {
|
||||
// Empty returns true when the set is empty.
|
||||
Empty() bool
|
||||
|
||||
// Len returns count of items in the set.
|
||||
Len() int
|
||||
|
||||
// BoolArray returns []bool which converterd from the set.
|
||||
BoolArray() ([]bool, error)
|
||||
|
||||
// Int64Array returns []int64 which converterd from the set.
|
||||
Int64Array() ([]int64, error)
|
||||
|
||||
// Float64Array returns []float64 which converterd from the set.
|
||||
Float64Array() ([]float64, error)
|
||||
|
||||
// StringArray returns []string which converterd from the set.
|
||||
StringArray() ([]string, error)
|
||||
|
||||
// ArrayArray returns [][]interface{} which converterd from the set.
|
||||
ArrayArray() ([][]interface{}, error)
|
||||
|
||||
// MapArray returns []map[string]interface{} which converterd from the set.
|
||||
MapArray() ([]map[string]interface{}, error)
|
||||
|
||||
// ProxyArray returns []Proxy which wrap each items.
|
||||
ProxyArray() ([]Proxy, error)
|
||||
|
||||
// A returns an proxy for index in the set.
|
||||
A(n int) Proxy
|
||||
|
||||
// Q returns set of all items which property matchs with k.
|
||||
Q(k string) ProxySet
|
||||
|
||||
// Qc returns set of property of all items.
|
||||
Qc(k string) ProxySet
|
||||
|
||||
// Proxy implements frame.
|
||||
frame
|
||||
}
|
||||
|
||||
// New creates a new Proxy instance for v.
|
||||
func New(v interface{}) Proxy {
|
||||
return &valueProxy{value: v}
|
||||
}
|
||||
|
||||
// NewSet create a new ProxySet instance for v.
|
||||
func NewSet(v []interface{}) ProxySet {
|
||||
return &setProxy{values: v}
|
||||
}
|
193
vendor/github.com/koron/go-dproxy/set.go
generated
vendored
Normal file
193
vendor/github.com/koron/go-dproxy/set.go
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
package dproxy
|
||||
|
||||
import "strconv"
|
||||
|
||||
type setProxy struct {
|
||||
values []interface{}
|
||||
parent frame
|
||||
label string
|
||||
}
|
||||
|
||||
// setProxy implements ProxySet
|
||||
var _ ProxySet = (*setProxy)(nil)
|
||||
|
||||
func (p *setProxy) Empty() bool {
|
||||
return p.Len() == 0
|
||||
}
|
||||
|
||||
func (p *setProxy) Len() int {
|
||||
return len(p.values)
|
||||
}
|
||||
|
||||
func (p *setProxy) BoolArray() ([]bool, error) {
|
||||
r := make([]bool, len(p.values))
|
||||
for i, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case bool:
|
||||
r[i] = v
|
||||
default:
|
||||
return nil, elementTypeError(p, i, Tbool, v)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) Int64Array() ([]int64, error) {
|
||||
r := make([]int64, len(p.values))
|
||||
for i, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case int:
|
||||
r[i] = int64(v)
|
||||
case int32:
|
||||
r[i] = int64(v)
|
||||
case int64:
|
||||
r[i] = v
|
||||
case float32:
|
||||
r[i] = int64(v)
|
||||
case float64:
|
||||
r[i] = int64(v)
|
||||
default:
|
||||
return nil, elementTypeError(p, i, Tint64, v)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) Float64Array() ([]float64, error) {
|
||||
r := make([]float64, len(p.values))
|
||||
for i, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case int:
|
||||
r[i] = float64(v)
|
||||
case int32:
|
||||
r[i] = float64(v)
|
||||
case int64:
|
||||
r[i] = float64(v)
|
||||
case float32:
|
||||
r[i] = float64(v)
|
||||
case float64:
|
||||
r[i] = v
|
||||
default:
|
||||
return nil, elementTypeError(p, i, Tfloat64, v)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) StringArray() ([]string, error) {
|
||||
r := make([]string, len(p.values))
|
||||
for i, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
r[i] = v
|
||||
default:
|
||||
return nil, elementTypeError(p, i, Tstring, v)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) ArrayArray() ([][]interface{}, error) {
|
||||
r := make([][]interface{}, len(p.values))
|
||||
for i, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case []interface{}:
|
||||
r[i] = v
|
||||
default:
|
||||
return nil, elementTypeError(p, i, Tarray, v)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) MapArray() ([]map[string]interface{}, error) {
|
||||
r := make([]map[string]interface{}, len(p.values))
|
||||
for i, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case map[string]interface{}:
|
||||
r[i] = v
|
||||
default:
|
||||
return nil, elementTypeError(p, i, Tmap, v)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) ProxyArray() ([]Proxy, error) {
|
||||
r := make([]Proxy, 0, len(p.values))
|
||||
for i, v := range p.values {
|
||||
r = append(r, &valueProxy{
|
||||
value: v,
|
||||
parent: p,
|
||||
label: "[" + strconv.Itoa(i) + "]",
|
||||
})
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (p *setProxy) A(n int) Proxy {
|
||||
a := "[" + strconv.Itoa(n) + "]"
|
||||
if n < 0 || n >= len(p.values) {
|
||||
return notfoundError(p, a)
|
||||
}
|
||||
return &valueProxy{
|
||||
value: p.values[n],
|
||||
parent: p,
|
||||
label: a,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *setProxy) Q(k string) ProxySet {
|
||||
w := findAll(p.values, k)
|
||||
return &setProxy{
|
||||
values: w,
|
||||
parent: p,
|
||||
label: ".." + k,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *setProxy) Qc(k string) ProxySet {
|
||||
r := make([]interface{}, 0, len(p.values))
|
||||
for _, v := range p.values {
|
||||
switch v := v.(type) {
|
||||
case map[string]interface{}:
|
||||
if w, ok := v[k]; ok {
|
||||
r = append(r, w)
|
||||
}
|
||||
}
|
||||
}
|
||||
return &setProxy{
|
||||
values: r,
|
||||
parent: p,
|
||||
label: ".." + k,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *setProxy) parentFrame() frame {
|
||||
return p.parent
|
||||
}
|
||||
|
||||
func (p *setProxy) frameLabel() string {
|
||||
return p.label
|
||||
}
|
||||
|
||||
func findAll(v interface{}, k string) []interface{} {
|
||||
return findAllImpl(v, k, make([]interface{}, 0, 10))
|
||||
}
|
||||
|
||||
func findAllImpl(v interface{}, k string, r []interface{}) []interface{} {
|
||||
switch v := v.(type) {
|
||||
case map[string]interface{}:
|
||||
for n, w := range v {
|
||||
if n == k {
|
||||
r = append(r, w)
|
||||
}
|
||||
r = findAllImpl(w, k, r)
|
||||
}
|
||||
case []interface{}:
|
||||
for _, w := range v {
|
||||
r = findAllImpl(w, k, r)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
76
vendor/github.com/koron/go-dproxy/type.go
generated
vendored
Normal file
76
vendor/github.com/koron/go-dproxy/type.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package dproxy
|
||||
|
||||
// Type is type of value.
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// Tunknown shows value is not supported.
|
||||
Tunknown Type = iota
|
||||
|
||||
// Tnil shows value is nil.
|
||||
Tnil
|
||||
|
||||
// Tbool shows value is bool.
|
||||
Tbool
|
||||
|
||||
// Tint64 shows value is int64.
|
||||
Tint64
|
||||
|
||||
// Tfloat64 shows value is float64.
|
||||
Tfloat64
|
||||
|
||||
// Tstring shows value is string.
|
||||
Tstring
|
||||
|
||||
// Tarray shows value is an array ([]interface{})
|
||||
Tarray
|
||||
|
||||
// Tmap shows value is a map (map[string]interface{})
|
||||
Tmap
|
||||
)
|
||||
|
||||
// detectType returns type of a value.
|
||||
func detectType(v interface{}) Type {
|
||||
if v == nil {
|
||||
return Tnil
|
||||
}
|
||||
switch v.(type) {
|
||||
case bool:
|
||||
return Tbool
|
||||
case int, int32, int64:
|
||||
return Tint64
|
||||
case float32, float64:
|
||||
return Tfloat64
|
||||
case string:
|
||||
return Tstring
|
||||
case []interface{}:
|
||||
return Tarray
|
||||
case map[string]interface{}:
|
||||
return Tmap
|
||||
default:
|
||||
return Tunknown
|
||||
}
|
||||
}
|
||||
|
||||
func (t Type) String() string {
|
||||
switch t {
|
||||
case Tunknown:
|
||||
return "unknown"
|
||||
case Tnil:
|
||||
return "nil"
|
||||
case Tbool:
|
||||
return "bool"
|
||||
case Tint64:
|
||||
return "int64"
|
||||
case Tfloat64:
|
||||
return "float64"
|
||||
case Tstring:
|
||||
return "string"
|
||||
case Tarray:
|
||||
return "array"
|
||||
case Tmap:
|
||||
return "map"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
222
vendor/github.com/koron/go-dproxy/value.go
generated
vendored
Normal file
222
vendor/github.com/koron/go-dproxy/value.go
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
package dproxy
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type valueProxy struct {
|
||||
value interface{}
|
||||
parent frame
|
||||
label string
|
||||
}
|
||||
|
||||
// valueProxy implements Proxy.
|
||||
var _ Proxy = (*valueProxy)(nil)
|
||||
|
||||
func (p *valueProxy) Nil() bool {
|
||||
return p.value == nil
|
||||
}
|
||||
|
||||
func (p *valueProxy) Value() (interface{}, error) {
|
||||
return p.value, nil
|
||||
}
|
||||
|
||||
func (p *valueProxy) Bool() (bool, error) {
|
||||
switch v := p.value.(type) {
|
||||
case bool:
|
||||
return v, nil
|
||||
default:
|
||||
return false, typeError(p, Tbool, v)
|
||||
}
|
||||
}
|
||||
|
||||
type int64er interface {
|
||||
Int64() (int64, error)
|
||||
}
|
||||
|
||||
func (p *valueProxy) Int64() (int64, error) {
|
||||
switch v := p.value.(type) {
|
||||
case int:
|
||||
return int64(v), nil
|
||||
case int32:
|
||||
return int64(v), nil
|
||||
case int64:
|
||||
return v, nil
|
||||
case float32:
|
||||
return int64(v), nil
|
||||
case float64:
|
||||
return int64(v), nil
|
||||
case int64er:
|
||||
w, err := v.Int64()
|
||||
if err != nil {
|
||||
return 0, &errorProxy{
|
||||
errorType: EconvertFailure,
|
||||
parent: p,
|
||||
infoStr: err.Error(),
|
||||
}
|
||||
}
|
||||
return w, nil
|
||||
default:
|
||||
return 0, typeError(p, Tint64, v)
|
||||
}
|
||||
}
|
||||
|
||||
type float64er interface {
|
||||
Float64() (float64, error)
|
||||
}
|
||||
|
||||
func (p *valueProxy) Float64() (float64, error) {
|
||||
switch v := p.value.(type) {
|
||||
case int:
|
||||
return float64(v), nil
|
||||
case int32:
|
||||
return float64(v), nil
|
||||
case int64:
|
||||
return float64(v), nil
|
||||
case float32:
|
||||
return float64(v), nil
|
||||
case float64:
|
||||
return v, nil
|
||||
case float64er:
|
||||
w, err := v.Float64()
|
||||
if err != nil {
|
||||
return 0, &errorProxy{
|
||||
errorType: EconvertFailure,
|
||||
parent: p,
|
||||
infoStr: err.Error(),
|
||||
}
|
||||
}
|
||||
return w, nil
|
||||
default:
|
||||
return 0, typeError(p, Tfloat64, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) String() (string, error) {
|
||||
switch v := p.value.(type) {
|
||||
case string:
|
||||
return v, nil
|
||||
default:
|
||||
return "", typeError(p, Tstring, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) Array() ([]interface{}, error) {
|
||||
switch v := p.value.(type) {
|
||||
case []interface{}:
|
||||
return v, nil
|
||||
default:
|
||||
return nil, typeError(p, Tarray, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) Map() (map[string]interface{}, error) {
|
||||
switch v := p.value.(type) {
|
||||
case map[string]interface{}:
|
||||
return v, nil
|
||||
default:
|
||||
return nil, typeError(p, Tmap, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) A(n int) Proxy {
|
||||
switch v := p.value.(type) {
|
||||
case []interface{}:
|
||||
a := "[" + strconv.Itoa(n) + "]"
|
||||
if n < 0 || n >= len(v) {
|
||||
return notfoundError(p, a)
|
||||
}
|
||||
return &valueProxy{
|
||||
value: v[n],
|
||||
parent: p,
|
||||
label: a,
|
||||
}
|
||||
default:
|
||||
return requiredTypeError(p, Tarray, v)
|
||||
}
|
||||
}
|
||||
|
||||
var mapType = reflect.TypeOf(map[string]interface{}(nil))
|
||||
|
||||
func (p *valueProxy) m(v map[string]interface{}, k string) Proxy {
|
||||
a := "." + k
|
||||
w, ok := v[k]
|
||||
if !ok {
|
||||
return notfoundError(p, a)
|
||||
}
|
||||
return &valueProxy{
|
||||
value: w,
|
||||
parent: p,
|
||||
label: a,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) M(k string) Proxy {
|
||||
if v, ok := p.value.(map[string]interface{}); ok {
|
||||
return p.m(v, k)
|
||||
}
|
||||
|
||||
if rv := reflect.ValueOf(p.value); rv.IsValid() && rv.Type().ConvertibleTo(mapType) {
|
||||
v, _ := rv.Convert(mapType).Interface().(map[string]interface{})
|
||||
return p.m(v, k)
|
||||
}
|
||||
|
||||
return requiredTypeError(p, Tmap, p.value)
|
||||
}
|
||||
|
||||
func (p *valueProxy) P(q string) Proxy {
|
||||
return pointer(p, q)
|
||||
}
|
||||
|
||||
func (p *valueProxy) ProxySet() ProxySet {
|
||||
switch v := p.value.(type) {
|
||||
case []interface{}:
|
||||
return &setProxy{
|
||||
values: v,
|
||||
parent: p,
|
||||
}
|
||||
default:
|
||||
return typeError(p, Tarray, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) Q(k string) ProxySet {
|
||||
w := findAll(p.value, k)
|
||||
return &setProxy{
|
||||
values: w,
|
||||
parent: p,
|
||||
label: ".." + k,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) findJPT(t string) Proxy {
|
||||
switch v := p.value.(type) {
|
||||
case map[string]interface{}:
|
||||
return p.M(t)
|
||||
case []interface{}:
|
||||
n, err := strconv.ParseUint(t, 10, 0)
|
||||
if err != nil {
|
||||
return &errorProxy{
|
||||
errorType: EinvalidIndex,
|
||||
parent: p,
|
||||
infoStr: err.Error(),
|
||||
}
|
||||
}
|
||||
return p.A(int(n))
|
||||
default:
|
||||
return &errorProxy{
|
||||
errorType: EmapNorArray,
|
||||
parent: p,
|
||||
actual: detectType(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *valueProxy) parentFrame() frame {
|
||||
return p.parent
|
||||
}
|
||||
|
||||
func (p *valueProxy) frameLabel() string {
|
||||
return p.label
|
||||
}
|
Reference in New Issue
Block a user