forked from github/multus-cni
* 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>
254 lines
5.1 KiB
Go
254 lines
5.1 KiB
Go
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,
|
|
}
|
|
}
|