Compare commits
31 Commits
0.4.0
...
release-0.
Author | SHA1 | Date | |
---|---|---|---|
|
01bf238799 | ||
|
37a5aef6ea | ||
|
5424c5eb55 | ||
|
213688fd7d | ||
|
3eaacc01ae | ||
|
e20d13ace0 | ||
|
0ddeea3d78 | ||
|
bbc4fe30a6 | ||
|
7291a3bd71 | ||
|
826593d6ba | ||
|
6491d7b87f | ||
|
d04da92a23 | ||
|
fc741bf444 | ||
|
8afe1bea53 | ||
|
112772d02d | ||
|
a385f1ac82 | ||
|
1f19133ea8 | ||
|
7985ed5091 | ||
|
19c13b7401 | ||
|
3e6818d0b3 | ||
|
8cadff2b79 | ||
|
6862274e8e | ||
|
a02542b529 | ||
|
7dbbf52e1c | ||
|
9a9131d965 | ||
|
a6d50a8046 | ||
|
d47bb4f587 | ||
|
206b078c5f | ||
|
7c5f9ecc40 | ||
|
69fb81bcd3 | ||
|
c00cf69b55 |
34
.github/workflows/ci.yml
vendored
34
.github/workflows/ci.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
tags:
|
||||
- "*"
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
@@ -20,7 +19,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Vendor
|
||||
run: |
|
||||
make vendor
|
||||
@@ -33,10 +32,23 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Build
|
||||
run: make
|
||||
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.18
|
||||
- name: Build docs
|
||||
run: |
|
||||
make gen-docs
|
||||
git diff --exit-code
|
||||
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -44,7 +56,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Build kg and kgctl for all Linux Architectures
|
||||
run: make all-build
|
||||
|
||||
@@ -55,7 +67,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Build kgctl for Darwin amd64
|
||||
run: make OS=darwin ARCH=amd64
|
||||
- name: Build kgctl for Darwin arm64
|
||||
@@ -68,7 +80,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Build kgctl for Windows
|
||||
run: make OS=windows
|
||||
|
||||
@@ -79,7 +91,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Run Unit Tests
|
||||
run: make unit
|
||||
|
||||
@@ -91,7 +103,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Run e2e Tests
|
||||
run: make e2e
|
||||
|
||||
@@ -102,7 +114,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Lint Code
|
||||
run: make lint
|
||||
|
||||
@@ -113,7 +125,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Enable Experimental Docker CLI
|
||||
run: |
|
||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
||||
@@ -143,7 +155,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
go-version: 1.18
|
||||
- name: Enable Experimental Docker CLI
|
||||
run: |
|
||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
||||
|
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
@@ -3,15 +3,15 @@ on:
|
||||
types: [created]
|
||||
name: Handle Release
|
||||
jobs:
|
||||
linux:
|
||||
kgctl:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.1
|
||||
- name: Make Directory with kgctl Binaries to Be Released
|
||||
go-version: 1.18
|
||||
- name: Build kgctl Binaries to Be Released
|
||||
run: make release
|
||||
- name: Publish Release
|
||||
uses: skx/github-action-publish-binaries@master
|
||||
|
@@ -1,7 +1,7 @@
|
||||
ARG FROM=alpine
|
||||
FROM $FROM AS cni
|
||||
ARG GOARCH=amd64
|
||||
ARG CNI_PLUGINS_VERSION=v0.9.1
|
||||
ARG CNI_PLUGINS_VERSION=v1.1.1
|
||||
RUN apk add --no-cache curl && \
|
||||
curl -Lo cni.tar.gz https://github.com/containernetworking/plugins/releases/download/$CNI_PLUGINS_VERSION/cni-plugins-linux-$GOARCH-$CNI_PLUGINS_VERSION.tgz && \
|
||||
tar -xf cni.tar.gz
|
||||
@@ -13,5 +13,7 @@ LABEL maintainer="squat <lserven@gmail.com>"
|
||||
RUN echo -e "https://alpine.global.ssl.fastly.net/alpine/$ALPINE_VERSION/main\nhttps://alpine.global.ssl.fastly.net/alpine/$ALPINE_VERSION/community" > /etc/apk/repositories && \
|
||||
apk add --no-cache ipset iptables ip6tables graphviz font-noto
|
||||
COPY --from=cni bridge host-local loopback portmap /opt/cni/bin/
|
||||
ADD https://raw.githubusercontent.com/kubernetes-sigs/iptables-wrappers/e139a115350974aac8a82ec4b815d2845f86997e/iptables-wrapper-installer.sh /
|
||||
RUN chmod 700 /iptables-wrapper-installer.sh && /iptables-wrapper-installer.sh --no-sanity-check
|
||||
COPY bin/linux/$GOARCH/kg /opt/bin/
|
||||
ENTRYPOINT ["/opt/bin/kg"]
|
||||
|
8
Makefile
8
Makefile
@@ -45,8 +45,8 @@ KUBECTL_BINARY := $(shell pwd)/bin/kubectl
|
||||
BASH_UNIT := $(shell pwd)/bin/bash_unit
|
||||
BASH_UNIT_FLAGS :=
|
||||
|
||||
BUILD_IMAGE ?= golang:1.17.1-alpine3.14
|
||||
BASE_IMAGE ?= alpine:3.14
|
||||
BUILD_IMAGE ?= golang:1.18
|
||||
BASE_IMAGE ?= alpine:3.15
|
||||
|
||||
build: $(BINS)
|
||||
|
||||
@@ -81,7 +81,7 @@ crd: manifests/crds.yaml
|
||||
manifests/crds.yaml: pkg/k8s/apis/kilo/v1alpha1/types.go $(CONTROLLER_GEN_BINARY)
|
||||
$(CONTROLLER_GEN_BINARY) crd \
|
||||
paths=./pkg/k8s/apis/kilo/... \
|
||||
output:crd:stdout | tail -n +3 > $@
|
||||
output:crd:stdout > $@
|
||||
|
||||
client: pkg/k8s/clientset/versioned/typed/kilo/v1alpha1/peer.go
|
||||
pkg/k8s/clientset/versioned/typed/kilo/v1alpha1/peer.go: .header pkg/k8s/apis/kilo/v1alpha1/types.go $(CLIENT_GEN_BINARY)
|
||||
@@ -139,7 +139,7 @@ pkg/k8s/listers/kilo/v1alpha1/peer.go: .header pkg/k8s/apis/kilo/v1alpha1/types.
|
||||
rm -r github.com || true
|
||||
go fmt ./pkg/k8s/listers/...
|
||||
|
||||
gen-docs: generate docs/api.md
|
||||
gen-docs: generate docs/api.md docs/kg.md
|
||||
docs/api.md: pkg/k8s/apis/kilo/v1alpha1/types.go $(DOCS_GEN_BINARY)
|
||||
$(DOCS_GEN_BINARY) $< > $@
|
||||
|
||||
|
@@ -27,10 +27,10 @@ import (
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
"github.com/metalmatze/signal/internalserver"
|
||||
"github.com/oklog/run"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/spf13/cobra"
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@@ -251,18 +251,21 @@ func runRoot(_ *cobra.Command, _ []string) error {
|
||||
|
||||
var g run.Group
|
||||
{
|
||||
h := internalserver.NewHandler(
|
||||
internalserver.WithName("Internal Kilo API"),
|
||||
internalserver.WithPrometheusRegistry(registry),
|
||||
internalserver.WithPProf(),
|
||||
)
|
||||
h.AddEndpoint("/health", "Exposes health checks", healthHandler)
|
||||
h.AddEndpoint("/graph", "Exposes Kilo mesh topology graph", (&graphHandler{m, gr, &hostname, s}).ServeHTTP)
|
||||
// Run the HTTP server.
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/health", healthHandler)
|
||||
mux.Handle("/graph", &graphHandler{m, gr, &hostname, s})
|
||||
mux.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))
|
||||
l, err := net.Listen("tcp", listen)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to listen on %s: %v", listen, err)
|
||||
}
|
||||
|
||||
g.Add(func() error {
|
||||
if err := http.Serve(l, mux); err != nil && err != http.ErrServerClosed {
|
||||
if err := http.Serve(l, h); err != nil && err != http.ErrServerClosed {
|
||||
return fmt.Errorf("error: server exited unexpectedly: %v", err)
|
||||
}
|
||||
return nil
|
||||
|
63
docs/kg.md
63
docs/kg.md
@@ -16,26 +16,45 @@ The behavior of `kg` can be configured using the command line flags listed below
|
||||
|
||||
[embedmd]:# (../tmp/help.txt)
|
||||
```txt
|
||||
Usage of bin//linux/amd64/kg:
|
||||
--backend string The backend for the mesh. Possible values: kubernetes (default "kubernetes")
|
||||
--clean-up-interface Should Kilo delete its interface when it shuts down?
|
||||
--cni Should Kilo manage the node's CNI configuration? (default true)
|
||||
--cni-path string Path to CNI config. (default "/etc/cni/net.d/10-kilo.conflist")
|
||||
--compatibility string Should Kilo run in compatibility mode? Possible values: flannel
|
||||
--create-interface Should kilo create an interface on startup? (default true)
|
||||
--encapsulate string When should Kilo encapsulate packets within a location? Possible values: never, crosssubnet, always (default "always")
|
||||
--hostname string Hostname of the node on which this process is running.
|
||||
--interface string Name of the Kilo interface to use; if it does not exist, it will be created. (default "kilo0")
|
||||
--kubeconfig string Path to kubeconfig.
|
||||
--listen string The address at which to listen for health and metrics. (default ":1107")
|
||||
--local Should Kilo manage routes within a location? (default true)
|
||||
--log-level string Log level to use. Possible values: all, debug, info, warn, error, none (default "info")
|
||||
--master string The address of the Kubernetes API server (overrides any value in kubeconfig).
|
||||
--mesh-granularity string The granularity of the network mesh to create. Possible values: location, full (default "location")
|
||||
--mtu uint The MTU of the WireGuard interface created by Kilo. (default 1420)
|
||||
--port uint The port over which WireGuard peers should communicate. (default 51820)
|
||||
--resync-period duration How often should the Kilo controllers reconcile? (default 30s)
|
||||
--subnet string CIDR from which to allocate addresses for WireGuard interfaces. (default "10.4.0.0/16")
|
||||
--topology-label string Kubernetes node label used to group nodes into logical locations. (default "topology.kubernetes.io/region")
|
||||
--version Print version and exit
|
||||
kg is the Kilo agent.
|
||||
It runs on every node of a cluster,
|
||||
setting up the public and private keys for the VPN
|
||||
as well as the necessary rules to route packets between locations.
|
||||
|
||||
Usage:
|
||||
kg [flags]
|
||||
kg [command]
|
||||
|
||||
Available Commands:
|
||||
completion generate the autocompletion script for the specified shell
|
||||
help Help about any command
|
||||
version Print the version and exit.
|
||||
webhook webhook starts a HTTPS server to validate updates and creations of Kilo peers.
|
||||
|
||||
Flags:
|
||||
--backend string The backend for the mesh. Possible values: kubernetes (default "kubernetes")
|
||||
--clean-up-interface Should Kilo delete its interface when it shuts down?
|
||||
--cni Should Kilo manage the node's CNI configuration? (default true)
|
||||
--cni-path string Path to CNI config. (default "/etc/cni/net.d/10-kilo.conflist")
|
||||
--compatibility string Should Kilo run in compatibility mode? Possible values: flannel
|
||||
--create-interface Should kilo create an interface on startup? (default true)
|
||||
--encapsulate string When should Kilo encapsulate packets within a location? Possible values: never, crosssubnet, always (default "always")
|
||||
-h, --help help for kg
|
||||
--hostname string Hostname of the node on which this process is running.
|
||||
--interface string Name of the Kilo interface to use; if it does not exist, it will be created. (default "kilo0")
|
||||
--iptables-forward-rules Add default accept rules to the FORWARD chain in iptables. Warning: this may break firewalls with a deny all policy and is potentially insecure!
|
||||
--kubeconfig string Path to kubeconfig.
|
||||
--listen string The address at which to listen for health and metrics. (default ":1107")
|
||||
--local Should Kilo manage routes within a location? (default true)
|
||||
--log-level string Log level to use. Possible values: all, debug, info, warn, error, none (default "info")
|
||||
--master string The address of the Kubernetes API server (overrides any value in kubeconfig).
|
||||
--mesh-granularity string The granularity of the network mesh to create. Possible values: location, full (default "location")
|
||||
--mtu uint The MTU of the WireGuard interface created by Kilo. (default 1420)
|
||||
--port int The port over which WireGuard peers should communicate. (default 51820)
|
||||
--prioritise-private-addresses Prefer to assign a private IP address to the node's endpoint.
|
||||
--resync-period duration How often should the Kilo controllers reconcile? (default 30s)
|
||||
--subnet string CIDR from which to allocate addresses for WireGuard interfaces. (default "10.4.0.0/16")
|
||||
--topology-label string Kubernetes node label used to group nodes into logical locations. (default "topology.kubernetes.io/region")
|
||||
--version Print version and exit
|
||||
|
||||
```
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
|
77
go.mod
77
go.mod
@@ -1,50 +1,50 @@
|
||||
module github.com/squat/kilo
|
||||
|
||||
go 1.17
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310
|
||||
github.com/campoy/embedmd v1.0.0
|
||||
github.com/containernetworking/cni v0.6.0
|
||||
github.com/containernetworking/plugins v0.6.0
|
||||
github.com/coreos/go-iptables v0.4.0
|
||||
github.com/containernetworking/cni v1.0.1
|
||||
github.com/containernetworking/plugins v1.1.1
|
||||
github.com/coreos/go-iptables v0.6.0
|
||||
github.com/go-kit/kit v0.9.0
|
||||
github.com/imdario/mergo v0.3.6 // indirect
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
|
||||
github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a
|
||||
github.com/oklog/run v1.1.0
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/spf13/cobra v1.1.3
|
||||
github.com/vishvananda/netlink v1.0.0
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20211124212657-dd7407c86d22
|
||||
k8s.io/api v0.21.1
|
||||
k8s.io/apiextensions-apiserver v0.21.1
|
||||
k8s.io/apimachinery v0.21.1
|
||||
k8s.io/client-go v0.21.1
|
||||
k8s.io/code-generator v0.21.1
|
||||
sigs.k8s.io/controller-tools v0.6.0
|
||||
k8s.io/api v0.23.6
|
||||
k8s.io/apiextensions-apiserver v0.23.6
|
||||
k8s.io/apimachinery v0.23.6
|
||||
k8s.io/client-go v0.23.6
|
||||
k8s.io/code-generator v0.23.6
|
||||
sigs.k8s.io/controller-tools v0.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||
github.com/fatih/color v1.12.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
||||
github.com/go-logr/logr v0.4.0 // indirect
|
||||
github.com/gobuffalo/flect v0.2.2 // indirect
|
||||
github.com/go-logr/logr v1.2.0 // indirect
|
||||
github.com/gobuffalo/flect v0.2.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/googleapis/gnostic v0.4.1 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.1 // indirect
|
||||
github.com/google/uuid v1.2.0 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
github.com/imdario/mergo v0.3.11 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
@@ -52,32 +52,35 @@ require (
|
||||
github.com/mdlayher/netlink v1.4.1 // indirect
|
||||
github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.26.0 // indirect
|
||||
github.com/prometheus/common v0.28.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
golang.org/x/tools v0.1.2 // indirect
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20211123210315-387f7c461a16 // indirect
|
||||
google.golang.org/appengine v1.6.5 // indirect
|
||||
google.golang.org/protobuf v1.26.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 // indirect
|
||||
k8s.io/klog/v2 v2.8.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 // indirect
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect
|
||||
k8s.io/klog/v2 v2.30.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
|
||||
k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
480
go.sum
480
go.sum
@@ -9,29 +9,47 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
@@ -42,23 +60,29 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310 h1:t+qxRrRtwNiUYA+Xh2jSXhoG2grnMCMKX4Fg6lx9X1U=
|
||||
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
|
||||
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -67,24 +91,27 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/containernetworking/cni v0.6.0 h1:FXICGBZNMtdHlW65trpoHviHctQD3seWhRRcqp2hMOU=
|
||||
github.com/containernetworking/cni v0.6.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/plugins v0.6.0 h1:bqPT7yYisnWs+FrtgY5/qLEB9QZ/6z11wMNCwSdzZm0=
|
||||
github.com/containernetworking/plugins v0.6.0/go.mod h1:dagHaAhNjXjT9QYOklkKJDGaQPTg4pf//FrUcJeb7FU=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||
github.com/containernetworking/cni v1.0.1 h1:9OIL/sZmMYDBe+G8svzILAlulUpaDTUjeAbtH/JNLBo=
|
||||
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
|
||||
github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE=
|
||||
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-iptables v0.4.0 h1:wh4UbVs8DhLUbpyq97GLJDKrQMjEDD63T1xE4CrsKzQ=
|
||||
github.com/coreos/go-iptables v0.4.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
|
||||
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -93,23 +120,32 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -124,42 +160,46 @@ github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobuffalo/flect v0.2.2 h1:PAVD7sp0KOdfswjAw9BpLCU9hXo7wFSzgpQ+zNeks/A=
|
||||
github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
|
||||
github.com/gobuffalo/flect v0.2.3 h1:f/ZukRnSNA/DUpSNDadko7Qc0PhGvsew35p/2tu+CRY=
|
||||
github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@@ -169,16 +209,23 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w=
|
||||
github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
@@ -187,29 +234,37 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -224,7 +279,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
@@ -233,12 +287,15 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
@@ -252,43 +309,44 @@ github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190 h1:iycCSDo8EKVueI9sfVBBJmtNn9DnXV/K1YWwEJO+uOs=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@@ -310,6 +368,8 @@ github.com/mdlayher/netlink v1.4.1/go.mod h1:e4/KuJ+s8UhfUpO9z00/fDZZmhSrs+oxyqA
|
||||
github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc=
|
||||
github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb h1:2dC7L10LmTqlyMVzFJ00qM25lqESg9Z4u3GuEXN5iHY=
|
||||
github.com/mdlayher/socket v0.0.0-20211102153432-57e3fa563ecb/go.mod h1:nFZ1EtZYK8Gi/k6QNu7z7CgO20i/4ExeQswwWuPmG/g=
|
||||
github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQovz3p+BiQ81Jy845xSMu2CWKuXsXuUM=
|
||||
github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a/go.mod h1:3OETvrxfELvGsU2RoGGWercfeZ4bCL3+SOwzIWtJH/Q=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
@@ -321,14 +381,16 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
@@ -338,31 +400,29 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
|
||||
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
@@ -370,6 +430,7 @@ github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prY
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
@@ -381,88 +442,125 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.28.0 h1:vGVfV9KrDTvWt5boZO0I19g2E3CsWfpPPKZM9dt3mEw=
|
||||
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 h1:ZFfeKAhIQiiOrQaI3/znw0gOmYpO28Tcu1YaqMa/jtQ=
|
||||
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
|
||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 h1:+UB2BJA852UkGH42H+Oee69djmxS3ANzl2b/JtT1YiA=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
|
||||
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
|
||||
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
|
||||
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
|
||||
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
|
||||
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
|
||||
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
|
||||
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
|
||||
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
@@ -487,8 +585,10 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
@@ -497,7 +597,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -516,8 +617,8 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -527,36 +628,58 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -575,7 +698,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -593,56 +715,76 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
@@ -653,13 +795,13 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@@ -675,14 +817,30 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff h1:VX/uD7MK0AHXGiScH3fsieUQUcpmRERPDYtqZdJnA+Q=
|
||||
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -703,13 +861,27 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@@ -727,16 +899,56 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -748,20 +960,21 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
@@ -770,6 +983,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -777,6 +991,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
@@ -787,38 +1002,41 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c=
|
||||
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
|
||||
k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo=
|
||||
k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA=
|
||||
k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs=
|
||||
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY=
|
||||
k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4=
|
||||
k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
|
||||
k8s.io/code-generator v0.21.1 h1:jvcxHpVu5dm/LMXr3GOj/jroiP8+v2YnJE9i2OVRenk=
|
||||
k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
|
||||
k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.23.6 h1:yOK34wbYECH4RsJbQ9sfkFK3O7f/DUHRlzFehkqZyVw=
|
||||
k8s.io/api v0.23.6/go.mod h1:1kFaYxGCFHYp3qd6a85DAj/yW8aVD6XLZMqJclkoi9g=
|
||||
k8s.io/apiextensions-apiserver v0.23.6 h1:v58cQ6Z0/GK1IXYr+oW0fnYl52o9LTY0WgoWvI8uv5Q=
|
||||
k8s.io/apiextensions-apiserver v0.23.6/go.mod h1:YVh17Mphv183THQJA5spNFp9XfoidFyL3WoDgZxQIZU=
|
||||
k8s.io/apimachinery v0.23.6 h1:RH1UweWJkWNTlFx0D8uxOpaU1tjIOvVVWV/bu5b3/NQ=
|
||||
k8s.io/apimachinery v0.23.6/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
|
||||
k8s.io/apiserver v0.23.6/go.mod h1:5PU32F82tfErXPmf7FXhd/UcuLfh97tGepjKUgJ2atg=
|
||||
k8s.io/client-go v0.23.6 h1:7h4SctDVQAQbkHQnR4Kzi7EyUyvla5G1pFWf4+Od7hQ=
|
||||
k8s.io/client-go v0.23.6/go.mod h1:Umt5icFOMLV/+qbtZ3PR0D+JA6lvvb3syzodv4irpK4=
|
||||
k8s.io/code-generator v0.23.6 h1:4J4zL5TU7e96kjGvr5LOFsgR1P9ZU/C6EQeGYcNrFvw=
|
||||
k8s.io/code-generator v0.23.6/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
|
||||
k8s.io/component-base v0.23.6/go.mod h1:FGMPeMrjYu0UZBSAFcfloVDplj9IvU+uRMTOdE23Fj0=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
|
||||
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE=
|
||||
k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/controller-tools v0.6.0 h1:o2Fm1K7CmIp8OVaBtXsWB/ssBAzyoKZPPAGR3VuxaKs=
|
||||
sigs.k8s.io/controller-tools v0.6.0/go.mod h1:baRMVPrctU77F+rfAuH2uPqW93k6yQnZA2dhUOr7ihc=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
|
||||
sigs.k8s.io/controller-tools v0.8.0 h1:uUkfTGEwrguqYYfcI2RRGUnC8mYdCFDqfwPKUcNJh1o=
|
||||
sigs.k8s.io/controller-tools v0.8.0/go.mod h1:qE2DXhVOiEq5ijmINcFbqi9GZrrUjzB1TuJU0xa6eoY=
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
@@ -1,8 +1,9 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.0
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
creationTimestamp: null
|
||||
name: peers.kilo.squat.ai
|
||||
spec:
|
||||
|
@@ -67,7 +67,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -101,7 +101,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -131,7 +131,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
|
@@ -96,7 +96,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -127,7 +127,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: generate-kubeconfig
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
args:
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -133,7 +133,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -164,7 +164,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: generate-kubeconfig
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
args:
|
||||
@@ -185,7 +185,7 @@ spec:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
@@ -264,7 +264,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -311,7 +311,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: generate-kubeconfig
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
args:
|
||||
@@ -332,7 +332,7 @@ spec:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
@@ -428,7 +428,7 @@ spec:
|
||||
readOnly: true
|
||||
initContainers:
|
||||
- name: generate-kubeconfig
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
args:
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -131,7 +131,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -178,7 +178,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: generate-kubeconfig
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
args:
|
||||
@@ -199,7 +199,7 @@ spec:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -130,7 +130,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -160,7 +160,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: generate-kubeconfig
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
args:
|
||||
@@ -181,7 +181,7 @@ spec:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
|
@@ -79,7 +79,7 @@ spec:
|
||||
mountPath: /var/run/wireguard
|
||||
readOnly: false
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -139,4 +139,4 @@ spec:
|
||||
type: FileOrCreate
|
||||
- name: wireguard
|
||||
hostPath:
|
||||
path: /var/run/wireguard
|
||||
path: /var/run/wireguard
|
||||
|
@@ -67,7 +67,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -114,7 +114,7 @@ spec:
|
||||
mountPath: /var/run/wireguard
|
||||
readOnly: false
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
@@ -150,7 +150,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
@@ -204,4 +204,4 @@ spec:
|
||||
type: FileOrCreate
|
||||
- name: wireguard
|
||||
hostPath:
|
||||
path: /var/run/wireguard
|
||||
path: /var/run/wireguard
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -101,7 +101,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -131,7 +131,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
|
@@ -67,7 +67,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
|
@@ -8,7 +8,7 @@ metadata:
|
||||
data:
|
||||
cni-conf.json: |
|
||||
{
|
||||
"cniVersion":"0.3.1",
|
||||
"cniVersion":"0.4.0",
|
||||
"name":"kilo",
|
||||
"plugins":[
|
||||
{
|
||||
@@ -101,7 +101,7 @@ spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kilo
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- --kubeconfig=/etc/kubernetes/kubeconfig
|
||||
- --hostname=$(NODE_NAME)
|
||||
@@ -131,7 +131,7 @@ spec:
|
||||
readOnly: false
|
||||
initContainers:
|
||||
- name: install-cni
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
|
@@ -46,7 +46,7 @@ spec:
|
||||
runAsUser: 1000
|
||||
containers:
|
||||
- name: server
|
||||
image: squat/kilo
|
||||
image: squat/kilo:0.5.0
|
||||
args:
|
||||
- webhook
|
||||
- --cert-file=/run/secrets/tls/tls.crt
|
||||
|
@@ -18,6 +18,7 @@ package versioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
kilov1alpha1 "github.com/squat/kilo/pkg/k8s/clientset/versioned/typed/kilo/v1alpha1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
@@ -53,22 +54,45 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
|
||||
if configShallowCopy.UserAgent == "" {
|
||||
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
// share the transport between all clients
|
||||
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new Clientset for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfigAndClient will generate a rate-limiter in configShallowCopy.
|
||||
func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
if configShallowCopy.Burst <= 0 {
|
||||
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
}
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.kiloV1alpha1, err = kilov1alpha1.NewForConfig(&configShallowCopy)
|
||||
cs.kiloV1alpha1, err = kilov1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -78,11 +102,11 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.kiloV1alpha1 = kilov1alpha1.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
cs, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
|
@@ -72,7 +72,10 @@ func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
return c.tracker
|
||||
}
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
var (
|
||||
_ clientset.Interface = &Clientset{}
|
||||
_ testing.FakeClient = &Clientset{}
|
||||
)
|
||||
|
||||
// KiloV1alpha1 retrieves the KiloV1alpha1Client
|
||||
func (c *Clientset) KiloV1alpha1() kilov1alpha1.KiloV1alpha1Interface {
|
||||
|
@@ -97,7 +97,7 @@ func (c *FakePeers) Update(ctx context.Context, peer *v1alpha1.Peer, opts v1.Upd
|
||||
// Delete takes name of the peer and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePeers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(peersResource, name), &v1alpha1.Peer{})
|
||||
Invokes(testing.NewRootDeleteActionWithOptions(peersResource, name, opts), &v1alpha1.Peer{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,8 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
v1alpha1 "github.com/squat/kilo/pkg/k8s/apis/kilo/v1alpha1"
|
||||
"github.com/squat/kilo/pkg/k8s/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
@@ -37,12 +39,28 @@ func (c *KiloV1alpha1Client) Peers() PeerInterface {
|
||||
}
|
||||
|
||||
// NewForConfig creates a new KiloV1alpha1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
func NewForConfig(c *rest.Config) (*KiloV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
httpClient, err := rest.HTTPClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewForConfigAndClient(&config, httpClient)
|
||||
}
|
||||
|
||||
// NewForConfigAndClient creates a new KiloV1alpha1Client for the given config and http client.
|
||||
// Note the http client provided takes precedence over the configured transport values.
|
||||
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*KiloV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
570
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
570
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
@@ -14,15 +14,40 @@
|
||||
|
||||
package libcni
|
||||
|
||||
// Note this is the actual implementation of the CNI specification, which
|
||||
// is reflected in the https://github.com/containernetworking/cni/blob/master/SPEC.md file
|
||||
// it is typically bundled into runtime providers (i.e. containerd or cri-o would use this
|
||||
// before calling runc or hcsshim). It is also bundled into CNI providers as well, for example,
|
||||
// to add an IP to a container, to parse the configuration of the CNI and so on.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/create"
|
||||
"github.com/containernetworking/cni/pkg/utils"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
)
|
||||
|
||||
var (
|
||||
CacheDir = "/var/lib/cni"
|
||||
)
|
||||
|
||||
const (
|
||||
CNICacheV1 = "cniCacheV1"
|
||||
)
|
||||
|
||||
// A RuntimeConf holds the arguments to one invocation of a CNI plugin
|
||||
// excepting the network configuration, with the nested exception that
|
||||
// the `runtimeConfig` from the network configuration is included
|
||||
// here.
|
||||
type RuntimeConf struct {
|
||||
ContainerID string
|
||||
NetNS string
|
||||
@@ -34,6 +59,9 @@ type RuntimeConf struct {
|
||||
// in this map which match the capabilities of the plugin are passed
|
||||
// to the plugin
|
||||
CapabilityArgs map[string]interface{}
|
||||
|
||||
// DEPRECATED. Will be removed in a future release.
|
||||
CacheDir string
|
||||
}
|
||||
|
||||
type NetworkConfig struct {
|
||||
@@ -42,33 +70,64 @@ type NetworkConfig struct {
|
||||
}
|
||||
|
||||
type NetworkConfigList struct {
|
||||
Name string
|
||||
CNIVersion string
|
||||
Plugins []*NetworkConfig
|
||||
Bytes []byte
|
||||
Name string
|
||||
CNIVersion string
|
||||
DisableCheck bool
|
||||
Plugins []*NetworkConfig
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
type CNI interface {
|
||||
AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
||||
DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error
|
||||
AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
||||
CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
|
||||
DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
|
||||
GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
||||
GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
|
||||
|
||||
AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||
DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
|
||||
AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||
CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
|
||||
DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
|
||||
GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||
GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
|
||||
|
||||
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
|
||||
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
|
||||
}
|
||||
|
||||
type CNIConfig struct {
|
||||
Path []string
|
||||
Path []string
|
||||
exec invoke.Exec
|
||||
cacheDir string
|
||||
}
|
||||
|
||||
// CNIConfig implements the CNI interface
|
||||
var _ CNI = &CNIConfig{}
|
||||
|
||||
func buildOneConfig(list *NetworkConfigList, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) {
|
||||
// NewCNIConfig returns a new CNIConfig object that will search for plugins
|
||||
// in the given paths and use the given exec interface to run those plugins,
|
||||
// or if the exec interface is not given, will use a default exec handler.
|
||||
func NewCNIConfig(path []string, exec invoke.Exec) *CNIConfig {
|
||||
return NewCNIConfigWithCacheDir(path, "", exec)
|
||||
}
|
||||
|
||||
// NewCNIConfigWithCacheDir returns a new CNIConfig object that will search for plugins
|
||||
// in the given paths use the given exec interface to run those plugins,
|
||||
// or if the exec interface is not given, will use a default exec handler.
|
||||
// The given cache directory will be used for temporary data storage when needed.
|
||||
func NewCNIConfigWithCacheDir(path []string, cacheDir string, exec invoke.Exec) *CNIConfig {
|
||||
return &CNIConfig{
|
||||
Path: path,
|
||||
cacheDir: cacheDir,
|
||||
exec: exec,
|
||||
}
|
||||
}
|
||||
|
||||
func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) {
|
||||
var err error
|
||||
|
||||
inject := map[string]interface{}{
|
||||
"name": list.Name,
|
||||
"cniVersion": list.CNIVersion,
|
||||
"name": name,
|
||||
"cniVersion": cniVersion,
|
||||
}
|
||||
// Add previous plugin result
|
||||
if prevResult != nil {
|
||||
@@ -92,7 +151,7 @@ func buildOneConfig(list *NetworkConfigList, orig *NetworkConfig, prevResult typ
|
||||
// These capabilities arguments are filtered through the plugin's advertised
|
||||
// capabilities from its config JSON, and any keys in the CapabilityArgs
|
||||
// matching plugin capabilities are added to the "runtimeConfig" dictionary
|
||||
// sent to the plugin via JSON on stdin. For exmaple, if the plugin's
|
||||
// sent to the plugin via JSON on stdin. For example, if the plugin's
|
||||
// capabilities include "portMappings", and the CapabilityArgs map includes a
|
||||
// "portMappings" key, that key and its value are added to the "runtimeConfig"
|
||||
// dictionary to be passed to the plugin's stdin.
|
||||
@@ -119,45 +178,295 @@ func injectRuntimeConfig(orig *NetworkConfig, rt *RuntimeConf) (*NetworkConfig,
|
||||
return orig, nil
|
||||
}
|
||||
|
||||
// ensure we have a usable exec if the CNIConfig was not given one
|
||||
func (c *CNIConfig) ensureExec() invoke.Exec {
|
||||
if c.exec == nil {
|
||||
c.exec = &invoke.DefaultExec{
|
||||
RawExec: &invoke.RawExec{Stderr: os.Stderr},
|
||||
PluginDecoder: version.PluginDecoder{},
|
||||
}
|
||||
}
|
||||
return c.exec
|
||||
}
|
||||
|
||||
type cachedInfo struct {
|
||||
Kind string `json:"kind"`
|
||||
ContainerID string `json:"containerId"`
|
||||
Config []byte `json:"config"`
|
||||
IfName string `json:"ifName"`
|
||||
NetworkName string `json:"networkName"`
|
||||
CniArgs [][2]string `json:"cniArgs,omitempty"`
|
||||
CapabilityArgs map[string]interface{} `json:"capabilityArgs,omitempty"`
|
||||
RawResult map[string]interface{} `json:"result,omitempty"`
|
||||
Result types.Result `json:"-"`
|
||||
}
|
||||
|
||||
// getCacheDir returns the cache directory in this order:
|
||||
// 1) global cacheDir from CNIConfig object
|
||||
// 2) deprecated cacheDir from RuntimeConf object
|
||||
// 3) fall back to default cache directory
|
||||
func (c *CNIConfig) getCacheDir(rt *RuntimeConf) string {
|
||||
if c.cacheDir != "" {
|
||||
return c.cacheDir
|
||||
}
|
||||
if rt.CacheDir != "" {
|
||||
return rt.CacheDir
|
||||
}
|
||||
return CacheDir
|
||||
}
|
||||
|
||||
func (c *CNIConfig) getCacheFilePath(netName string, rt *RuntimeConf) (string, error) {
|
||||
if netName == "" || rt.ContainerID == "" || rt.IfName == "" {
|
||||
return "", fmt.Errorf("cache file path requires network name (%q), container ID (%q), and interface name (%q)", netName, rt.ContainerID, rt.IfName)
|
||||
}
|
||||
return filepath.Join(c.getCacheDir(rt), "results", fmt.Sprintf("%s-%s-%s", netName, rt.ContainerID, rt.IfName)), nil
|
||||
}
|
||||
|
||||
func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string, rt *RuntimeConf) error {
|
||||
cached := cachedInfo{
|
||||
Kind: CNICacheV1,
|
||||
ContainerID: rt.ContainerID,
|
||||
Config: config,
|
||||
IfName: rt.IfName,
|
||||
NetworkName: netName,
|
||||
CniArgs: rt.Args,
|
||||
CapabilityArgs: rt.CapabilityArgs,
|
||||
}
|
||||
|
||||
// We need to get type.Result into cachedInfo as JSON map
|
||||
// Marshal to []byte, then Unmarshal into cached.RawResult
|
||||
data, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &cached.RawResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newBytes, err := json.Marshal(&cached)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fname, err := c.getCacheFilePath(netName, rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(fname, newBytes, 0600)
|
||||
}
|
||||
|
||||
func (c *CNIConfig) cacheDel(netName string, rt *RuntimeConf) error {
|
||||
fname, err := c.getCacheFilePath(netName, rt)
|
||||
if err != nil {
|
||||
// Ignore error
|
||||
return nil
|
||||
}
|
||||
return os.Remove(fname)
|
||||
}
|
||||
|
||||
func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||
var bytes []byte
|
||||
|
||||
fname, err := c.getCacheFilePath(netName, rt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
bytes, err = ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
// Ignore read errors; the cached result may not exist on-disk
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
unmarshaled := cachedInfo{}
|
||||
if err := json.Unmarshal(bytes, &unmarshaled); err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to unmarshal cached network %q config: %w", netName, err)
|
||||
}
|
||||
if unmarshaled.Kind != CNICacheV1 {
|
||||
return nil, nil, fmt.Errorf("read cached network %q config has wrong kind: %v", netName, unmarshaled.Kind)
|
||||
}
|
||||
|
||||
newRt := *rt
|
||||
if unmarshaled.CniArgs != nil {
|
||||
newRt.Args = unmarshaled.CniArgs
|
||||
}
|
||||
newRt.CapabilityArgs = unmarshaled.CapabilityArgs
|
||||
|
||||
return unmarshaled.Config, &newRt, nil
|
||||
}
|
||||
|
||||
func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
|
||||
fname, err := c.getCacheFilePath(netName, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
// Ignore read errors; the cached result may not exist on-disk
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Load the cached result
|
||||
result, err := create.CreateFromBytes(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert to the config version to ensure plugins get prevResult
|
||||
// in the same version as the config. The cached result version
|
||||
// should match the config version unless the config was changed
|
||||
// while the container was running.
|
||||
result, err = result.GetAsVersion(cniVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert cached result to config version %q: %w", cniVersion, err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
|
||||
fname, err := c.getCacheFilePath(netName, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fdata, err := ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
// Ignore read errors; the cached result may not exist on-disk
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
cachedInfo := cachedInfo{}
|
||||
if err := json.Unmarshal(fdata, &cachedInfo); err != nil || cachedInfo.Kind != CNICacheV1 {
|
||||
return c.getLegacyCachedResult(netName, cniVersion, rt)
|
||||
}
|
||||
|
||||
newBytes, err := json.Marshal(&cachedInfo.RawResult)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal cached network %q config: %w", netName, err)
|
||||
}
|
||||
|
||||
// Load the cached result
|
||||
result, err := create.CreateFromBytes(newBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert to the config version to ensure plugins get prevResult
|
||||
// in the same version as the config. The cached result version
|
||||
// should match the config version unless the config was changed
|
||||
// while the container was running.
|
||||
result, err = result.GetAsVersion(cniVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert cached result to config version %q: %w", cniVersion, err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetNetworkListCachedResult returns the cached Result of the previous
|
||||
// AddNetworkList() operation for a network list, or an error.
|
||||
func (c *CNIConfig) GetNetworkListCachedResult(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
|
||||
return c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
}
|
||||
|
||||
// GetNetworkCachedResult returns the cached Result of the previous
|
||||
// AddNetwork() operation for a network, or an error.
|
||||
func (c *CNIConfig) GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
|
||||
return c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||
}
|
||||
|
||||
// GetNetworkListCachedConfig copies the input RuntimeConf to output
|
||||
// RuntimeConf with fields updated with info from the cached Config.
|
||||
func (c *CNIConfig) GetNetworkListCachedConfig(list *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||
return c.getCachedConfig(list.Name, rt)
|
||||
}
|
||||
|
||||
// GetNetworkCachedConfig copies the input RuntimeConf to output
|
||||
// RuntimeConf with fields updated with info from the cached Config.
|
||||
func (c *CNIConfig) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||
return c.getCachedConfig(net.Network.Name, rt)
|
||||
}
|
||||
|
||||
func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
|
||||
c.ensureExec()
|
||||
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := utils.ValidateContainerID(rt.ContainerID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := utils.ValidateNetworkName(name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := utils.ValidateInterfaceName(rt.IfName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return invoke.ExecPluginWithResult(ctx, pluginPath, newConf.Bytes, c.args("ADD", rt), c.exec)
|
||||
}
|
||||
|
||||
// AddNetworkList executes a sequence of plugins with the ADD command
|
||||
func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
|
||||
var prevResult types.Result
|
||||
func (c *CNIConfig) AddNetworkList(ctx context.Context, list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
|
||||
var err error
|
||||
var result types.Result
|
||||
for _, net := range list.Plugins {
|
||||
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||
result, err = c.addNetwork(ctx, list.Name, list.CNIVersion, net, result, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newConf, err := buildOneConfig(list, net, prevResult, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prevResult, err = invoke.ExecPluginWithResult(pluginPath, newConf.Bytes, c.args("ADD", rt))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("plugin %s failed (add): %w", pluginDescription(net.Network), err)
|
||||
}
|
||||
}
|
||||
|
||||
return prevResult, nil
|
||||
if err = c.cacheAdd(result, list.Bytes, list.Name, rt); err != nil {
|
||||
return nil, fmt.Errorf("failed to set network %q cached result: %w", list.Name, err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DelNetworkList executes a sequence of plugins with the DEL command
|
||||
func (c *CNIConfig) DelNetworkList(list *NetworkConfigList, rt *RuntimeConf) error {
|
||||
for i := len(list.Plugins) - 1; i >= 0; i-- {
|
||||
net := list.Plugins[i]
|
||||
func (c *CNIConfig) checkNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error {
|
||||
c.ensureExec()
|
||||
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newConf, err := buildOneConfig(list, net, nil, rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return invoke.ExecPluginWithoutResult(ctx, pluginPath, newConf.Bytes, c.args("CHECK", rt), c.exec)
|
||||
}
|
||||
|
||||
if err := invoke.ExecPluginWithoutResult(pluginPath, newConf.Bytes, c.args("DEL", rt)); err != nil {
|
||||
// CheckNetworkList executes a sequence of plugins with the CHECK command
|
||||
func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigList, rt *RuntimeConf) error {
|
||||
// CHECK was added in CNI spec version 0.4.0 and higher
|
||||
if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
|
||||
return err
|
||||
} else if !gtet {
|
||||
return fmt.Errorf("configuration version %q does not support the CHECK command", list.CNIVersion)
|
||||
}
|
||||
|
||||
if list.DisableCheck {
|
||||
return nil
|
||||
}
|
||||
|
||||
cachedResult, err := c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err)
|
||||
}
|
||||
|
||||
for _, net := range list.Plugins {
|
||||
if err := c.checkNetwork(ctx, list.Name, list.CNIVersion, net, cachedResult, rt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -165,45 +474,196 @@ func (c *CNIConfig) DelNetworkList(list *NetworkConfigList, rt *RuntimeConf) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CNIConfig) delNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error {
|
||||
c.ensureExec()
|
||||
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return invoke.ExecPluginWithoutResult(ctx, pluginPath, newConf.Bytes, c.args("DEL", rt), c.exec)
|
||||
}
|
||||
|
||||
// DelNetworkList executes a sequence of plugins with the DEL command
|
||||
func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList, rt *RuntimeConf) error {
|
||||
var cachedResult types.Result
|
||||
|
||||
// Cached result on DEL was added in CNI spec version 0.4.0 and higher
|
||||
if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
|
||||
return err
|
||||
} else if gtet {
|
||||
cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
for i := len(list.Plugins) - 1; i >= 0; i-- {
|
||||
net := list.Plugins[i]
|
||||
if err := c.delNetwork(ctx, list.Name, list.CNIVersion, net, cachedResult, rt); err != nil {
|
||||
return fmt.Errorf("plugin %s failed (delete): %w", pluginDescription(net.Network), err)
|
||||
}
|
||||
}
|
||||
_ = c.cacheDel(list.Name, rt)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func pluginDescription(net *types.NetConf) string {
|
||||
if net == nil {
|
||||
return "<missing>"
|
||||
}
|
||||
pluginType := net.Type
|
||||
out := fmt.Sprintf("type=%q", pluginType)
|
||||
name := net.Name
|
||||
if name != "" {
|
||||
out += fmt.Sprintf(" name=%q", name)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AddNetwork executes the plugin with the ADD command
|
||||
func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
|
||||
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||
func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
|
||||
result, err := c.addNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, nil, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
net, err = injectRuntimeConfig(net, rt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err = c.cacheAdd(result, net.Bytes, net.Network.Name, rt); err != nil {
|
||||
return nil, fmt.Errorf("failed to set network %q cached result: %w", net.Network.Name, err)
|
||||
}
|
||||
|
||||
return invoke.ExecPluginWithResult(pluginPath, net.Bytes, c.args("ADD", rt))
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CheckNetwork executes the plugin with the CHECK command
|
||||
func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error {
|
||||
// CHECK was added in CNI spec version 0.4.0 and higher
|
||||
if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil {
|
||||
return err
|
||||
} else if !gtet {
|
||||
return fmt.Errorf("configuration version %q does not support the CHECK command", net.Network.CNIVersion)
|
||||
}
|
||||
|
||||
cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err)
|
||||
}
|
||||
return c.checkNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt)
|
||||
}
|
||||
|
||||
// DelNetwork executes the plugin with the DEL command
|
||||
func (c *CNIConfig) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error {
|
||||
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||
func (c *CNIConfig) DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error {
|
||||
var cachedResult types.Result
|
||||
|
||||
// Cached result on DEL was added in CNI spec version 0.4.0 and higher
|
||||
if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil {
|
||||
return err
|
||||
} else if gtet {
|
||||
cachedResult, err = c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.delNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = c.cacheDel(net.Network.Name, rt)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateNetworkList checks that a configuration is reasonably valid.
|
||||
// - all the specified plugins exist on disk
|
||||
// - every plugin supports the desired version.
|
||||
//
|
||||
// Returns a list of all capabilities supported by the configuration, or error
|
||||
func (c *CNIConfig) ValidateNetworkList(ctx context.Context, list *NetworkConfigList) ([]string, error) {
|
||||
version := list.CNIVersion
|
||||
|
||||
// holding map for seen caps (in case of duplicates)
|
||||
caps := map[string]interface{}{}
|
||||
|
||||
errs := []error{}
|
||||
for _, net := range list.Plugins {
|
||||
if err := c.validatePlugin(ctx, net.Network.Type, version); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
for c, enabled := range net.Network.Capabilities {
|
||||
if !enabled {
|
||||
continue
|
||||
}
|
||||
caps[c] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return nil, fmt.Errorf("%v", errs)
|
||||
}
|
||||
|
||||
// make caps list
|
||||
cc := make([]string, 0, len(caps))
|
||||
for c := range caps {
|
||||
cc = append(cc, c)
|
||||
}
|
||||
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
// ValidateNetwork checks that a configuration is reasonably valid.
|
||||
// It uses the same logic as ValidateNetworkList)
|
||||
// Returns a list of capabilities
|
||||
func (c *CNIConfig) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error) {
|
||||
caps := []string{}
|
||||
for c, ok := range net.Network.Capabilities {
|
||||
if ok {
|
||||
caps = append(caps, c)
|
||||
}
|
||||
}
|
||||
if err := c.validatePlugin(ctx, net.Network.Type, net.Network.CNIVersion); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return caps, nil
|
||||
}
|
||||
|
||||
// validatePlugin checks that an individual plugin's configuration is sane
|
||||
func (c *CNIConfig) validatePlugin(ctx context.Context, pluginName, expectedVersion string) error {
|
||||
c.ensureExec()
|
||||
pluginPath, err := c.exec.FindInPath(pluginName, c.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if expectedVersion == "" {
|
||||
expectedVersion = "0.1.0"
|
||||
}
|
||||
|
||||
net, err = injectRuntimeConfig(net, rt)
|
||||
vi, err := invoke.GetVersionInfo(ctx, pluginPath, c.exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return invoke.ExecPluginWithoutResult(pluginPath, net.Bytes, c.args("DEL", rt))
|
||||
for _, vers := range vi.SupportedVersions() {
|
||||
if vers == expectedVersion {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("plugin %s does not support config version %q", pluginName, expectedVersion)
|
||||
}
|
||||
|
||||
// GetVersionInfo reports which versions of the CNI spec are supported by
|
||||
// the given plugin.
|
||||
func (c *CNIConfig) GetVersionInfo(pluginType string) (version.PluginInfo, error) {
|
||||
pluginPath, err := invoke.FindInPath(pluginType, c.Path)
|
||||
func (c *CNIConfig) GetVersionInfo(ctx context.Context, pluginType string) (version.PluginInfo, error) {
|
||||
c.ensureExec()
|
||||
pluginPath, err := c.exec.FindInPath(pluginType, c.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return invoke.GetVersionInfo(pluginPath)
|
||||
return invoke.GetVersionInfo(ctx, pluginPath, c.exec)
|
||||
}
|
||||
|
||||
// =====
|
||||
|
32
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
32
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
@@ -43,7 +43,10 @@ func (e NoConfigsFoundError) Error() string {
|
||||
func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
|
||||
conf := &NetworkConfig{Bytes: bytes}
|
||||
if err := json.Unmarshal(bytes, &conf.Network); err != nil {
|
||||
return nil, fmt.Errorf("error parsing configuration: %s", err)
|
||||
return nil, fmt.Errorf("error parsing configuration: %w", err)
|
||||
}
|
||||
if conf.Network.Type == "" {
|
||||
return nil, fmt.Errorf("error parsing configuration: missing 'type'")
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
@@ -51,7 +54,7 @@ func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
|
||||
func ConfFromFile(filename string) (*NetworkConfig, error) {
|
||||
bytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %s", filename, err)
|
||||
return nil, fmt.Errorf("error reading %s: %w", filename, err)
|
||||
}
|
||||
return ConfFromBytes(bytes)
|
||||
}
|
||||
@@ -59,7 +62,7 @@ func ConfFromFile(filename string) (*NetworkConfig, error) {
|
||||
func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
|
||||
rawList := make(map[string]interface{})
|
||||
if err := json.Unmarshal(bytes, &rawList); err != nil {
|
||||
return nil, fmt.Errorf("error parsing configuration list: %s", err)
|
||||
return nil, fmt.Errorf("error parsing configuration list: %w", err)
|
||||
}
|
||||
|
||||
rawName, ok := rawList["name"]
|
||||
@@ -80,10 +83,19 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
|
||||
}
|
||||
}
|
||||
|
||||
disableCheck := false
|
||||
if rawDisableCheck, ok := rawList["disableCheck"]; ok {
|
||||
disableCheck, ok = rawDisableCheck.(bool)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck)
|
||||
}
|
||||
}
|
||||
|
||||
list := &NetworkConfigList{
|
||||
Name: name,
|
||||
CNIVersion: cniVersion,
|
||||
Bytes: bytes,
|
||||
Name: name,
|
||||
DisableCheck: disableCheck,
|
||||
CNIVersion: cniVersion,
|
||||
Bytes: bytes,
|
||||
}
|
||||
|
||||
var plugins []interface{}
|
||||
@@ -102,11 +114,11 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
|
||||
for i, conf := range plugins {
|
||||
newBytes, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal plugin config %d: %v", i, err)
|
||||
return nil, fmt.Errorf("failed to marshal plugin config %d: %w", i, err)
|
||||
}
|
||||
netConf, err := ConfFromBytes(newBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse plugin config %d: %v", i, err)
|
||||
return nil, fmt.Errorf("failed to parse plugin config %d: %w", i, err)
|
||||
}
|
||||
list.Plugins = append(list.Plugins, netConf)
|
||||
}
|
||||
@@ -117,7 +129,7 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
|
||||
func ConfListFromFile(filename string) (*NetworkConfigList, error) {
|
||||
bytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %s", filename, err)
|
||||
return nil, fmt.Errorf("error reading %s: %w", filename, err)
|
||||
}
|
||||
return ConfListFromBytes(bytes)
|
||||
}
|
||||
@@ -206,7 +218,7 @@ func InjectConf(original *NetworkConfig, newValues map[string]interface{}) (*Net
|
||||
config := make(map[string]interface{})
|
||||
err := json.Unmarshal(original.Bytes, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshal existing network bytes: %s", err)
|
||||
return nil, fmt.Errorf("unmarshal existing network bytes: %w", err)
|
||||
}
|
||||
|
||||
for key, value := range newValues {
|
||||
|
70
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
70
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package invoke
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@@ -22,6 +23,8 @@ import (
|
||||
type CNIArgs interface {
|
||||
// For use with os/exec; i.e., return nil to inherit the
|
||||
// environment from this process
|
||||
// For use in delegation; inherit the environment from this
|
||||
// process and allow overrides
|
||||
AsEnv() []string
|
||||
}
|
||||
|
||||
@@ -29,7 +32,7 @@ type inherited struct{}
|
||||
|
||||
var inheritArgsFromEnv inherited
|
||||
|
||||
func (_ *inherited) AsEnv() []string {
|
||||
func (*inherited) AsEnv() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -57,17 +60,17 @@ func (args *Args) AsEnv() []string {
|
||||
pluginArgsStr = stringify(args.PluginArgs)
|
||||
}
|
||||
|
||||
// Ensure that the custom values are first, so any value present in
|
||||
// the process environment won't override them.
|
||||
env = append([]string{
|
||||
"CNI_COMMAND=" + args.Command,
|
||||
"CNI_CONTAINERID=" + args.ContainerID,
|
||||
"CNI_NETNS=" + args.NetNS,
|
||||
"CNI_ARGS=" + pluginArgsStr,
|
||||
"CNI_IFNAME=" + args.IfName,
|
||||
"CNI_PATH=" + args.Path,
|
||||
}, env...)
|
||||
return env
|
||||
// Duplicated values which come first will be overridden, so we must put the
|
||||
// custom values in the end to avoid being overridden by the process environments.
|
||||
env = append(env,
|
||||
"CNI_COMMAND="+args.Command,
|
||||
"CNI_CONTAINERID="+args.ContainerID,
|
||||
"CNI_NETNS="+args.NetNS,
|
||||
"CNI_ARGS="+pluginArgsStr,
|
||||
"CNI_IFNAME="+args.IfName,
|
||||
"CNI_PATH="+args.Path,
|
||||
)
|
||||
return dedupEnv(env)
|
||||
}
|
||||
|
||||
// taken from rkt/networking/net_plugin.go
|
||||
@@ -80,3 +83,46 @@ func stringify(pluginArgs [][2]string) string {
|
||||
|
||||
return strings.Join(entries, ";")
|
||||
}
|
||||
|
||||
// DelegateArgs implements the CNIArgs interface
|
||||
// used for delegation to inherit from environments
|
||||
// and allow some overrides like CNI_COMMAND
|
||||
var _ CNIArgs = &DelegateArgs{}
|
||||
|
||||
type DelegateArgs struct {
|
||||
Command string
|
||||
}
|
||||
|
||||
func (d *DelegateArgs) AsEnv() []string {
|
||||
env := os.Environ()
|
||||
|
||||
// The custom values should come in the end to override the existing
|
||||
// process environment of the same key.
|
||||
env = append(env,
|
||||
"CNI_COMMAND="+d.Command,
|
||||
)
|
||||
return dedupEnv(env)
|
||||
}
|
||||
|
||||
// dedupEnv returns a copy of env with any duplicates removed, in favor of later values.
|
||||
// Items not of the normal environment "key=value" form are preserved unchanged.
|
||||
func dedupEnv(env []string) []string {
|
||||
out := make([]string, 0, len(env))
|
||||
envMap := map[string]string{}
|
||||
|
||||
for _, kv := range env {
|
||||
// find the first "=" in environment, if not, just keep it
|
||||
eq := strings.Index(kv, "=")
|
||||
if eq < 0 {
|
||||
out = append(out, kv)
|
||||
continue
|
||||
}
|
||||
envMap[kv[:eq]] = kv[eq+1:]
|
||||
}
|
||||
|
||||
for k, v := range envMap {
|
||||
out = append(out, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
57
vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
generated
vendored
57
vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
generated
vendored
@@ -15,39 +15,66 @@
|
||||
package invoke
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
func DelegateAdd(delegatePlugin string, netconf []byte) (types.Result, error) {
|
||||
if os.Getenv("CNI_COMMAND") != "ADD" {
|
||||
return nil, fmt.Errorf("CNI_COMMAND is not ADD")
|
||||
func delegateCommon(delegatePlugin string, exec Exec) (string, Exec, error) {
|
||||
if exec == nil {
|
||||
exec = defaultExec
|
||||
}
|
||||
|
||||
paths := filepath.SplitList(os.Getenv("CNI_PATH"))
|
||||
pluginPath, err := exec.FindInPath(delegatePlugin, paths)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
pluginPath, err := FindInPath(delegatePlugin, paths)
|
||||
return pluginPath, exec, nil
|
||||
}
|
||||
|
||||
// DelegateAdd calls the given delegate plugin with the CNI ADD action and
|
||||
// JSON configuration
|
||||
func DelegateAdd(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) (types.Result, error) {
|
||||
pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ExecPluginWithResult(pluginPath, netconf, ArgsFromEnv())
|
||||
// DelegateAdd will override the original "CNI_COMMAND" env from process with ADD
|
||||
return ExecPluginWithResult(ctx, pluginPath, netconf, delegateArgs("ADD"), realExec)
|
||||
}
|
||||
|
||||
func DelegateDel(delegatePlugin string, netconf []byte) error {
|
||||
if os.Getenv("CNI_COMMAND") != "DEL" {
|
||||
return fmt.Errorf("CNI_COMMAND is not DEL")
|
||||
}
|
||||
|
||||
paths := filepath.SplitList(os.Getenv("CNI_PATH"))
|
||||
|
||||
pluginPath, err := FindInPath(delegatePlugin, paths)
|
||||
// DelegateCheck calls the given delegate plugin with the CNI CHECK action and
|
||||
// JSON configuration
|
||||
func DelegateCheck(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
|
||||
pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ExecPluginWithoutResult(pluginPath, netconf, ArgsFromEnv())
|
||||
// DelegateCheck will override the original CNI_COMMAND env from process with CHECK
|
||||
return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("CHECK"), realExec)
|
||||
}
|
||||
|
||||
// DelegateDel calls the given delegate plugin with the CNI DEL action and
|
||||
// JSON configuration
|
||||
func DelegateDel(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
|
||||
pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// DelegateDel will override the original CNI_COMMAND env from process with DEL
|
||||
return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("DEL"), realExec)
|
||||
}
|
||||
|
||||
// return CNIArgs used by delegation
|
||||
func delegateArgs(action string) *DelegateArgs {
|
||||
return &DelegateArgs{
|
||||
Command: action,
|
||||
}
|
||||
}
|
||||
|
115
vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
generated
vendored
115
vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
generated
vendored
@@ -15,57 +15,83 @@
|
||||
package invoke
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/create"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
)
|
||||
|
||||
func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) {
|
||||
return defaultPluginExec.WithResult(pluginPath, netconf, args)
|
||||
// Exec is an interface encapsulates all operations that deal with finding
|
||||
// and executing a CNI plugin. Tests may provide a fake implementation
|
||||
// to avoid writing fake plugins to temporary directories during the test.
|
||||
type Exec interface {
|
||||
ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error)
|
||||
FindInPath(plugin string, paths []string) (string, error)
|
||||
Decode(jsonBytes []byte) (version.PluginInfo, error)
|
||||
}
|
||||
|
||||
func ExecPluginWithoutResult(pluginPath string, netconf []byte, args CNIArgs) error {
|
||||
return defaultPluginExec.WithoutResult(pluginPath, netconf, args)
|
||||
}
|
||||
// For example, a testcase could pass an instance of the following fakeExec
|
||||
// object to ExecPluginWithResult() to verify the incoming stdin and environment
|
||||
// and provide a tailored response:
|
||||
//
|
||||
//import (
|
||||
// "encoding/json"
|
||||
// "path"
|
||||
// "strings"
|
||||
//)
|
||||
//
|
||||
//type fakeExec struct {
|
||||
// version.PluginDecoder
|
||||
//}
|
||||
//
|
||||
//func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
|
||||
// net := &types.NetConf{}
|
||||
// err := json.Unmarshal(stdinData, net)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("failed to unmarshal configuration: %v", err)
|
||||
// }
|
||||
// pluginName := path.Base(pluginPath)
|
||||
// if pluginName != net.Type {
|
||||
// return nil, fmt.Errorf("plugin name %q did not match config type %q", pluginName, net.Type)
|
||||
// }
|
||||
// for _, e := range environ {
|
||||
// // Check environment for forced failure request
|
||||
// parts := strings.Split(e, "=")
|
||||
// if len(parts) > 0 && parts[0] == "FAIL" {
|
||||
// return nil, fmt.Errorf("failed to execute plugin %s", pluginName)
|
||||
// }
|
||||
// }
|
||||
// return []byte("{\"CNIVersion\":\"0.4.0\"}"), nil
|
||||
//}
|
||||
//
|
||||
//func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) {
|
||||
// if len(paths) > 0 {
|
||||
// return path.Join(paths[0], plugin), nil
|
||||
// }
|
||||
// return "", fmt.Errorf("failed to find plugin %s in paths %v", plugin, paths)
|
||||
//}
|
||||
|
||||
func GetVersionInfo(pluginPath string) (version.PluginInfo, error) {
|
||||
return defaultPluginExec.GetVersionInfo(pluginPath)
|
||||
}
|
||||
|
||||
var defaultPluginExec = &PluginExec{
|
||||
RawExec: &RawExec{Stderr: os.Stderr},
|
||||
VersionDecoder: &version.PluginDecoder{},
|
||||
}
|
||||
|
||||
type PluginExec struct {
|
||||
RawExec interface {
|
||||
ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error)
|
||||
func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) (types.Result, error) {
|
||||
if exec == nil {
|
||||
exec = defaultExec
|
||||
}
|
||||
VersionDecoder interface {
|
||||
Decode(jsonBytes []byte) (version.PluginInfo, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) {
|
||||
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv())
|
||||
stdoutBytes, err := exec.ExecPlugin(ctx, pluginPath, netconf, args.AsEnv())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Plugin must return result in same version as specified in netconf
|
||||
versionDecoder := &version.ConfigDecoder{}
|
||||
confVersion, err := versionDecoder.Decode(netconf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return version.NewResult(confVersion, stdoutBytes)
|
||||
return create.CreateFromBytes(stdoutBytes)
|
||||
}
|
||||
|
||||
func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIArgs) error {
|
||||
_, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv())
|
||||
func ExecPluginWithoutResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) error {
|
||||
if exec == nil {
|
||||
exec = defaultExec
|
||||
}
|
||||
_, err := exec.ExecPlugin(ctx, pluginPath, netconf, args.AsEnv())
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -73,7 +99,10 @@ func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIAr
|
||||
// For recent-enough plugins, it uses the information returned by the VERSION
|
||||
// command. For older plugins which do not recognize that command, it reports
|
||||
// version 0.1.0
|
||||
func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, error) {
|
||||
func GetVersionInfo(ctx context.Context, pluginPath string, exec Exec) (version.PluginInfo, error) {
|
||||
if exec == nil {
|
||||
exec = defaultExec
|
||||
}
|
||||
args := &Args{
|
||||
Command: "VERSION",
|
||||
|
||||
@@ -83,7 +112,7 @@ func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, erro
|
||||
Path: "dummy",
|
||||
}
|
||||
stdin := []byte(fmt.Sprintf(`{"cniVersion":%q}`, version.Current()))
|
||||
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, stdin, args.AsEnv())
|
||||
stdoutBytes, err := exec.ExecPlugin(ctx, pluginPath, stdin, args.AsEnv())
|
||||
if err != nil {
|
||||
if err.Error() == "unknown CNI_COMMAND: VERSION" {
|
||||
return version.PluginSupports("0.1.0"), nil
|
||||
@@ -91,5 +120,19 @@ func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return e.VersionDecoder.Decode(stdoutBytes)
|
||||
return exec.Decode(stdoutBytes)
|
||||
}
|
||||
|
||||
// DefaultExec is an object that implements the Exec interface which looks
|
||||
// for and executes plugins from disk.
|
||||
type DefaultExec struct {
|
||||
*RawExec
|
||||
version.PluginDecoder
|
||||
}
|
||||
|
||||
// DefaultExec implements the Exec interface
|
||||
var _ Exec = &DefaultExec{}
|
||||
|
||||
var defaultExec = &DefaultExec{
|
||||
RawExec: &RawExec{Stderr: os.Stderr},
|
||||
}
|
||||
|
5
vendor/github.com/containernetworking/cni/pkg/invoke/find.go
generated
vendored
5
vendor/github.com/containernetworking/cni/pkg/invoke/find.go
generated
vendored
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FindInPath returns the full path of the plugin by searching in the provided path
|
||||
@@ -26,6 +27,10 @@ func FindInPath(plugin string, paths []string) (string, error) {
|
||||
return "", fmt.Errorf("no plugin name provided")
|
||||
}
|
||||
|
||||
if strings.ContainsRune(plugin, os.PathSeparator) {
|
||||
return "", fmt.Errorf("invalid plugin name: %s", plugin)
|
||||
}
|
||||
|
||||
if len(paths) == 0 {
|
||||
return "", fmt.Errorf("no paths provided")
|
||||
}
|
||||
|
2
vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
generated
vendored
2
vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
generated
vendored
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build darwin dragonfly freebsd linux netbsd opensbd solaris
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package invoke
|
||||
|
||||
|
67
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
67
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
@@ -16,10 +16,13 @@ package invoke
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
@@ -28,32 +31,58 @@ type RawExec struct {
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
func (e *RawExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
|
||||
func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
|
||||
stdout := &bytes.Buffer{}
|
||||
stderr := &bytes.Buffer{}
|
||||
c := exec.CommandContext(ctx, pluginPath)
|
||||
c.Env = environ
|
||||
c.Stdin = bytes.NewBuffer(stdinData)
|
||||
c.Stdout = stdout
|
||||
c.Stderr = stderr
|
||||
|
||||
c := exec.Cmd{
|
||||
Env: environ,
|
||||
Path: pluginPath,
|
||||
Args: []string{pluginPath},
|
||||
Stdin: bytes.NewBuffer(stdinData),
|
||||
Stdout: stdout,
|
||||
Stderr: e.Stderr,
|
||||
}
|
||||
if err := c.Run(); err != nil {
|
||||
return nil, pluginErr(err, stdout.Bytes())
|
||||
// Retry the command on "text file busy" errors
|
||||
for i := 0; i <= 5; i++ {
|
||||
err := c.Run()
|
||||
|
||||
// Command succeeded
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// If the plugin is currently about to be written, then we wait a
|
||||
// second and try it again
|
||||
if strings.Contains(err.Error(), "text file busy") {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
// All other errors except than the busy text file
|
||||
return nil, e.pluginErr(err, stdout.Bytes(), stderr.Bytes())
|
||||
}
|
||||
|
||||
// Copy stderr to caller's buffer in case plugin printed to both
|
||||
// stdout and stderr for some reason. Ignore failures as stderr is
|
||||
// only informational.
|
||||
if e.Stderr != nil && stderr.Len() > 0 {
|
||||
_, _ = stderr.WriteTo(e.Stderr)
|
||||
}
|
||||
return stdout.Bytes(), nil
|
||||
}
|
||||
|
||||
func pluginErr(err error, output []byte) error {
|
||||
if _, ok := err.(*exec.ExitError); ok {
|
||||
emsg := types.Error{}
|
||||
if perr := json.Unmarshal(output, &emsg); perr != nil {
|
||||
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr)
|
||||
func (e *RawExec) pluginErr(err error, stdout, stderr []byte) error {
|
||||
emsg := types.Error{}
|
||||
if len(stdout) == 0 {
|
||||
if len(stderr) == 0 {
|
||||
emsg.Msg = fmt.Sprintf("netplugin failed with no error message: %v", err)
|
||||
} else {
|
||||
emsg.Msg = fmt.Sprintf("netplugin failed: %q", string(stderr))
|
||||
}
|
||||
return &emsg
|
||||
} else if perr := json.Unmarshal(stdout, &emsg); perr != nil {
|
||||
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(stdout), perr)
|
||||
}
|
||||
|
||||
return err
|
||||
return &emsg
|
||||
}
|
||||
|
||||
func (e *RawExec) FindInPath(plugin string, paths []string) (string, error) {
|
||||
return FindInPath(plugin, paths)
|
||||
}
|
||||
|
106
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
generated
vendored
106
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
generated
vendored
@@ -17,29 +17,52 @@ package types020
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
convert "github.com/containernetworking/cni/pkg/types/internal"
|
||||
)
|
||||
|
||||
const ImplementedSpecVersion string = "0.2.0"
|
||||
|
||||
var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion}
|
||||
var supportedVersions = []string{"", "0.1.0", ImplementedSpecVersion}
|
||||
|
||||
// Register converters for all versions less than the implemented spec version
|
||||
func init() {
|
||||
convert.RegisterConverter("0.1.0", []string{ImplementedSpecVersion}, convertFrom010)
|
||||
convert.RegisterConverter(ImplementedSpecVersion, []string{"0.1.0"}, convertTo010)
|
||||
|
||||
// Creator
|
||||
convert.RegisterCreator(supportedVersions, NewResult)
|
||||
}
|
||||
|
||||
// Compatibility types for CNI version 0.1.0 and 0.2.0
|
||||
|
||||
// NewResult creates a new Result object from JSON data. The JSON data
|
||||
// must be compatible with the CNI versions implemented by this type.
|
||||
func NewResult(data []byte) (types.Result, error) {
|
||||
result := &Result{}
|
||||
if err := json.Unmarshal(data, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
for _, v := range supportedVersions {
|
||||
if result.CNIVersion == v {
|
||||
if result.CNIVersion == "" {
|
||||
result.CNIVersion = "0.1.0"
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q",
|
||||
supportedVersions, result.CNIVersion)
|
||||
}
|
||||
|
||||
// GetResult converts the given Result object to the ImplementedSpecVersion
|
||||
// and returns the concrete type or an error
|
||||
func GetResult(r types.Result) (*Result, error) {
|
||||
// We expect version 0.1.0/0.2.0 results
|
||||
result020, err := r.GetAsVersion(ImplementedSpecVersion)
|
||||
result020, err := convert.Convert(r, ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -50,6 +73,32 @@ func GetResult(r types.Result) (*Result, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func convertFrom010(from types.Result, toVersion string) (types.Result, error) {
|
||||
if toVersion != "0.2.0" {
|
||||
panic("only converts to version 0.2.0")
|
||||
}
|
||||
fromResult := from.(*Result)
|
||||
return &Result{
|
||||
CNIVersion: ImplementedSpecVersion,
|
||||
IP4: fromResult.IP4.Copy(),
|
||||
IP6: fromResult.IP6.Copy(),
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertTo010(from types.Result, toVersion string) (types.Result, error) {
|
||||
if toVersion != "0.1.0" {
|
||||
panic("only converts to version 0.1.0")
|
||||
}
|
||||
fromResult := from.(*Result)
|
||||
return &Result{
|
||||
CNIVersion: "0.1.0",
|
||||
IP4: fromResult.IP4.Copy(),
|
||||
IP6: fromResult.IP6.Copy(),
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Result is what gets returned from the plugin (via stdout) to the caller
|
||||
type Result struct {
|
||||
CNIVersion string `json:"cniVersion,omitempty"`
|
||||
@@ -59,42 +108,31 @@ type Result struct {
|
||||
}
|
||||
|
||||
func (r *Result) Version() string {
|
||||
return ImplementedSpecVersion
|
||||
return r.CNIVersion
|
||||
}
|
||||
|
||||
func (r *Result) GetAsVersion(version string) (types.Result, error) {
|
||||
for _, supportedVersion := range SupportedVersions {
|
||||
if version == supportedVersion {
|
||||
r.CNIVersion = version
|
||||
return r, nil
|
||||
}
|
||||
// If the creator of the result did not set the CNIVersion, assume it
|
||||
// should be the highest spec version implemented by this Result
|
||||
if r.CNIVersion == "" {
|
||||
r.CNIVersion = ImplementedSpecVersion
|
||||
}
|
||||
return nil, fmt.Errorf("cannot convert version %q to %s", SupportedVersions, version)
|
||||
return convert.Convert(r, version)
|
||||
}
|
||||
|
||||
func (r *Result) Print() error {
|
||||
return r.PrintTo(os.Stdout)
|
||||
}
|
||||
|
||||
func (r *Result) PrintTo(writer io.Writer) error {
|
||||
data, err := json.MarshalIndent(r, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = os.Stdout.Write(data)
|
||||
_, err = writer.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where
|
||||
// $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the
|
||||
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
||||
func (r *Result) String() string {
|
||||
var str string
|
||||
if r.IP4 != nil {
|
||||
str = fmt.Sprintf("IP4:%+v, ", *r.IP4)
|
||||
}
|
||||
if r.IP6 != nil {
|
||||
str += fmt.Sprintf("IP6:%+v, ", *r.IP6)
|
||||
}
|
||||
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
||||
}
|
||||
|
||||
// IPConfig contains values necessary to configure an interface
|
||||
type IPConfig struct {
|
||||
IP net.IPNet
|
||||
@@ -102,6 +140,22 @@ type IPConfig struct {
|
||||
Routes []types.Route
|
||||
}
|
||||
|
||||
func (i *IPConfig) Copy() *IPConfig {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var routes []types.Route
|
||||
for _, fromRoute := range i.Routes {
|
||||
routes = append(routes, *fromRoute.Copy())
|
||||
}
|
||||
return &IPConfig{
|
||||
IP: i.IP,
|
||||
Gateway: i.Gateway,
|
||||
Routes: routes,
|
||||
}
|
||||
}
|
||||
|
||||
// net.IPNet is not JSON (un)marshallable so this duality is needed
|
||||
// for our custom IPNet type
|
||||
|
||||
|
306
vendor/github.com/containernetworking/cni/pkg/types/040/types.go
generated
vendored
Normal file
306
vendor/github.com/containernetworking/cni/pkg/types/040/types.go
generated
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 types040
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
types020 "github.com/containernetworking/cni/pkg/types/020"
|
||||
convert "github.com/containernetworking/cni/pkg/types/internal"
|
||||
)
|
||||
|
||||
const ImplementedSpecVersion string = "0.4.0"
|
||||
|
||||
var supportedVersions = []string{"0.3.0", "0.3.1", ImplementedSpecVersion}
|
||||
|
||||
// Register converters for all versions less than the implemented spec version
|
||||
func init() {
|
||||
// Up-converters
|
||||
convert.RegisterConverter("0.1.0", supportedVersions, convertFrom02x)
|
||||
convert.RegisterConverter("0.2.0", supportedVersions, convertFrom02x)
|
||||
convert.RegisterConverter("0.3.0", supportedVersions, convertInternal)
|
||||
convert.RegisterConverter("0.3.1", supportedVersions, convertInternal)
|
||||
|
||||
// Down-converters
|
||||
convert.RegisterConverter("0.4.0", []string{"0.3.0", "0.3.1"}, convertInternal)
|
||||
convert.RegisterConverter("0.4.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
|
||||
convert.RegisterConverter("0.3.1", []string{"0.1.0", "0.2.0"}, convertTo02x)
|
||||
convert.RegisterConverter("0.3.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
|
||||
|
||||
// Creator
|
||||
convert.RegisterCreator(supportedVersions, NewResult)
|
||||
}
|
||||
|
||||
func NewResult(data []byte) (types.Result, error) {
|
||||
result := &Result{}
|
||||
if err := json.Unmarshal(data, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range supportedVersions {
|
||||
if result.CNIVersion == v {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q",
|
||||
supportedVersions, result.CNIVersion)
|
||||
}
|
||||
|
||||
func GetResult(r types.Result) (*Result, error) {
|
||||
resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, ok := resultCurrent.(*Result)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to convert result")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func NewResultFromResult(result types.Result) (*Result, error) {
|
||||
newResult, err := convert.Convert(result, ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newResult.(*Result), nil
|
||||
}
|
||||
|
||||
// Result is what gets returned from the plugin (via stdout) to the caller
|
||||
type Result struct {
|
||||
CNIVersion string `json:"cniVersion,omitempty"`
|
||||
Interfaces []*Interface `json:"interfaces,omitempty"`
|
||||
IPs []*IPConfig `json:"ips,omitempty"`
|
||||
Routes []*types.Route `json:"routes,omitempty"`
|
||||
DNS types.DNS `json:"dns,omitempty"`
|
||||
}
|
||||
|
||||
func convert020IPConfig(from *types020.IPConfig, ipVersion string) *IPConfig {
|
||||
return &IPConfig{
|
||||
Version: ipVersion,
|
||||
Address: from.IP,
|
||||
Gateway: from.Gateway,
|
||||
}
|
||||
}
|
||||
|
||||
func convertFrom02x(from types.Result, toVersion string) (types.Result, error) {
|
||||
fromResult := from.(*types020.Result)
|
||||
toResult := &Result{
|
||||
CNIVersion: toVersion,
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
Routes: []*types.Route{},
|
||||
}
|
||||
if fromResult.IP4 != nil {
|
||||
toResult.IPs = append(toResult.IPs, convert020IPConfig(fromResult.IP4, "4"))
|
||||
for _, fromRoute := range fromResult.IP4.Routes {
|
||||
toResult.Routes = append(toResult.Routes, fromRoute.Copy())
|
||||
}
|
||||
}
|
||||
|
||||
if fromResult.IP6 != nil {
|
||||
toResult.IPs = append(toResult.IPs, convert020IPConfig(fromResult.IP6, "6"))
|
||||
for _, fromRoute := range fromResult.IP6.Routes {
|
||||
toResult.Routes = append(toResult.Routes, fromRoute.Copy())
|
||||
}
|
||||
}
|
||||
|
||||
return toResult, nil
|
||||
}
|
||||
|
||||
func convertInternal(from types.Result, toVersion string) (types.Result, error) {
|
||||
fromResult := from.(*Result)
|
||||
toResult := &Result{
|
||||
CNIVersion: toVersion,
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
Routes: []*types.Route{},
|
||||
}
|
||||
for _, fromIntf := range fromResult.Interfaces {
|
||||
toResult.Interfaces = append(toResult.Interfaces, fromIntf.Copy())
|
||||
}
|
||||
for _, fromIPC := range fromResult.IPs {
|
||||
toResult.IPs = append(toResult.IPs, fromIPC.Copy())
|
||||
}
|
||||
for _, fromRoute := range fromResult.Routes {
|
||||
toResult.Routes = append(toResult.Routes, fromRoute.Copy())
|
||||
}
|
||||
return toResult, nil
|
||||
}
|
||||
|
||||
func convertTo02x(from types.Result, toVersion string) (types.Result, error) {
|
||||
fromResult := from.(*Result)
|
||||
toResult := &types020.Result{
|
||||
CNIVersion: toVersion,
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
}
|
||||
|
||||
for _, fromIP := range fromResult.IPs {
|
||||
// Only convert the first IP address of each version as 0.2.0
|
||||
// and earlier cannot handle multiple IP addresses
|
||||
if fromIP.Version == "4" && toResult.IP4 == nil {
|
||||
toResult.IP4 = &types020.IPConfig{
|
||||
IP: fromIP.Address,
|
||||
Gateway: fromIP.Gateway,
|
||||
}
|
||||
} else if fromIP.Version == "6" && toResult.IP6 == nil {
|
||||
toResult.IP6 = &types020.IPConfig{
|
||||
IP: fromIP.Address,
|
||||
Gateway: fromIP.Gateway,
|
||||
}
|
||||
}
|
||||
if toResult.IP4 != nil && toResult.IP6 != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, fromRoute := range fromResult.Routes {
|
||||
is4 := fromRoute.Dst.IP.To4() != nil
|
||||
if is4 && toResult.IP4 != nil {
|
||||
toResult.IP4.Routes = append(toResult.IP4.Routes, types.Route{
|
||||
Dst: fromRoute.Dst,
|
||||
GW: fromRoute.GW,
|
||||
})
|
||||
} else if !is4 && toResult.IP6 != nil {
|
||||
toResult.IP6.Routes = append(toResult.IP6.Routes, types.Route{
|
||||
Dst: fromRoute.Dst,
|
||||
GW: fromRoute.GW,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 0.2.0 and earlier require at least one IP address in the Result
|
||||
if toResult.IP4 == nil && toResult.IP6 == nil {
|
||||
return nil, fmt.Errorf("cannot convert: no valid IP addresses")
|
||||
}
|
||||
|
||||
return toResult, nil
|
||||
}
|
||||
|
||||
func (r *Result) Version() string {
|
||||
return r.CNIVersion
|
||||
}
|
||||
|
||||
func (r *Result) GetAsVersion(version string) (types.Result, error) {
|
||||
// If the creator of the result did not set the CNIVersion, assume it
|
||||
// should be the highest spec version implemented by this Result
|
||||
if r.CNIVersion == "" {
|
||||
r.CNIVersion = ImplementedSpecVersion
|
||||
}
|
||||
return convert.Convert(r, version)
|
||||
}
|
||||
|
||||
func (r *Result) Print() error {
|
||||
return r.PrintTo(os.Stdout)
|
||||
}
|
||||
|
||||
func (r *Result) PrintTo(writer io.Writer) error {
|
||||
data, err := json.MarshalIndent(r, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = writer.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// Interface contains values about the created interfaces
|
||||
type Interface struct {
|
||||
Name string `json:"name"`
|
||||
Mac string `json:"mac,omitempty"`
|
||||
Sandbox string `json:"sandbox,omitempty"`
|
||||
}
|
||||
|
||||
func (i *Interface) String() string {
|
||||
return fmt.Sprintf("%+v", *i)
|
||||
}
|
||||
|
||||
func (i *Interface) Copy() *Interface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
newIntf := *i
|
||||
return &newIntf
|
||||
}
|
||||
|
||||
// Int returns a pointer to the int value passed in. Used to
|
||||
// set the IPConfig.Interface field.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// IPConfig contains values necessary to configure an IP address on an interface
|
||||
type IPConfig struct {
|
||||
// IP version, either "4" or "6"
|
||||
Version string
|
||||
// Index into Result structs Interfaces list
|
||||
Interface *int
|
||||
Address net.IPNet
|
||||
Gateway net.IP
|
||||
}
|
||||
|
||||
func (i *IPConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *i)
|
||||
}
|
||||
|
||||
func (i *IPConfig) Copy() *IPConfig {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ipc := &IPConfig{
|
||||
Version: i.Version,
|
||||
Address: i.Address,
|
||||
Gateway: i.Gateway,
|
||||
}
|
||||
if i.Interface != nil {
|
||||
intf := *i.Interface
|
||||
ipc.Interface = &intf
|
||||
}
|
||||
return ipc
|
||||
}
|
||||
|
||||
// JSON (un)marshallable types
|
||||
type ipConfig struct {
|
||||
Version string `json:"version"`
|
||||
Interface *int `json:"interface,omitempty"`
|
||||
Address types.IPNet `json:"address"`
|
||||
Gateway net.IP `json:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
func (c *IPConfig) MarshalJSON() ([]byte, error) {
|
||||
ipc := ipConfig{
|
||||
Version: c.Version,
|
||||
Interface: c.Interface,
|
||||
Address: types.IPNet(c.Address),
|
||||
Gateway: c.Gateway,
|
||||
}
|
||||
|
||||
return json.Marshal(ipc)
|
||||
}
|
||||
|
||||
func (c *IPConfig) UnmarshalJSON(data []byte) error {
|
||||
ipc := ipConfig{}
|
||||
if err := json.Unmarshal(data, &ipc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Version = ipc.Version
|
||||
c.Interface = ipc.Interface
|
||||
c.Address = net.IPNet(ipc.Address)
|
||||
c.Gateway = ipc.Gateway
|
||||
return nil
|
||||
}
|
307
vendor/github.com/containernetworking/cni/pkg/types/100/types.go
generated
vendored
Normal file
307
vendor/github.com/containernetworking/cni/pkg/types/100/types.go
generated
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 types100
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
types040 "github.com/containernetworking/cni/pkg/types/040"
|
||||
convert "github.com/containernetworking/cni/pkg/types/internal"
|
||||
)
|
||||
|
||||
const ImplementedSpecVersion string = "1.0.0"
|
||||
|
||||
var supportedVersions = []string{ImplementedSpecVersion}
|
||||
|
||||
// Register converters for all versions less than the implemented spec version
|
||||
func init() {
|
||||
// Up-converters
|
||||
convert.RegisterConverter("0.1.0", supportedVersions, convertFrom02x)
|
||||
convert.RegisterConverter("0.2.0", supportedVersions, convertFrom02x)
|
||||
convert.RegisterConverter("0.3.0", supportedVersions, convertFrom04x)
|
||||
convert.RegisterConverter("0.3.1", supportedVersions, convertFrom04x)
|
||||
convert.RegisterConverter("0.4.0", supportedVersions, convertFrom04x)
|
||||
|
||||
// Down-converters
|
||||
convert.RegisterConverter("1.0.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x)
|
||||
convert.RegisterConverter("1.0.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
|
||||
|
||||
// Creator
|
||||
convert.RegisterCreator(supportedVersions, NewResult)
|
||||
}
|
||||
|
||||
func NewResult(data []byte) (types.Result, error) {
|
||||
result := &Result{}
|
||||
if err := json.Unmarshal(data, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range supportedVersions {
|
||||
if result.CNIVersion == v {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q",
|
||||
supportedVersions, result.CNIVersion)
|
||||
}
|
||||
|
||||
func GetResult(r types.Result) (*Result, error) {
|
||||
resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, ok := resultCurrent.(*Result)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to convert result")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func NewResultFromResult(result types.Result) (*Result, error) {
|
||||
newResult, err := convert.Convert(result, ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newResult.(*Result), nil
|
||||
}
|
||||
|
||||
// Result is what gets returned from the plugin (via stdout) to the caller
|
||||
type Result struct {
|
||||
CNIVersion string `json:"cniVersion,omitempty"`
|
||||
Interfaces []*Interface `json:"interfaces,omitempty"`
|
||||
IPs []*IPConfig `json:"ips,omitempty"`
|
||||
Routes []*types.Route `json:"routes,omitempty"`
|
||||
DNS types.DNS `json:"dns,omitempty"`
|
||||
}
|
||||
|
||||
func convertFrom02x(from types.Result, toVersion string) (types.Result, error) {
|
||||
result040, err := convert.Convert(from, "0.4.0")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result100, err := convertFrom04x(result040, ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result100, nil
|
||||
}
|
||||
|
||||
func convertIPConfigFrom040(from *types040.IPConfig) *IPConfig {
|
||||
to := &IPConfig{
|
||||
Address: from.Address,
|
||||
Gateway: from.Gateway,
|
||||
}
|
||||
if from.Interface != nil {
|
||||
intf := *from.Interface
|
||||
to.Interface = &intf
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
||||
func convertInterfaceFrom040(from *types040.Interface) *Interface {
|
||||
return &Interface{
|
||||
Name: from.Name,
|
||||
Mac: from.Mac,
|
||||
Sandbox: from.Sandbox,
|
||||
}
|
||||
}
|
||||
|
||||
func convertFrom04x(from types.Result, toVersion string) (types.Result, error) {
|
||||
fromResult := from.(*types040.Result)
|
||||
toResult := &Result{
|
||||
CNIVersion: toVersion,
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
Routes: []*types.Route{},
|
||||
}
|
||||
for _, fromIntf := range fromResult.Interfaces {
|
||||
toResult.Interfaces = append(toResult.Interfaces, convertInterfaceFrom040(fromIntf))
|
||||
}
|
||||
for _, fromIPC := range fromResult.IPs {
|
||||
toResult.IPs = append(toResult.IPs, convertIPConfigFrom040(fromIPC))
|
||||
}
|
||||
for _, fromRoute := range fromResult.Routes {
|
||||
toResult.Routes = append(toResult.Routes, fromRoute.Copy())
|
||||
}
|
||||
return toResult, nil
|
||||
}
|
||||
|
||||
func convertIPConfigTo040(from *IPConfig) *types040.IPConfig {
|
||||
version := "6"
|
||||
if from.Address.IP.To4() != nil {
|
||||
version = "4"
|
||||
}
|
||||
to := &types040.IPConfig{
|
||||
Version: version,
|
||||
Address: from.Address,
|
||||
Gateway: from.Gateway,
|
||||
}
|
||||
if from.Interface != nil {
|
||||
intf := *from.Interface
|
||||
to.Interface = &intf
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
||||
func convertInterfaceTo040(from *Interface) *types040.Interface {
|
||||
return &types040.Interface{
|
||||
Name: from.Name,
|
||||
Mac: from.Mac,
|
||||
Sandbox: from.Sandbox,
|
||||
}
|
||||
}
|
||||
|
||||
func convertTo04x(from types.Result, toVersion string) (types.Result, error) {
|
||||
fromResult := from.(*Result)
|
||||
toResult := &types040.Result{
|
||||
CNIVersion: toVersion,
|
||||
DNS: *fromResult.DNS.Copy(),
|
||||
Routes: []*types.Route{},
|
||||
}
|
||||
for _, fromIntf := range fromResult.Interfaces {
|
||||
toResult.Interfaces = append(toResult.Interfaces, convertInterfaceTo040(fromIntf))
|
||||
}
|
||||
for _, fromIPC := range fromResult.IPs {
|
||||
toResult.IPs = append(toResult.IPs, convertIPConfigTo040(fromIPC))
|
||||
}
|
||||
for _, fromRoute := range fromResult.Routes {
|
||||
toResult.Routes = append(toResult.Routes, fromRoute.Copy())
|
||||
}
|
||||
return toResult, nil
|
||||
}
|
||||
|
||||
func convertTo02x(from types.Result, toVersion string) (types.Result, error) {
|
||||
// First convert to 0.4.0
|
||||
result040, err := convertTo04x(from, "0.4.0")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result02x, err := convert.Convert(result040, toVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result02x, nil
|
||||
}
|
||||
|
||||
func (r *Result) Version() string {
|
||||
return r.CNIVersion
|
||||
}
|
||||
|
||||
func (r *Result) GetAsVersion(version string) (types.Result, error) {
|
||||
// If the creator of the result did not set the CNIVersion, assume it
|
||||
// should be the highest spec version implemented by this Result
|
||||
if r.CNIVersion == "" {
|
||||
r.CNIVersion = ImplementedSpecVersion
|
||||
}
|
||||
return convert.Convert(r, version)
|
||||
}
|
||||
|
||||
func (r *Result) Print() error {
|
||||
return r.PrintTo(os.Stdout)
|
||||
}
|
||||
|
||||
func (r *Result) PrintTo(writer io.Writer) error {
|
||||
data, err := json.MarshalIndent(r, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = writer.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// Interface contains values about the created interfaces
|
||||
type Interface struct {
|
||||
Name string `json:"name"`
|
||||
Mac string `json:"mac,omitempty"`
|
||||
Sandbox string `json:"sandbox,omitempty"`
|
||||
}
|
||||
|
||||
func (i *Interface) String() string {
|
||||
return fmt.Sprintf("%+v", *i)
|
||||
}
|
||||
|
||||
func (i *Interface) Copy() *Interface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
newIntf := *i
|
||||
return &newIntf
|
||||
}
|
||||
|
||||
// Int returns a pointer to the int value passed in. Used to
|
||||
// set the IPConfig.Interface field.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// IPConfig contains values necessary to configure an IP address on an interface
|
||||
type IPConfig struct {
|
||||
// Index into Result structs Interfaces list
|
||||
Interface *int
|
||||
Address net.IPNet
|
||||
Gateway net.IP
|
||||
}
|
||||
|
||||
func (i *IPConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *i)
|
||||
}
|
||||
|
||||
func (i *IPConfig) Copy() *IPConfig {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ipc := &IPConfig{
|
||||
Address: i.Address,
|
||||
Gateway: i.Gateway,
|
||||
}
|
||||
if i.Interface != nil {
|
||||
intf := *i.Interface
|
||||
ipc.Interface = &intf
|
||||
}
|
||||
return ipc
|
||||
}
|
||||
|
||||
// JSON (un)marshallable types
|
||||
type ipConfig struct {
|
||||
Interface *int `json:"interface,omitempty"`
|
||||
Address types.IPNet `json:"address"`
|
||||
Gateway net.IP `json:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
func (c *IPConfig) MarshalJSON() ([]byte, error) {
|
||||
ipc := ipConfig{
|
||||
Interface: c.Interface,
|
||||
Address: types.IPNet(c.Address),
|
||||
Gateway: c.Gateway,
|
||||
}
|
||||
|
||||
return json.Marshal(ipc)
|
||||
}
|
||||
|
||||
func (c *IPConfig) UnmarshalJSON(data []byte) error {
|
||||
ipc := ipConfig{}
|
||||
if err := json.Unmarshal(data, &ipc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Interface = ipc.Interface
|
||||
c.Address = net.IPNet(ipc.Address)
|
||||
c.Gateway = ipc.Gateway
|
||||
return nil
|
||||
}
|
20
vendor/github.com/containernetworking/cni/pkg/types/args.go
generated
vendored
20
vendor/github.com/containernetworking/cni/pkg/types/args.go
generated
vendored
@@ -36,7 +36,7 @@ func (b *UnmarshallableBool) UnmarshalText(data []byte) error {
|
||||
case "0", "false":
|
||||
*b = false
|
||||
default:
|
||||
return fmt.Errorf("Boolean unmarshal error: invalid input %s", s)
|
||||
return fmt.Errorf("boolean unmarshal error: invalid input %s", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -91,16 +91,26 @@ func LoadArgs(args string, container interface{}) error {
|
||||
unknownArgs = append(unknownArgs, pair)
|
||||
continue
|
||||
}
|
||||
keyFieldIface := keyField.Addr().Interface()
|
||||
u, ok := keyFieldIface.(encoding.TextUnmarshaler)
|
||||
|
||||
var keyFieldInterface interface{}
|
||||
switch {
|
||||
case keyField.Kind() == reflect.Ptr:
|
||||
keyField.Set(reflect.New(keyField.Type().Elem()))
|
||||
keyFieldInterface = keyField.Interface()
|
||||
case keyField.CanAddr() && keyField.Addr().CanInterface():
|
||||
keyFieldInterface = keyField.Addr().Interface()
|
||||
default:
|
||||
return UnmarshalableArgsError{fmt.Errorf("field '%s' has no valid interface", keyString)}
|
||||
}
|
||||
u, ok := keyFieldInterface.(encoding.TextUnmarshaler)
|
||||
if !ok {
|
||||
return UnmarshalableArgsError{fmt.Errorf(
|
||||
"ARGS: cannot unmarshal into field '%s' - type '%s' does not implement encoding.TextUnmarshaler",
|
||||
keyString, reflect.TypeOf(keyFieldIface))}
|
||||
keyString, reflect.TypeOf(keyFieldInterface))}
|
||||
}
|
||||
err := u.UnmarshalText([]byte(valueString))
|
||||
if err != nil {
|
||||
return fmt.Errorf("ARGS: error parsing value of pair %q: %v)", pair, err)
|
||||
return fmt.Errorf("ARGS: error parsing value of pair %q: %w", pair, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
56
vendor/github.com/containernetworking/cni/pkg/types/create/create.go
generated
vendored
Normal file
56
vendor/github.com/containernetworking/cni/pkg/types/create/create.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 create
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
convert "github.com/containernetworking/cni/pkg/types/internal"
|
||||
)
|
||||
|
||||
// DecodeVersion returns the CNI version from CNI configuration or result JSON,
|
||||
// or an error if the operation could not be performed.
|
||||
func DecodeVersion(jsonBytes []byte) (string, error) {
|
||||
var conf struct {
|
||||
CNIVersion string `json:"cniVersion"`
|
||||
}
|
||||
err := json.Unmarshal(jsonBytes, &conf)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("decoding version from network config: %w", err)
|
||||
}
|
||||
if conf.CNIVersion == "" {
|
||||
return "0.1.0", nil
|
||||
}
|
||||
return conf.CNIVersion, nil
|
||||
}
|
||||
|
||||
// Create creates a CNI Result using the given JSON with the expected
|
||||
// version, or an error if the creation could not be performed
|
||||
func Create(version string, bytes []byte) (types.Result, error) {
|
||||
return convert.Create(version, bytes)
|
||||
}
|
||||
|
||||
// CreateFromBytes creates a CNI Result from the given JSON, automatically
|
||||
// detecting the CNI spec version of the result. An error is returned if the
|
||||
// operation could not be performed.
|
||||
func CreateFromBytes(bytes []byte) (types.Result, error) {
|
||||
version, err := DecodeVersion(bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return convert.Create(version, bytes)
|
||||
}
|
300
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
generated
vendored
300
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
generated
vendored
@@ -1,300 +0,0 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 current
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/020"
|
||||
)
|
||||
|
||||
const ImplementedSpecVersion string = "0.3.1"
|
||||
|
||||
var SupportedVersions = []string{"0.3.0", ImplementedSpecVersion}
|
||||
|
||||
func NewResult(data []byte) (types.Result, error) {
|
||||
result := &Result{}
|
||||
if err := json.Unmarshal(data, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func GetResult(r types.Result) (*Result, error) {
|
||||
resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, ok := resultCurrent.(*Result)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to convert result")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var resultConverters = []struct {
|
||||
versions []string
|
||||
convert func(types.Result) (*Result, error)
|
||||
}{
|
||||
{types020.SupportedVersions, convertFrom020},
|
||||
{SupportedVersions, convertFrom030},
|
||||
}
|
||||
|
||||
func convertFrom020(result types.Result) (*Result, error) {
|
||||
oldResult, err := types020.GetResult(result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newResult := &Result{
|
||||
CNIVersion: ImplementedSpecVersion,
|
||||
DNS: oldResult.DNS,
|
||||
Routes: []*types.Route{},
|
||||
}
|
||||
|
||||
if oldResult.IP4 != nil {
|
||||
newResult.IPs = append(newResult.IPs, &IPConfig{
|
||||
Version: "4",
|
||||
Address: oldResult.IP4.IP,
|
||||
Gateway: oldResult.IP4.Gateway,
|
||||
})
|
||||
for _, route := range oldResult.IP4.Routes {
|
||||
gw := route.GW
|
||||
if gw == nil {
|
||||
gw = oldResult.IP4.Gateway
|
||||
}
|
||||
newResult.Routes = append(newResult.Routes, &types.Route{
|
||||
Dst: route.Dst,
|
||||
GW: gw,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if oldResult.IP6 != nil {
|
||||
newResult.IPs = append(newResult.IPs, &IPConfig{
|
||||
Version: "6",
|
||||
Address: oldResult.IP6.IP,
|
||||
Gateway: oldResult.IP6.Gateway,
|
||||
})
|
||||
for _, route := range oldResult.IP6.Routes {
|
||||
gw := route.GW
|
||||
if gw == nil {
|
||||
gw = oldResult.IP6.Gateway
|
||||
}
|
||||
newResult.Routes = append(newResult.Routes, &types.Route{
|
||||
Dst: route.Dst,
|
||||
GW: gw,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(newResult.IPs) == 0 {
|
||||
return nil, fmt.Errorf("cannot convert: no valid IP addresses")
|
||||
}
|
||||
|
||||
return newResult, nil
|
||||
}
|
||||
|
||||
func convertFrom030(result types.Result) (*Result, error) {
|
||||
newResult, ok := result.(*Result)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to convert result")
|
||||
}
|
||||
newResult.CNIVersion = ImplementedSpecVersion
|
||||
return newResult, nil
|
||||
}
|
||||
|
||||
func NewResultFromResult(result types.Result) (*Result, error) {
|
||||
version := result.Version()
|
||||
for _, converter := range resultConverters {
|
||||
for _, supportedVersion := range converter.versions {
|
||||
if version == supportedVersion {
|
||||
return converter.convert(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported CNI result22 version %q", version)
|
||||
}
|
||||
|
||||
// Result is what gets returned from the plugin (via stdout) to the caller
|
||||
type Result struct {
|
||||
CNIVersion string `json:"cniVersion,omitempty"`
|
||||
Interfaces []*Interface `json:"interfaces,omitempty"`
|
||||
IPs []*IPConfig `json:"ips,omitempty"`
|
||||
Routes []*types.Route `json:"routes,omitempty"`
|
||||
DNS types.DNS `json:"dns,omitempty"`
|
||||
}
|
||||
|
||||
// Convert to the older 0.2.0 CNI spec Result type
|
||||
func (r *Result) convertTo020() (*types020.Result, error) {
|
||||
oldResult := &types020.Result{
|
||||
CNIVersion: types020.ImplementedSpecVersion,
|
||||
DNS: r.DNS,
|
||||
}
|
||||
|
||||
for _, ip := range r.IPs {
|
||||
// Only convert the first IP address of each version as 0.2.0
|
||||
// and earlier cannot handle multiple IP addresses
|
||||
if ip.Version == "4" && oldResult.IP4 == nil {
|
||||
oldResult.IP4 = &types020.IPConfig{
|
||||
IP: ip.Address,
|
||||
Gateway: ip.Gateway,
|
||||
}
|
||||
} else if ip.Version == "6" && oldResult.IP6 == nil {
|
||||
oldResult.IP6 = &types020.IPConfig{
|
||||
IP: ip.Address,
|
||||
Gateway: ip.Gateway,
|
||||
}
|
||||
}
|
||||
|
||||
if oldResult.IP4 != nil && oldResult.IP6 != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, route := range r.Routes {
|
||||
is4 := route.Dst.IP.To4() != nil
|
||||
if is4 && oldResult.IP4 != nil {
|
||||
oldResult.IP4.Routes = append(oldResult.IP4.Routes, types.Route{
|
||||
Dst: route.Dst,
|
||||
GW: route.GW,
|
||||
})
|
||||
} else if !is4 && oldResult.IP6 != nil {
|
||||
oldResult.IP6.Routes = append(oldResult.IP6.Routes, types.Route{
|
||||
Dst: route.Dst,
|
||||
GW: route.GW,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if oldResult.IP4 == nil && oldResult.IP6 == nil {
|
||||
return nil, fmt.Errorf("cannot convert: no valid IP addresses")
|
||||
}
|
||||
|
||||
return oldResult, nil
|
||||
}
|
||||
|
||||
func (r *Result) Version() string {
|
||||
return ImplementedSpecVersion
|
||||
}
|
||||
|
||||
func (r *Result) GetAsVersion(version string) (types.Result, error) {
|
||||
switch version {
|
||||
case "0.3.0", ImplementedSpecVersion:
|
||||
r.CNIVersion = version
|
||||
return r, nil
|
||||
case types020.SupportedVersions[0], types020.SupportedVersions[1], types020.SupportedVersions[2]:
|
||||
return r.convertTo020()
|
||||
}
|
||||
return nil, fmt.Errorf("cannot convert version 0.3.x to %q", version)
|
||||
}
|
||||
|
||||
func (r *Result) Print() error {
|
||||
data, err := json.MarshalIndent(r, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = os.Stdout.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns a formatted string in the form of "[Interfaces: $1,][ IP: $2,] DNS: $3" where
|
||||
// $1 represents the receiver's Interfaces, $2 represents the receiver's IP addresses and $3 the
|
||||
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
||||
func (r *Result) String() string {
|
||||
var str string
|
||||
if len(r.Interfaces) > 0 {
|
||||
str += fmt.Sprintf("Interfaces:%+v, ", r.Interfaces)
|
||||
}
|
||||
if len(r.IPs) > 0 {
|
||||
str += fmt.Sprintf("IP:%+v, ", r.IPs)
|
||||
}
|
||||
if len(r.Routes) > 0 {
|
||||
str += fmt.Sprintf("Routes:%+v, ", r.Routes)
|
||||
}
|
||||
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
||||
}
|
||||
|
||||
// Convert this old version result to the current CNI version result
|
||||
func (r *Result) Convert() (*Result, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Interface contains values about the created interfaces
|
||||
type Interface struct {
|
||||
Name string `json:"name"`
|
||||
Mac string `json:"mac,omitempty"`
|
||||
Sandbox string `json:"sandbox,omitempty"`
|
||||
}
|
||||
|
||||
func (i *Interface) String() string {
|
||||
return fmt.Sprintf("%+v", *i)
|
||||
}
|
||||
|
||||
// Int returns a pointer to the int value passed in. Used to
|
||||
// set the IPConfig.Interface field.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// IPConfig contains values necessary to configure an IP address on an interface
|
||||
type IPConfig struct {
|
||||
// IP version, either "4" or "6"
|
||||
Version string
|
||||
// Index into Result structs Interfaces list
|
||||
Interface *int
|
||||
Address net.IPNet
|
||||
Gateway net.IP
|
||||
}
|
||||
|
||||
func (i *IPConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *i)
|
||||
}
|
||||
|
||||
// JSON (un)marshallable types
|
||||
type ipConfig struct {
|
||||
Version string `json:"version"`
|
||||
Interface *int `json:"interface,omitempty"`
|
||||
Address types.IPNet `json:"address"`
|
||||
Gateway net.IP `json:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
func (c *IPConfig) MarshalJSON() ([]byte, error) {
|
||||
ipc := ipConfig{
|
||||
Version: c.Version,
|
||||
Interface: c.Interface,
|
||||
Address: types.IPNet(c.Address),
|
||||
Gateway: c.Gateway,
|
||||
}
|
||||
|
||||
return json.Marshal(ipc)
|
||||
}
|
||||
|
||||
func (c *IPConfig) UnmarshalJSON(data []byte) error {
|
||||
ipc := ipConfig{}
|
||||
if err := json.Unmarshal(data, &ipc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Version = ipc.Version
|
||||
c.Interface = ipc.Interface
|
||||
c.Address = net.IPNet(ipc.Address)
|
||||
c.Gateway = ipc.Gateway
|
||||
return nil
|
||||
}
|
92
vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go
generated
vendored
Normal file
92
vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 convert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
// ConvertFn should convert from the given arbitrary Result type into a
|
||||
// Result implementing CNI specification version passed in toVersion.
|
||||
// The function is guaranteed to be passed a Result type matching the
|
||||
// fromVersion it was registered with, and is guaranteed to be
|
||||
// passed a toVersion matching one of the toVersions it was registered with.
|
||||
type ConvertFn func(from types.Result, toVersion string) (types.Result, error)
|
||||
|
||||
type converter struct {
|
||||
// fromVersion is the CNI Result spec version that convertFn accepts
|
||||
fromVersion string
|
||||
// toVersions is a list of versions that convertFn can convert to
|
||||
toVersions []string
|
||||
convertFn ConvertFn
|
||||
}
|
||||
|
||||
var converters []*converter
|
||||
|
||||
func findConverter(fromVersion, toVersion string) *converter {
|
||||
for _, c := range converters {
|
||||
if c.fromVersion == fromVersion {
|
||||
for _, v := range c.toVersions {
|
||||
if v == toVersion {
|
||||
return c
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert converts a CNI Result to the requested CNI specification version,
|
||||
// or returns an error if the conversion could not be performed or failed
|
||||
func Convert(from types.Result, toVersion string) (types.Result, error) {
|
||||
if toVersion == "" {
|
||||
toVersion = "0.1.0"
|
||||
}
|
||||
|
||||
fromVersion := from.Version()
|
||||
|
||||
// Shortcut for same version
|
||||
if fromVersion == toVersion {
|
||||
return from, nil
|
||||
}
|
||||
|
||||
// Otherwise find the right converter
|
||||
c := findConverter(fromVersion, toVersion)
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("no converter for CNI result version %s to %s",
|
||||
fromVersion, toVersion)
|
||||
}
|
||||
return c.convertFn(from, toVersion)
|
||||
}
|
||||
|
||||
// RegisterConverter registers a CNI Result converter. SHOULD NOT BE CALLED
|
||||
// EXCEPT FROM CNI ITSELF.
|
||||
func RegisterConverter(fromVersion string, toVersions []string, convertFn ConvertFn) {
|
||||
// Make sure there is no converter already registered for these
|
||||
// from and to versions
|
||||
for _, v := range toVersions {
|
||||
if findConverter(fromVersion, v) != nil {
|
||||
panic(fmt.Sprintf("converter already registered for %s to %s",
|
||||
fromVersion, v))
|
||||
}
|
||||
}
|
||||
converters = append(converters, &converter{
|
||||
fromVersion: fromVersion,
|
||||
toVersions: toVersions,
|
||||
convertFn: convertFn,
|
||||
})
|
||||
}
|
66
vendor/github.com/containernetworking/cni/pkg/types/internal/create.go
generated
vendored
Normal file
66
vendor/github.com/containernetworking/cni/pkg/types/internal/create.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 convert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
type ResultFactoryFunc func([]byte) (types.Result, error)
|
||||
|
||||
type creator struct {
|
||||
// CNI Result spec versions that createFn can create a Result for
|
||||
versions []string
|
||||
createFn ResultFactoryFunc
|
||||
}
|
||||
|
||||
var creators []*creator
|
||||
|
||||
func findCreator(version string) *creator {
|
||||
for _, c := range creators {
|
||||
for _, v := range c.versions {
|
||||
if v == version {
|
||||
return c
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create creates a CNI Result using the given JSON, or an error if the creation
|
||||
// could not be performed
|
||||
func Create(version string, bytes []byte) (types.Result, error) {
|
||||
if c := findCreator(version); c != nil {
|
||||
return c.createFn(bytes)
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported CNI result version %q", version)
|
||||
}
|
||||
|
||||
// RegisterCreator registers a CNI Result creator. SHOULD NOT BE CALLED
|
||||
// EXCEPT FROM CNI ITSELF.
|
||||
func RegisterCreator(versions []string, createFn ResultFactoryFunc) {
|
||||
// Make sure there is no creator already registered for these versions
|
||||
for _, v := range versions {
|
||||
if findCreator(v) != nil {
|
||||
panic(fmt.Sprintf("creator already registered for %s", v))
|
||||
}
|
||||
}
|
||||
creators = append(creators, &creator{
|
||||
versions: versions,
|
||||
createFn: createFn,
|
||||
})
|
||||
}
|
83
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
83
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
@@ -16,8 +16,8 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
@@ -63,25 +63,29 @@ type NetConf struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Capabilities map[string]bool `json:"capabilities,omitempty"`
|
||||
IPAM struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
} `json:"ipam,omitempty"`
|
||||
DNS DNS `json:"dns"`
|
||||
IPAM IPAM `json:"ipam,omitempty"`
|
||||
DNS DNS `json:"dns"`
|
||||
|
||||
RawPrevResult map[string]interface{} `json:"prevResult,omitempty"`
|
||||
PrevResult Result `json:"-"`
|
||||
}
|
||||
|
||||
type IPAM struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// NetConfList describes an ordered list of networks.
|
||||
type NetConfList struct {
|
||||
CNIVersion string `json:"cniVersion,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Plugins []*NetConf `json:"plugins,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
DisableCheck bool `json:"disableCheck,omitempty"`
|
||||
Plugins []*NetConf `json:"plugins,omitempty"`
|
||||
}
|
||||
|
||||
type ResultFactoryFunc func([]byte) (Result, error)
|
||||
|
||||
// Result is an interface that provides the result of plugin execution
|
||||
type Result interface {
|
||||
// The highest CNI specification result verison the result supports
|
||||
// The highest CNI specification result version the result supports
|
||||
// without having to convert
|
||||
Version() string
|
||||
|
||||
@@ -92,8 +96,8 @@ type Result interface {
|
||||
// Prints the result in JSON format to stdout
|
||||
Print() error
|
||||
|
||||
// Returns a JSON string representation of the result
|
||||
String() string
|
||||
// Prints the result in JSON format to provided writer
|
||||
PrintTo(writer io.Writer) error
|
||||
}
|
||||
|
||||
func PrintResult(result Result, version string) error {
|
||||
@@ -112,6 +116,24 @@ type DNS struct {
|
||||
Options []string `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (d *DNS) Copy() *DNS {
|
||||
if d == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
to := &DNS{Domain: d.Domain}
|
||||
for _, ns := range d.Nameservers {
|
||||
to.Nameservers = append(to.Nameservers, ns)
|
||||
}
|
||||
for _, s := range d.Search {
|
||||
to.Search = append(to.Search, s)
|
||||
}
|
||||
for _, o := range d.Options {
|
||||
to.Options = append(to.Options, o)
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
Dst net.IPNet
|
||||
GW net.IP
|
||||
@@ -121,12 +143,30 @@ func (r *Route) String() string {
|
||||
return fmt.Sprintf("%+v", *r)
|
||||
}
|
||||
|
||||
func (r *Route) Copy() *Route {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &Route{
|
||||
Dst: r.Dst,
|
||||
GW: r.GW,
|
||||
}
|
||||
}
|
||||
|
||||
// Well known error codes
|
||||
// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes
|
||||
const (
|
||||
ErrUnknown uint = iota // 0
|
||||
ErrIncompatibleCNIVersion // 1
|
||||
ErrUnsupportedField // 2
|
||||
ErrUnknown uint = iota // 0
|
||||
ErrIncompatibleCNIVersion // 1
|
||||
ErrUnsupportedField // 2
|
||||
ErrUnknownContainer // 3
|
||||
ErrInvalidEnvironmentVariables // 4
|
||||
ErrIOFailure // 5
|
||||
ErrDecodingFailure // 6
|
||||
ErrInvalidNetworkConfig // 7
|
||||
ErrTryAgainLater uint = 11
|
||||
ErrInternal uint = 999
|
||||
)
|
||||
|
||||
type Error struct {
|
||||
@@ -135,6 +175,14 @@ type Error struct {
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
func NewError(code uint, msg, details string) *Error {
|
||||
return &Error{
|
||||
Code: code,
|
||||
Msg: msg,
|
||||
Details: details,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
details := ""
|
||||
if e.Details != "" {
|
||||
@@ -167,7 +215,7 @@ func (r *Route) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Route) MarshalJSON() ([]byte, error) {
|
||||
func (r Route) MarshalJSON() ([]byte, error) {
|
||||
rt := route{
|
||||
Dst: IPNet(r.Dst),
|
||||
GW: r.GW,
|
||||
@@ -184,6 +232,3 @@ func prettyPrint(obj interface{}) error {
|
||||
_, err = os.Stdout.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// NotImplementedError is used to indicate that a method is not implemented for the given platform
|
||||
var NotImplementedError = errors.New("Not Implemented")
|
||||
|
84
vendor/github.com/containernetworking/cni/pkg/utils/utils.go
generated
vendored
Normal file
84
vendor/github.com/containernetworking/cni/pkg/utils/utils.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2019 CNI authors
|
||||
//
|
||||
// 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 utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"unicode"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// cniValidNameChars is the regexp used to validate valid characters in
|
||||
// containerID and networkName
|
||||
cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]`
|
||||
|
||||
// maxInterfaceNameLength is the length max of a valid interface name
|
||||
maxInterfaceNameLength = 15
|
||||
)
|
||||
|
||||
var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`)
|
||||
|
||||
// ValidateContainerID will validate that the supplied containerID is not empty does not contain invalid characters
|
||||
func ValidateContainerID(containerID string) *types.Error {
|
||||
|
||||
if containerID == "" {
|
||||
return types.NewError(types.ErrUnknownContainer, "missing containerID", "")
|
||||
}
|
||||
if !cniReg.MatchString(containerID) {
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, "invalid characters in containerID", containerID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateNetworkName will validate that the supplied networkName does not contain invalid characters
|
||||
func ValidateNetworkName(networkName string) *types.Error {
|
||||
|
||||
if networkName == "" {
|
||||
return types.NewError(types.ErrInvalidNetworkConfig, "missing network name:", "")
|
||||
}
|
||||
if !cniReg.MatchString(networkName) {
|
||||
return types.NewError(types.ErrInvalidNetworkConfig, "invalid characters found in network name", networkName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateInterfaceName will validate the interface name based on the three rules below
|
||||
// 1. The name must not be empty
|
||||
// 2. The name must be less than 16 characters
|
||||
// 3. The name must not be "." or ".."
|
||||
// 3. The name must not contain / or : or any whitespace characters
|
||||
// ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024
|
||||
func ValidateInterfaceName(ifName string) *types.Error {
|
||||
if len(ifName) == 0 {
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is empty", "")
|
||||
}
|
||||
if len(ifName) > maxInterfaceNameLength {
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is too long", fmt.Sprintf("interface name should be less than %d characters", maxInterfaceNameLength+1))
|
||||
}
|
||||
if ifName == "." || ifName == ".." {
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is . or ..", "")
|
||||
}
|
||||
for _, r := range bytes.Runes([]byte(ifName)) {
|
||||
if r == '/' || r == ':' || unicode.IsSpace(r) {
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name contains / or : or whitespace characters", "")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
15
vendor/github.com/containernetworking/cni/pkg/version/conf.go
generated
vendored
15
vendor/github.com/containernetworking/cni/pkg/version/conf.go
generated
vendored
@@ -15,23 +15,12 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/containernetworking/cni/pkg/types/create"
|
||||
)
|
||||
|
||||
// ConfigDecoder can decode the CNI version available in network config data
|
||||
type ConfigDecoder struct{}
|
||||
|
||||
func (*ConfigDecoder) Decode(jsonBytes []byte) (string, error) {
|
||||
var conf struct {
|
||||
CNIVersion string `json:"cniVersion"`
|
||||
}
|
||||
err := json.Unmarshal(jsonBytes, &conf)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("decoding version from network config: %s", err)
|
||||
}
|
||||
if conf.CNIVersion == "" {
|
||||
return "0.1.0", nil
|
||||
}
|
||||
return conf.CNIVersion, nil
|
||||
return create.DecodeVersion(jsonBytes)
|
||||
}
|
||||
|
65
vendor/github.com/containernetworking/cni/pkg/version/plugin.go
generated
vendored
65
vendor/github.com/containernetworking/cni/pkg/version/plugin.go
generated
vendored
@@ -18,6 +18,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PluginInfo reports information about CNI versioning
|
||||
@@ -66,7 +68,7 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
|
||||
var info pluginInfo
|
||||
err := json.Unmarshal(jsonBytes, &info)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding version info: %s", err)
|
||||
return nil, fmt.Errorf("decoding version info: %w", err)
|
||||
}
|
||||
if info.CNIVersion_ == "" {
|
||||
return nil, fmt.Errorf("decoding version info: missing field cniVersion")
|
||||
@@ -79,3 +81,64 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// ParseVersion parses a version string like "3.0.1" or "0.4.5" into major,
|
||||
// minor, and micro numbers or returns an error
|
||||
func ParseVersion(version string) (int, int, int, error) {
|
||||
var major, minor, micro int
|
||||
if version == "" {
|
||||
return -1, -1, -1, fmt.Errorf("invalid version %q: the version is empty", version)
|
||||
}
|
||||
|
||||
parts := strings.Split(version, ".")
|
||||
if len(parts) >= 4 {
|
||||
return -1, -1, -1, fmt.Errorf("invalid version %q: too many parts", version)
|
||||
}
|
||||
|
||||
major, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return -1, -1, -1, fmt.Errorf("failed to convert major version part %q: %w", parts[0], err)
|
||||
}
|
||||
|
||||
if len(parts) >= 2 {
|
||||
minor, err = strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return -1, -1, -1, fmt.Errorf("failed to convert minor version part %q: %w", parts[1], err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(parts) >= 3 {
|
||||
micro, err = strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
return -1, -1, -1, fmt.Errorf("failed to convert micro version part %q: %w", parts[2], err)
|
||||
}
|
||||
}
|
||||
|
||||
return major, minor, micro, nil
|
||||
}
|
||||
|
||||
// GreaterThanOrEqualTo takes two string versions, parses them into major/minor/micro
|
||||
// numbers, and compares them to determine whether the first version is greater
|
||||
// than or equal to the second
|
||||
func GreaterThanOrEqualTo(version, otherVersion string) (bool, error) {
|
||||
firstMajor, firstMinor, firstMicro, err := ParseVersion(version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
secondMajor, secondMinor, secondMicro, err := ParseVersion(otherVersion)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if firstMajor > secondMajor {
|
||||
return true, nil
|
||||
} else if firstMajor == secondMajor {
|
||||
if firstMinor > secondMinor {
|
||||
return true, nil
|
||||
} else if firstMinor == secondMinor && firstMicro >= secondMicro {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
64
vendor/github.com/containernetworking/cni/pkg/version/version.go
generated
vendored
64
vendor/github.com/containernetworking/cni/pkg/version/version.go
generated
vendored
@@ -15,16 +15,17 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/020"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/cni/pkg/types/create"
|
||||
)
|
||||
|
||||
// Current reports the version of the CNI spec implemented by this library
|
||||
func Current() string {
|
||||
return "0.3.1"
|
||||
return types100.ImplementedSpecVersion
|
||||
}
|
||||
|
||||
// Legacy PluginInfo describes a plugin that is backwards compatible with the
|
||||
@@ -35,27 +36,54 @@ func Current() string {
|
||||
// Any future CNI spec versions which meet this definition should be added to
|
||||
// this list.
|
||||
var Legacy = PluginSupports("0.1.0", "0.2.0")
|
||||
var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1")
|
||||
var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0")
|
||||
|
||||
var resultFactories = []struct {
|
||||
supportedVersions []string
|
||||
newResult types.ResultFactoryFunc
|
||||
}{
|
||||
{current.SupportedVersions, current.NewResult},
|
||||
{types020.SupportedVersions, types020.NewResult},
|
||||
// VersionsFrom returns a list of versions starting from min, inclusive
|
||||
func VersionsStartingFrom(min string) PluginInfo {
|
||||
out := []string{}
|
||||
// cheat, just assume ordered
|
||||
ok := false
|
||||
for _, v := range All.SupportedVersions() {
|
||||
if !ok && v == min {
|
||||
ok = true
|
||||
}
|
||||
if ok {
|
||||
out = append(out, v)
|
||||
}
|
||||
}
|
||||
return PluginSupports(out...)
|
||||
}
|
||||
|
||||
// Finds a Result object matching the requested version (if any) and asks
|
||||
// that object to parse the plugin result, returning an error if parsing failed.
|
||||
func NewResult(version string, resultBytes []byte) (types.Result, error) {
|
||||
reconciler := &Reconciler{}
|
||||
for _, resultFactory := range resultFactories {
|
||||
err := reconciler.CheckRaw(version, resultFactory.supportedVersions)
|
||||
if err == nil {
|
||||
// Result supports this version
|
||||
return resultFactory.newResult(resultBytes)
|
||||
}
|
||||
return create.Create(version, resultBytes)
|
||||
}
|
||||
|
||||
// ParsePrevResult parses a prevResult in a NetConf structure and sets
|
||||
// the NetConf's PrevResult member to the parsed Result object.
|
||||
func ParsePrevResult(conf *types.NetConf) error {
|
||||
if conf.RawPrevResult == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported CNI result version %q", version)
|
||||
// Prior to 1.0.0, Result types may not marshal a CNIVersion. Since the
|
||||
// result version must match the config version, if the Result's version
|
||||
// is empty, inject the config version.
|
||||
if ver, ok := conf.RawPrevResult["CNIVersion"]; !ok || ver == "" {
|
||||
conf.RawPrevResult["CNIVersion"] = conf.CNIVersion
|
||||
}
|
||||
|
||||
resultBytes, err := json.Marshal(conf.RawPrevResult)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not serialize prevResult: %w", err)
|
||||
}
|
||||
|
||||
conf.RawPrevResult = nil
|
||||
conf.PrevResult, err = create.Create(conf.CNIVersion, resultBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse prevResult: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
105
vendor/github.com/containernetworking/plugins/pkg/ip/ip.go
generated
vendored
Normal file
105
vendor/github.com/containernetworking/plugins/pkg/ip/ip.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2021 CNI authors
|
||||
//
|
||||
// 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 ip
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IP is a CNI maintained type inherited from net.IPNet which can
|
||||
// represent a single IP address with or without prefix.
|
||||
type IP struct {
|
||||
net.IPNet
|
||||
}
|
||||
|
||||
// newIP will create an IP with net.IP and net.IPMask
|
||||
func newIP(ip net.IP, mask net.IPMask) *IP {
|
||||
return &IP{
|
||||
IPNet: net.IPNet{
|
||||
IP: ip,
|
||||
Mask: mask,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ParseIP will parse string s as an IP, and return it.
|
||||
// The string s must be formed like <ip>[/<prefix>].
|
||||
// If s is not a valid textual representation of an IP,
|
||||
// will return nil.
|
||||
func ParseIP(s string) *IP {
|
||||
if strings.ContainsAny(s, "/") {
|
||||
ip, ipNet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return newIP(ip, ipNet.Mask)
|
||||
} else {
|
||||
ip := net.ParseIP(s)
|
||||
if ip == nil {
|
||||
return nil
|
||||
}
|
||||
return newIP(ip, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// ToIP will return a net.IP in standard form from this IP.
|
||||
// If this IP can not be converted to a valid net.IP, will return nil.
|
||||
func (i *IP) ToIP() net.IP {
|
||||
switch {
|
||||
case i.IP.To4() != nil:
|
||||
return i.IP.To4()
|
||||
case i.IP.To16() != nil:
|
||||
return i.IP.To16()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the string form of this IP.
|
||||
func (i *IP) String() string {
|
||||
if len(i.Mask) > 0 {
|
||||
return i.IPNet.String()
|
||||
}
|
||||
return i.IP.String()
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
// The encoding is the same as returned by String,
|
||||
// But when len(ip) is zero, will return an empty slice.
|
||||
func (i *IP) MarshalText() ([]byte, error) {
|
||||
if len(i.IP) == 0 {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return []byte(i.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// The textual bytes are expected in a form accepted by Parse,
|
||||
// But when len(b) is zero, will return an empty IP.
|
||||
func (i *IP) UnmarshalText(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
*i = IP{}
|
||||
return nil
|
||||
}
|
||||
|
||||
ip := ParseIP(string(b))
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid IP address %s", string(b))
|
||||
}
|
||||
*i = *ip
|
||||
return nil
|
||||
}
|
@@ -15,9 +15,10 @@
|
||||
package ip
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
)
|
||||
|
||||
func EnableIP4Forward() error {
|
||||
@@ -35,12 +36,13 @@ func EnableForward(ips []*current.IPConfig) error {
|
||||
v6 := false
|
||||
|
||||
for _, ip := range ips {
|
||||
if ip.Version == "4" && !v4 {
|
||||
isV4 := ip.Address.IP.To4() != nil
|
||||
if isV4 && !v4 {
|
||||
if err := EnableIP4Forward(); err != nil {
|
||||
return err
|
||||
}
|
||||
v4 = true
|
||||
} else if ip.Version == "6" && !v6 {
|
||||
} else if !isV4 && !v6 {
|
||||
if err := EnableIP6Forward(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -51,5 +53,10 @@ func EnableForward(ips []*current.IPConfig) error {
|
||||
}
|
||||
|
||||
func echo1(f string) error {
|
||||
if content, err := ioutil.ReadFile(f); err == nil {
|
||||
if bytes.Equal(bytes.TrimSpace(content), []byte("1")) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return ioutil.WriteFile(f, []byte("1"), 0644)
|
||||
}
|
@@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
// SetupIPMasq installs iptables rules to masquerade traffic
|
||||
// coming from ipn and going outside of it
|
||||
// coming from ip of ipn and going outside of ipn
|
||||
func SetupIPMasq(ipn *net.IPNet, chain string, comment string) error {
|
||||
isV6 := ipn.IP.To4() == nil
|
||||
|
||||
@@ -70,23 +70,57 @@ func SetupIPMasq(ipn *net.IPNet, chain string, comment string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return ipt.AppendUnique("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain, "-m", "comment", "--comment", comment)
|
||||
// Packets from the specific IP of this network will hit the chain
|
||||
return ipt.AppendUnique("nat", "POSTROUTING", "-s", ipn.IP.String(), "-j", chain, "-m", "comment", "--comment", comment)
|
||||
}
|
||||
|
||||
// TeardownIPMasq undoes the effects of SetupIPMasq
|
||||
func TeardownIPMasq(ipn *net.IPNet, chain string, comment string) error {
|
||||
ipt, err := iptables.New()
|
||||
isV6 := ipn.IP.To4() == nil
|
||||
|
||||
var ipt *iptables.IPTables
|
||||
var err error
|
||||
|
||||
if isV6 {
|
||||
ipt, err = iptables.NewWithProtocol(iptables.ProtocolIPv6)
|
||||
} else {
|
||||
ipt, err = iptables.NewWithProtocol(iptables.ProtocolIPv4)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to locate iptables: %v", err)
|
||||
}
|
||||
|
||||
if err = ipt.Delete("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain, "-m", "comment", "--comment", comment); err != nil {
|
||||
err = ipt.Delete("nat", "POSTROUTING", "-s", ipn.IP.String(), "-j", chain, "-m", "comment", "--comment", comment)
|
||||
if err != nil && !isNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = ipt.ClearChain("nat", chain); err != nil {
|
||||
// for downward compatibility
|
||||
err = ipt.Delete("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain, "-m", "comment", "--comment", comment)
|
||||
if err != nil && !isNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return ipt.DeleteChain("nat", chain)
|
||||
err = ipt.ClearChain("nat", chain)
|
||||
if err != nil && !isNotExist(err) {
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
err = ipt.DeleteChain("nat", chain)
|
||||
if err != nil && !isNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isNotExist returnst true if the error is from iptables indicating
|
||||
// that the target does not exist.
|
||||
func isNotExist(err error) bool {
|
||||
e, ok := err.(*iptables.Error)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return e.IsNotExist()
|
||||
}
|
@@ -21,29 +21,45 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/utils/hwaddr"
|
||||
"github.com/safchain/ethtool"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/utils/sysctl"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrLinkNotFound = errors.New("link not found")
|
||||
)
|
||||
|
||||
func makeVethPair(name, peer string, mtu int) (netlink.Link, error) {
|
||||
// makeVethPair is called from within the container's network namespace
|
||||
func makeVethPair(name, peer string, mtu int, mac string, hostNS ns.NetNS) (netlink.Link, error) {
|
||||
veth := &netlink.Veth{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: name,
|
||||
Flags: net.FlagUp,
|
||||
MTU: mtu,
|
||||
Name: name,
|
||||
MTU: mtu,
|
||||
},
|
||||
PeerName: peer,
|
||||
PeerName: peer,
|
||||
PeerNamespace: netlink.NsFd(int(hostNS.Fd())),
|
||||
}
|
||||
if mac != "" {
|
||||
m, err := net.ParseMAC(mac)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
veth.LinkAttrs.HardwareAddr = m
|
||||
}
|
||||
if err := netlink.LinkAdd(veth); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Re-fetch the container link to get its creation-time parameters, e.g. index and mac
|
||||
veth2, err := netlink.LinkByName(name)
|
||||
if err != nil {
|
||||
netlink.LinkDel(veth) // try and clean up the link if possible.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return veth, nil
|
||||
return veth2, nil
|
||||
}
|
||||
|
||||
func peerExists(name string) bool {
|
||||
@@ -53,20 +69,24 @@ func peerExists(name string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func makeVeth(name string, mtu int) (peerName string, veth netlink.Link, err error) {
|
||||
func makeVeth(name, vethPeerName string, mtu int, mac string, hostNS ns.NetNS) (peerName string, veth netlink.Link, err error) {
|
||||
for i := 0; i < 10; i++ {
|
||||
peerName, err = RandomVethName()
|
||||
if err != nil {
|
||||
return
|
||||
if vethPeerName != "" {
|
||||
peerName = vethPeerName
|
||||
} else {
|
||||
peerName, err = RandomVethName()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
veth, err = makeVethPair(name, peerName, mtu)
|
||||
veth, err = makeVethPair(name, peerName, mtu, mac, hostNS)
|
||||
switch {
|
||||
case err == nil:
|
||||
return
|
||||
|
||||
case os.IsExist(err):
|
||||
if peerExists(peerName) {
|
||||
if peerExists(peerName) && vethPeerName == "" {
|
||||
continue
|
||||
}
|
||||
err = fmt.Errorf("container veth name provided (%v) already exists", name)
|
||||
@@ -86,7 +106,7 @@ func makeVeth(name string, mtu int) (peerName string, veth netlink.Link, err err
|
||||
// RandomVethName returns string "veth" with random prefix (hashed from entropy)
|
||||
func RandomVethName() (string, error) {
|
||||
entropy := make([]byte, 4)
|
||||
_, err := rand.Reader.Read(entropy)
|
||||
_, err := rand.Read(entropy)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to generate random veth name: %v", err)
|
||||
}
|
||||
@@ -114,29 +134,18 @@ func ifaceFromNetlinkLink(l netlink.Link) net.Interface {
|
||||
}
|
||||
}
|
||||
|
||||
// SetupVeth sets up a pair of virtual ethernet devices.
|
||||
// Call SetupVeth from inside the container netns. It will create both veth
|
||||
// SetupVethWithName sets up a pair of virtual ethernet devices.
|
||||
// Call SetupVethWithName from inside the container netns. It will create both veth
|
||||
// devices and move the host-side veth into the provided hostNS namespace.
|
||||
// On success, SetupVeth returns (hostVeth, containerVeth, nil)
|
||||
func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (net.Interface, net.Interface, error) {
|
||||
hostVethName, contVeth, err := makeVeth(contVethName, mtu)
|
||||
// hostVethName: If hostVethName is not specified, the host-side veth name will use a random string.
|
||||
// On success, SetupVethWithName returns (hostVeth, containerVeth, nil)
|
||||
func SetupVethWithName(contVethName, hostVethName string, mtu int, contVethMac string, hostNS ns.NetNS) (net.Interface, net.Interface, error) {
|
||||
hostVethName, contVeth, err := makeVeth(contVethName, hostVethName, mtu, contVethMac, hostNS)
|
||||
if err != nil {
|
||||
return net.Interface{}, net.Interface{}, err
|
||||
}
|
||||
|
||||
if err = netlink.LinkSetUp(contVeth); err != nil {
|
||||
return net.Interface{}, net.Interface{}, fmt.Errorf("failed to set %q up: %v", contVethName, err)
|
||||
}
|
||||
|
||||
hostVeth, err := netlink.LinkByName(hostVethName)
|
||||
if err != nil {
|
||||
return net.Interface{}, net.Interface{}, fmt.Errorf("failed to lookup %q: %v", hostVethName, err)
|
||||
}
|
||||
|
||||
if err = netlink.LinkSetNsFd(hostVeth, int(hostNS.Fd())); err != nil {
|
||||
return net.Interface{}, net.Interface{}, fmt.Errorf("failed to move veth to host netns: %v", err)
|
||||
}
|
||||
|
||||
var hostVeth netlink.Link
|
||||
err = hostNS.Do(func(_ ns.NetNS) error {
|
||||
hostVeth, err = netlink.LinkByName(hostVethName)
|
||||
if err != nil {
|
||||
@@ -146,6 +155,9 @@ func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (net.Interface, ne
|
||||
if err = netlink.LinkSetUp(hostVeth); err != nil {
|
||||
return fmt.Errorf("failed to set %q up: %v", hostVethName, err)
|
||||
}
|
||||
|
||||
// we want to own the routes for this interface
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv6/conf/%s/accept_ra", hostVethName), "0")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -154,10 +166,21 @@ func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (net.Interface, ne
|
||||
return ifaceFromNetlinkLink(hostVeth), ifaceFromNetlinkLink(contVeth), nil
|
||||
}
|
||||
|
||||
// SetupVeth sets up a pair of virtual ethernet devices.
|
||||
// Call SetupVeth from inside the container netns. It will create both veth
|
||||
// devices and move the host-side veth into the provided hostNS namespace.
|
||||
// On success, SetupVeth returns (hostVeth, containerVeth, nil)
|
||||
func SetupVeth(contVethName string, mtu int, contVethMac string, hostNS ns.NetNS) (net.Interface, net.Interface, error) {
|
||||
return SetupVethWithName(contVethName, "", mtu, contVethMac, hostNS)
|
||||
}
|
||||
|
||||
// DelLinkByName removes an interface link.
|
||||
func DelLinkByName(ifName string) error {
|
||||
iface, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
if _, ok := err.(netlink.LinkNotFoundError); ok {
|
||||
return ErrLinkNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
@@ -168,19 +191,18 @@ func DelLinkByName(ifName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DelLinkByNameAddr remove an interface returns its IP address
|
||||
// of the specified family
|
||||
func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) {
|
||||
// DelLinkByNameAddr remove an interface and returns its addresses
|
||||
func DelLinkByNameAddr(ifName string) ([]*net.IPNet, error) {
|
||||
iface, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
if err != nil && err.Error() == "Link not found" {
|
||||
if _, ok := err.(netlink.LinkNotFoundError); ok {
|
||||
return nil, ErrLinkNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
addrs, err := netlink.AddrList(iface, family)
|
||||
if err != nil || len(addrs) == 0 {
|
||||
addrs, err := netlink.AddrList(iface, netlink.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get IP addresses for %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
@@ -188,32 +210,52 @@ func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) {
|
||||
return nil, fmt.Errorf("failed to delete %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
return addrs[0].IPNet, nil
|
||||
}
|
||||
|
||||
func SetHWAddrByIP(ifName string, ip4 net.IP, ip6 net.IP) error {
|
||||
iface, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case ip4 == nil && ip6 == nil:
|
||||
return fmt.Errorf("neither ip4 or ip6 specified")
|
||||
|
||||
case ip4 != nil:
|
||||
{
|
||||
hwAddr, err := hwaddr.GenerateHardwareAddr4(ip4, hwaddr.PrivateMACPrefix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate hardware addr: %v", err)
|
||||
}
|
||||
if err = netlink.LinkSetHardwareAddr(iface, hwAddr); err != nil {
|
||||
return fmt.Errorf("failed to add hardware addr to %q: %v", ifName, err)
|
||||
}
|
||||
out := []*net.IPNet{}
|
||||
for _, addr := range addrs {
|
||||
if addr.IP.IsGlobalUnicast() {
|
||||
out = append(out, addr.IPNet)
|
||||
}
|
||||
case ip6 != nil:
|
||||
// TODO: IPv6
|
||||
}
|
||||
|
||||
return nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetVethPeerIfindex returns the veth link object, the peer ifindex of the
|
||||
// veth, or an error. This peer ifindex will only be valid in the peer's
|
||||
// network namespace.
|
||||
func GetVethPeerIfindex(ifName string) (netlink.Link, int, error) {
|
||||
link, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
return nil, -1, fmt.Errorf("could not look up %q: %v", ifName, err)
|
||||
}
|
||||
if _, ok := link.(*netlink.Veth); !ok {
|
||||
return nil, -1, fmt.Errorf("interface %q was not a veth interface", ifName)
|
||||
}
|
||||
|
||||
// veth supports IFLA_LINK (what vishvananda/netlink calls ParentIndex)
|
||||
// on 4.1 and higher kernels
|
||||
peerIndex := link.Attrs().ParentIndex
|
||||
if peerIndex <= 0 {
|
||||
// Fall back to ethtool for 4.0 and earlier kernels
|
||||
e, err := ethtool.NewEthtool()
|
||||
if err != nil {
|
||||
return nil, -1, fmt.Errorf("failed to initialize ethtool: %v", err)
|
||||
}
|
||||
defer e.Close()
|
||||
|
||||
stats, err := e.Stats(link.Attrs().Name)
|
||||
if err != nil {
|
||||
return nil, -1, fmt.Errorf("failed to request ethtool stats: %v", err)
|
||||
}
|
||||
n, ok := stats["peer_ifindex"]
|
||||
if !ok {
|
||||
return nil, -1, fmt.Errorf("failed to find 'peer_ifindex' in ethtool stats")
|
||||
}
|
||||
if n > 32767 || n == 0 {
|
||||
return nil, -1, fmt.Errorf("invalid 'peer_ifindex' %d", n)
|
||||
}
|
||||
peerIndex = int(n)
|
||||
}
|
||||
|
||||
return link, peerIndex, nil
|
||||
}
|
6
vendor/github.com/containernetworking/plugins/pkg/ip/route_linux.go
generated
vendored
6
vendor/github.com/containernetworking/plugins/pkg/ip/route_linux.go
generated
vendored
@@ -39,3 +39,9 @@ func AddHostRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
Gw: gw,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDefaultRoute sets the default route on the given gateway.
|
||||
func AddDefaultRoute(gw net.IP, dev netlink.Link) error {
|
||||
_, defNet, _ := net.ParseCIDR("0.0.0.0/0")
|
||||
return AddRoute(defNet, gw, dev)
|
||||
}
|
||||
|
34
vendor/github.com/containernetworking/plugins/pkg/ip/route_unspecified.go
generated
vendored
34
vendor/github.com/containernetworking/plugins/pkg/ip/route_unspecified.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
// Copyright 2015-2017 CNI authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build !linux
|
||||
|
||||
package ip
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
// AddRoute adds a universally-scoped route to a device.
|
||||
func AddRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return types.NotImplementedError
|
||||
}
|
||||
|
||||
// AddHostRoute adds a host-scoped route to a device.
|
||||
func AddHostRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return types.NotImplementedError
|
||||
}
|
116
vendor/github.com/containernetworking/plugins/pkg/ip/utils_linux.go
generated
vendored
Normal file
116
vendor/github.com/containernetworking/plugins/pkg/ip/utils_linux.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 ip
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func ValidateExpectedInterfaceIPs(ifName string, resultIPs []*current.IPConfig) error {
|
||||
|
||||
// Ensure ips
|
||||
for _, ips := range resultIPs {
|
||||
ourAddr := netlink.Addr{IPNet: &ips.Address}
|
||||
match := false
|
||||
|
||||
link, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot find container link %v", ifName)
|
||||
}
|
||||
|
||||
addrList, err := netlink.AddrList(link, netlink.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot obtain List of IP Addresses")
|
||||
}
|
||||
|
||||
for _, addr := range addrList {
|
||||
if addr.Equal(ourAddr) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if match == false {
|
||||
return fmt.Errorf("Failed to match addr %v on interface %v", ourAddr, ifName)
|
||||
}
|
||||
|
||||
// Convert the host/prefixlen to just prefix for route lookup.
|
||||
_, ourPrefix, err := net.ParseCIDR(ourAddr.String())
|
||||
|
||||
findGwy := &netlink.Route{Dst: ourPrefix}
|
||||
routeFilter := netlink.RT_FILTER_DST
|
||||
|
||||
family := netlink.FAMILY_V6
|
||||
if ips.Address.IP.To4() != nil {
|
||||
family = netlink.FAMILY_V4
|
||||
}
|
||||
|
||||
gwy, err := netlink.RouteListFiltered(family, findGwy, routeFilter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error %v trying to find Gateway %v for interface %v", err, ips.Gateway, ifName)
|
||||
}
|
||||
if gwy == nil {
|
||||
return fmt.Errorf("Failed to find Gateway %v for interface %v", ips.Gateway, ifName)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateExpectedRoute(resultRoutes []*types.Route) error {
|
||||
|
||||
// Ensure that each static route in prevResults is found in the routing table
|
||||
for _, route := range resultRoutes {
|
||||
find := &netlink.Route{Dst: &route.Dst, Gw: route.GW}
|
||||
routeFilter := netlink.RT_FILTER_DST | netlink.RT_FILTER_GW
|
||||
var family int
|
||||
|
||||
switch {
|
||||
case route.Dst.IP.To4() != nil:
|
||||
family = netlink.FAMILY_V4
|
||||
// Default route needs Dst set to nil
|
||||
if route.Dst.String() == "0.0.0.0/0" {
|
||||
find = &netlink.Route{Dst: nil, Gw: route.GW}
|
||||
routeFilter = netlink.RT_FILTER_DST
|
||||
}
|
||||
case len(route.Dst.IP) == net.IPv6len:
|
||||
family = netlink.FAMILY_V6
|
||||
// Default route needs Dst set to nil
|
||||
if route.Dst.String() == "::/0" {
|
||||
find = &netlink.Route{Dst: nil, Gw: route.GW}
|
||||
routeFilter = netlink.RT_FILTER_DST
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Invalid static route found %v", route)
|
||||
}
|
||||
|
||||
wasFound, err := netlink.RouteListFiltered(family, find, routeFilter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Expected Route %v not route table lookup error %v", route, err)
|
||||
}
|
||||
if wasFound == nil {
|
||||
return fmt.Errorf("Expected Route %v not found in routing table", route)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
15
vendor/github.com/containernetworking/plugins/pkg/ns/README.md
generated
vendored
15
vendor/github.com/containernetworking/plugins/pkg/ns/README.md
generated
vendored
@@ -12,10 +12,6 @@ For example, you cannot rely on the `ns.Set()` namespace being the current names
|
||||
The `ns.Do()` method provides **partial** control over network namespaces for you by implementing these strategies. All code dependent on a particular network namespace (including the root namespace) should be wrapped in the `ns.Do()` method to ensure the correct namespace is selected for the duration of your code. For example:
|
||||
|
||||
```go
|
||||
targetNs, err := ns.NewNS()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = targetNs.Do(func(hostNs ns.NetNS) error {
|
||||
dummy := &netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
@@ -26,11 +22,16 @@ err = targetNs.Do(func(hostNs ns.NetNS) error {
|
||||
})
|
||||
```
|
||||
|
||||
Note this requirement to wrap every network call is very onerous - any libraries you call might call out to network services such as DNS, and all such calls need to be protected after you call `ns.Do()`. The CNI plugins all exit very soon after calling `ns.Do()` which helps to minimize the problem.
|
||||
Note this requirement to wrap every network call is very onerous - any libraries you call might call out to network services such as DNS, and all such calls need to be protected after you call `ns.Do()`. All goroutines spawned from within the `ns.Do` will not inherit the new namespace. The CNI plugins all exit very soon after calling `ns.Do()` which helps to minimize the problem.
|
||||
|
||||
Also: If the runtime spawns a new OS thread, it will inherit the network namespace of the parent thread, which may have been temporarily switched, and thus the new OS thread will be permanently "stuck in the wrong namespace".
|
||||
When a new thread is spawned in Linux, it inherits the namespace of its parent. In versions of go **prior to 1.10**, if the runtime spawns a new OS thread, it picks the parent randomly. If the chosen parent thread has been moved to a new namespace (even temporarily), the new OS thread will be permanently "stuck in the wrong namespace", and goroutines will non-deterministically switch namespaces as they are rescheduled.
|
||||
|
||||
In short, **there was no safe way to change network namespaces, even temporarily, from within a long-lived, multithreaded Go process**. If you wish to do this, you must use go 1.10 or greater.
|
||||
|
||||
|
||||
### Creating network namespaces
|
||||
Earlier versions of this library managed namespace creation, but as CNI does not actually utilize this feature (and it was essentially unmaintained), it was removed. If you're writing a container runtime, you should implement namespace management yourself. However, there are some gotchas when doing so, especially around handling `/var/run/netns`. A reasonably correct reference implementation, borrowed from `rkt`, can be found in `pkg/testutils/netns_linux.go` if you're in need of a source of inspiration.
|
||||
|
||||
In short, **there is no safe way to change network namespaces from within a long-lived, multithreaded Go process**. If your daemon process needs to be namespace aware, consider spawning a separate process (like a CNI plugin) for each namespace.
|
||||
|
||||
### Further Reading
|
||||
- https://github.com/golang/go/wiki/LockOSThread
|
||||
|
178
vendor/github.com/containernetworking/plugins/pkg/ns/ns.go
generated
vendored
178
vendor/github.com/containernetworking/plugins/pkg/ns/ns.go
generated
vendored
@@ -1,178 +0,0 @@
|
||||
// Copyright 2015 CNI authors
|
||||
//
|
||||
// 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 ns
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type NetNS interface {
|
||||
// Executes the passed closure in this object's network namespace,
|
||||
// attempting to restore the original namespace before returning.
|
||||
// However, since each OS thread can have a different network namespace,
|
||||
// and Go's thread scheduling is highly variable, callers cannot
|
||||
// guarantee any specific namespace is set unless operations that
|
||||
// require that namespace are wrapped with Do(). Also, no code called
|
||||
// from Do() should call runtime.UnlockOSThread(), or the risk
|
||||
// of executing code in an incorrect namespace will be greater. See
|
||||
// https://github.com/golang/go/wiki/LockOSThread for further details.
|
||||
Do(toRun func(NetNS) error) error
|
||||
|
||||
// Sets the current network namespace to this object's network namespace.
|
||||
// Note that since Go's thread scheduling is highly variable, callers
|
||||
// cannot guarantee the requested namespace will be the current namespace
|
||||
// after this function is called; to ensure this wrap operations that
|
||||
// require the namespace with Do() instead.
|
||||
Set() error
|
||||
|
||||
// Returns the filesystem path representing this object's network namespace
|
||||
Path() string
|
||||
|
||||
// Returns a file descriptor representing this object's network namespace
|
||||
Fd() uintptr
|
||||
|
||||
// Cleans up this instance of the network namespace; if this instance
|
||||
// is the last user the namespace will be destroyed
|
||||
Close() error
|
||||
}
|
||||
|
||||
type netNS struct {
|
||||
file *os.File
|
||||
mounted bool
|
||||
closed bool
|
||||
}
|
||||
|
||||
// netNS implements the NetNS interface
|
||||
var _ NetNS = &netNS{}
|
||||
|
||||
const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||
NSFS_MAGIC = 0x6e736673
|
||||
PROCFS_MAGIC = 0x9fa0
|
||||
)
|
||||
|
||||
type NSPathNotExistErr struct{ msg string }
|
||||
|
||||
func (e NSPathNotExistErr) Error() string { return e.msg }
|
||||
|
||||
type NSPathNotNSErr struct{ msg string }
|
||||
|
||||
func (e NSPathNotNSErr) Error() string { return e.msg }
|
||||
|
||||
func IsNSorErr(nspath string) error {
|
||||
stat := syscall.Statfs_t{}
|
||||
if err := syscall.Statfs(nspath, &stat); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
err = NSPathNotExistErr{msg: fmt.Sprintf("failed to Statfs %q: %v", nspath, err)}
|
||||
} else {
|
||||
err = fmt.Errorf("failed to Statfs %q: %v", nspath, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
switch stat.Type {
|
||||
case PROCFS_MAGIC, NSFS_MAGIC:
|
||||
return nil
|
||||
default:
|
||||
return NSPathNotNSErr{msg: fmt.Sprintf("unknown FS magic on %q: %x", nspath, stat.Type)}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an object representing the namespace referred to by @path
|
||||
func GetNS(nspath string) (NetNS, error) {
|
||||
err := IsNSorErr(nspath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fd, err := os.Open(nspath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &netNS{file: fd}, nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Path() string {
|
||||
return ns.file.Name()
|
||||
}
|
||||
|
||||
func (ns *netNS) Fd() uintptr {
|
||||
return ns.file.Fd()
|
||||
}
|
||||
|
||||
func (ns *netNS) errorIfClosed() error {
|
||||
if ns.closed {
|
||||
return fmt.Errorf("%q has already been closed", ns.file.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Do(toRun func(NetNS) error) error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
containedCall := func(hostNS NetNS) error {
|
||||
threadNS, err := GetCurrentNS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open current netns: %v", err)
|
||||
}
|
||||
defer threadNS.Close()
|
||||
|
||||
// switch to target namespace
|
||||
if err = ns.Set(); err != nil {
|
||||
return fmt.Errorf("error switching to ns %v: %v", ns.file.Name(), err)
|
||||
}
|
||||
defer threadNS.Set() // switch back
|
||||
|
||||
return toRun(hostNS)
|
||||
}
|
||||
|
||||
// save a handle to current network namespace
|
||||
hostNS, err := GetCurrentNS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open current namespace: %v", err)
|
||||
}
|
||||
defer hostNS.Close()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
var innerError error
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
innerError = containedCall(hostNS)
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
return innerError
|
||||
}
|
||||
|
||||
// WithNetNSPath executes the passed closure under the given network
|
||||
// namespace, restoring the original namespace afterwards.
|
||||
func WithNetNSPath(nspath string, toRun func(NetNS) error) error {
|
||||
ns, err := GetNS(nspath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ns.Close()
|
||||
return ns.Do(toRun)
|
||||
}
|
261
vendor/github.com/containernetworking/plugins/pkg/ns/ns_linux.go
generated
vendored
261
vendor/github.com/containernetworking/plugins/pkg/ns/ns_linux.go
generated
vendored
@@ -15,18 +15,22 @@
|
||||
package ns
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Returns an object representing the current OS thread's network namespace
|
||||
func GetCurrentNS() (NetNS, error) {
|
||||
// Lock the thread in case other goroutine executes in it and changes its
|
||||
// network namespace after getCurrentThreadNetNSPath(), otherwise it might
|
||||
// return an unexpected network namespace.
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
return GetNS(getCurrentThreadNetNSPath())
|
||||
}
|
||||
|
||||
@@ -37,82 +41,6 @@ func getCurrentThreadNetNSPath() string {
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
|
||||
}
|
||||
|
||||
// Creates a new persistent network namespace and returns an object
|
||||
// representing that namespace, without switching to it
|
||||
func NewNS() (NetNS, error) {
|
||||
const nsRunDir = "/var/run/netns"
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(nsRunDir, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create an empty file at the mount point
|
||||
nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
nsPath := path.Join(nsRunDir, nsName)
|
||||
mountPointFd, err := os.Create(nsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mountPointFd.Close()
|
||||
|
||||
// Ensure the mount point is cleaned up on errors; if the namespace
|
||||
// was successfully mounted this will have no effect because the file
|
||||
// is in-use
|
||||
defer os.RemoveAll(nsPath)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// do namespace work in a dedicated goroutine, so that we can safely
|
||||
// Lock/Unlock OSThread without upsetting the lock/unlock state of
|
||||
// the caller of this function
|
||||
var fd *os.File
|
||||
go (func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
|
||||
var origNS NetNS
|
||||
origNS, err = GetNS(getCurrentThreadNetNSPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Close()
|
||||
|
||||
// create a new netns on the current thread
|
||||
err = unix.Unshare(unix.CLONE_NEWNET)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Set()
|
||||
|
||||
// bind mount the new netns from the current thread onto the mount point
|
||||
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fd, err = os.Open(nsPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})()
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
unix.Unmount(nsPath, unix.MNT_DETACH)
|
||||
return nil, fmt.Errorf("failed to create namespace: %v", err)
|
||||
}
|
||||
|
||||
return &netNS{file: fd, mounted: true}, nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Close() error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
@@ -123,16 +51,6 @@ func (ns *netNS) Close() error {
|
||||
}
|
||||
ns.closed = true
|
||||
|
||||
if ns.mounted {
|
||||
if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil {
|
||||
return fmt.Errorf("Failed to unmount namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
if err := os.RemoveAll(ns.file.Name()); err != nil {
|
||||
return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
ns.mounted = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -147,3 +65,170 @@ func (ns *netNS) Set() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type NetNS interface {
|
||||
// Executes the passed closure in this object's network namespace,
|
||||
// attempting to restore the original namespace before returning.
|
||||
// However, since each OS thread can have a different network namespace,
|
||||
// and Go's thread scheduling is highly variable, callers cannot
|
||||
// guarantee any specific namespace is set unless operations that
|
||||
// require that namespace are wrapped with Do(). Also, no code called
|
||||
// from Do() should call runtime.UnlockOSThread(), or the risk
|
||||
// of executing code in an incorrect namespace will be greater. See
|
||||
// https://github.com/golang/go/wiki/LockOSThread for further details.
|
||||
Do(toRun func(NetNS) error) error
|
||||
|
||||
// Sets the current network namespace to this object's network namespace.
|
||||
// Note that since Go's thread scheduling is highly variable, callers
|
||||
// cannot guarantee the requested namespace will be the current namespace
|
||||
// after this function is called; to ensure this wrap operations that
|
||||
// require the namespace with Do() instead.
|
||||
Set() error
|
||||
|
||||
// Returns the filesystem path representing this object's network namespace
|
||||
Path() string
|
||||
|
||||
// Returns a file descriptor representing this object's network namespace
|
||||
Fd() uintptr
|
||||
|
||||
// Cleans up this instance of the network namespace; if this instance
|
||||
// is the last user the namespace will be destroyed
|
||||
Close() error
|
||||
}
|
||||
|
||||
type netNS struct {
|
||||
file *os.File
|
||||
closed bool
|
||||
}
|
||||
|
||||
// netNS implements the NetNS interface
|
||||
var _ NetNS = &netNS{}
|
||||
|
||||
const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||
NSFS_MAGIC = unix.NSFS_MAGIC
|
||||
PROCFS_MAGIC = unix.PROC_SUPER_MAGIC
|
||||
)
|
||||
|
||||
type NSPathNotExistErr struct{ msg string }
|
||||
|
||||
func (e NSPathNotExistErr) Error() string { return e.msg }
|
||||
|
||||
type NSPathNotNSErr struct{ msg string }
|
||||
|
||||
func (e NSPathNotNSErr) Error() string { return e.msg }
|
||||
|
||||
func IsNSorErr(nspath string) error {
|
||||
stat := syscall.Statfs_t{}
|
||||
if err := syscall.Statfs(nspath, &stat); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
err = NSPathNotExistErr{msg: fmt.Sprintf("failed to Statfs %q: %v", nspath, err)}
|
||||
} else {
|
||||
err = fmt.Errorf("failed to Statfs %q: %v", nspath, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
switch stat.Type {
|
||||
case PROCFS_MAGIC, NSFS_MAGIC:
|
||||
return nil
|
||||
default:
|
||||
return NSPathNotNSErr{msg: fmt.Sprintf("unknown FS magic on %q: %x", nspath, stat.Type)}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an object representing the namespace referred to by @path
|
||||
func GetNS(nspath string) (NetNS, error) {
|
||||
err := IsNSorErr(nspath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fd, err := os.Open(nspath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &netNS{file: fd}, nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Path() string {
|
||||
return ns.file.Name()
|
||||
}
|
||||
|
||||
func (ns *netNS) Fd() uintptr {
|
||||
return ns.file.Fd()
|
||||
}
|
||||
|
||||
func (ns *netNS) errorIfClosed() error {
|
||||
if ns.closed {
|
||||
return fmt.Errorf("%q has already been closed", ns.file.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Do(toRun func(NetNS) error) error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
containedCall := func(hostNS NetNS) error {
|
||||
threadNS, err := GetCurrentNS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open current netns: %v", err)
|
||||
}
|
||||
defer threadNS.Close()
|
||||
|
||||
// switch to target namespace
|
||||
if err = ns.Set(); err != nil {
|
||||
return fmt.Errorf("error switching to ns %v: %v", ns.file.Name(), err)
|
||||
}
|
||||
defer func() {
|
||||
err := threadNS.Set() // switch back
|
||||
if err == nil {
|
||||
// Unlock the current thread only when we successfully switched back
|
||||
// to the original namespace; otherwise leave the thread locked which
|
||||
// will force the runtime to scrap the current thread, that is maybe
|
||||
// not as optimal but at least always safe to do.
|
||||
runtime.UnlockOSThread()
|
||||
}
|
||||
}()
|
||||
|
||||
return toRun(hostNS)
|
||||
}
|
||||
|
||||
// save a handle to current network namespace
|
||||
hostNS, err := GetCurrentNS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open current namespace: %v", err)
|
||||
}
|
||||
defer hostNS.Close()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// Start the callback in a new green thread so that if we later fail
|
||||
// to switch the namespace back to the original one, we can safely
|
||||
// leave the thread locked to die without a risk of the current thread
|
||||
// left lingering with incorrect namespace.
|
||||
var innerError error
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
innerError = containedCall(hostNS)
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
return innerError
|
||||
}
|
||||
|
||||
// WithNetNSPath executes the passed closure under the given network
|
||||
// namespace, restoring the original namespace afterwards.
|
||||
func WithNetNSPath(nspath string, toRun func(NetNS) error) error {
|
||||
ns, err := GetNS(nspath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ns.Close()
|
||||
return ns.Do(toRun)
|
||||
}
|
||||
|
36
vendor/github.com/containernetworking/plugins/pkg/ns/ns_unspecified.go
generated
vendored
36
vendor/github.com/containernetworking/plugins/pkg/ns/ns_unspecified.go
generated
vendored
@@ -1,36 +0,0 @@
|
||||
// Copyright 2015-2017 CNI authors
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build !linux
|
||||
|
||||
package ns
|
||||
|
||||
import "github.com/containernetworking/cni/pkg/types"
|
||||
|
||||
// Returns an object representing the current OS thread's network namespace
|
||||
func GetCurrentNS() (NetNS, error) {
|
||||
return nil, types.NotImplementedError
|
||||
}
|
||||
|
||||
func NewNS() (NetNS, error) {
|
||||
return nil, types.NotImplementedError
|
||||
}
|
||||
|
||||
func (ns *netNS) Close() error {
|
||||
return types.NotImplementedError
|
||||
}
|
||||
|
||||
func (ns *netNS) Set() error {
|
||||
return types.NotImplementedError
|
||||
}
|
63
vendor/github.com/containernetworking/plugins/pkg/utils/hwaddr/hwaddr.go
generated
vendored
63
vendor/github.com/containernetworking/plugins/pkg/utils/hwaddr/hwaddr.go
generated
vendored
@@ -1,63 +0,0 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 hwaddr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
ipRelevantByteLen = 4
|
||||
PrivateMACPrefixString = "0a:58"
|
||||
)
|
||||
|
||||
var (
|
||||
// private mac prefix safe to use
|
||||
PrivateMACPrefix = []byte{0x0a, 0x58}
|
||||
)
|
||||
|
||||
type SupportIp4OnlyErr struct{ msg string }
|
||||
|
||||
func (e SupportIp4OnlyErr) Error() string { return e.msg }
|
||||
|
||||
type MacParseErr struct{ msg string }
|
||||
|
||||
func (e MacParseErr) Error() string { return e.msg }
|
||||
|
||||
type InvalidPrefixLengthErr struct{ msg string }
|
||||
|
||||
func (e InvalidPrefixLengthErr) Error() string { return e.msg }
|
||||
|
||||
// GenerateHardwareAddr4 generates 48 bit virtual mac addresses based on the IP4 input.
|
||||
func GenerateHardwareAddr4(ip net.IP, prefix []byte) (net.HardwareAddr, error) {
|
||||
switch {
|
||||
|
||||
case ip.To4() == nil:
|
||||
return nil, SupportIp4OnlyErr{msg: "GenerateHardwareAddr4 only supports valid IPv4 address as input"}
|
||||
|
||||
case len(prefix) != len(PrivateMACPrefix):
|
||||
return nil, InvalidPrefixLengthErr{msg: fmt.Sprintf(
|
||||
"Prefix has length %d instead of %d", len(prefix), len(PrivateMACPrefix)),
|
||||
}
|
||||
}
|
||||
|
||||
ipByteLen := len(ip)
|
||||
return (net.HardwareAddr)(
|
||||
append(
|
||||
prefix,
|
||||
ip[ipByteLen-ipRelevantByteLen:ipByteLen]...),
|
||||
), nil
|
||||
}
|
78
vendor/github.com/containernetworking/plugins/pkg/utils/sysctl/sysctl_linux.go
generated
vendored
Normal file
78
vendor/github.com/containernetworking/plugins/pkg/utils/sysctl/sysctl_linux.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// 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 sysctl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Sysctl provides a method to set/get values from /proc/sys - in linux systems
|
||||
// new interface to set/get values of variables formerly handled by sysctl syscall
|
||||
// If optional `params` have only one string value - this function will
|
||||
// set this value into corresponding sysctl variable
|
||||
func Sysctl(name string, params ...string) (string, error) {
|
||||
if len(params) > 1 {
|
||||
return "", fmt.Errorf("unexcepted additional parameters")
|
||||
} else if len(params) == 1 {
|
||||
return setSysctl(name, params[0])
|
||||
}
|
||||
return getSysctl(name)
|
||||
}
|
||||
|
||||
func getSysctl(name string) (string, error) {
|
||||
fullName := filepath.Join("/proc/sys", toNormalName(name))
|
||||
data, err := ioutil.ReadFile(fullName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(data[:len(data)-1]), nil
|
||||
}
|
||||
|
||||
func setSysctl(name, value string) (string, error) {
|
||||
fullName := filepath.Join("/proc/sys", toNormalName(name))
|
||||
if err := ioutil.WriteFile(fullName, []byte(value), 0644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return getSysctl(name)
|
||||
}
|
||||
|
||||
// Normalize names by using slash as separator
|
||||
// Sysctl names can use dots or slashes as separator:
|
||||
// - if dots are used, dots and slashes are interchanged.
|
||||
// - if slashes are used, slashes and dots are left intact.
|
||||
// Separator in use is determined by first occurrence.
|
||||
func toNormalName(name string) string {
|
||||
interchange := false
|
||||
for _, c := range name {
|
||||
if c == '.' {
|
||||
interchange = true
|
||||
break
|
||||
}
|
||||
if c == '/' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if interchange {
|
||||
r := strings.NewReplacer(".", "/", "/", ".")
|
||||
return r.Replace(name)
|
||||
}
|
||||
return name
|
||||
}
|
@@ -21,7 +21,8 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ip"
|
||||
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend"
|
||||
)
|
||||
@@ -40,8 +41,8 @@ func NewIPAllocator(s *RangeSet, store backend.Store, id int) *IPAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
// Get alocates an IP
|
||||
func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, error) {
|
||||
// Get allocates an IP
|
||||
func (a *IPAllocator) Get(id string, ifname string, requestedIP net.IP) (*current.IPConfig, error) {
|
||||
a.store.Lock()
|
||||
defer a.store.Unlock()
|
||||
|
||||
@@ -62,7 +63,7 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
|
||||
return nil, fmt.Errorf("requested ip %s is subnet's gateway", requestedIP.String())
|
||||
}
|
||||
|
||||
reserved, err := a.store.Reserve(id, requestedIP, a.rangeID)
|
||||
reserved, err := a.store.Reserve(id, ifname, requestedIP, a.rangeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -73,6 +74,17 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
|
||||
gw = r.Gateway
|
||||
|
||||
} else {
|
||||
// try to get allocated IPs for this given id, if exists, just return error
|
||||
// because duplicate allocation is not allowed in SPEC
|
||||
// https://github.com/containernetworking/cni/blob/master/SPEC.md
|
||||
allocatedIPs := a.store.GetByID(id, ifname)
|
||||
for _, allocatedIP := range allocatedIPs {
|
||||
// check whether the existing IP belong to this range set
|
||||
if _, err := a.rangeset.RangeFor(allocatedIP); err == nil {
|
||||
return nil, fmt.Errorf("%s has been allocated to %s, duplicate allocation is not allowed", allocatedIP.String(), id)
|
||||
}
|
||||
}
|
||||
|
||||
iter, err := a.GetIter()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -83,7 +95,7 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
|
||||
break
|
||||
}
|
||||
|
||||
reserved, err := a.store.Reserve(id, reservedIP.IP, a.rangeID)
|
||||
reserved, err := a.store.Reserve(id, ifname, reservedIP.IP, a.rangeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -97,24 +109,19 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
|
||||
if reservedIP == nil {
|
||||
return nil, fmt.Errorf("no IP addresses available in range set: %s", a.rangeset.String())
|
||||
}
|
||||
version := "4"
|
||||
if reservedIP.IP.To4() == nil {
|
||||
version = "6"
|
||||
}
|
||||
|
||||
return ¤t.IPConfig{
|
||||
Version: version,
|
||||
Address: *reservedIP,
|
||||
Gateway: gw,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Release clears all IPs allocated for the container with given ID
|
||||
func (a *IPAllocator) Release(id string) error {
|
||||
func (a *IPAllocator) Release(id string, ifname string) error {
|
||||
a.store.Lock()
|
||||
defer a.store.Unlock()
|
||||
|
||||
return a.store.ReleaseByID(id)
|
||||
return a.store.ReleaseByID(id, ifname)
|
||||
}
|
||||
|
||||
type RangeIter struct {
|
||||
@@ -126,9 +133,8 @@ type RangeIter struct {
|
||||
// Our current position
|
||||
cur net.IP
|
||||
|
||||
// The IP and range index where we started iterating; if we hit this again, we're done.
|
||||
startIP net.IP
|
||||
startRange int
|
||||
// The IP where we started iterating; if we hit this again, we're done.
|
||||
startIP net.IP
|
||||
}
|
||||
|
||||
// GetIter encapsulates the strategy for this allocator.
|
||||
@@ -158,7 +164,6 @@ func (a *IPAllocator) GetIter() (*RangeIter, error) {
|
||||
for i, r := range *a.rangeset {
|
||||
if r.Contains(lastReservedIP) {
|
||||
iter.rangeIdx = i
|
||||
iter.startRange = i
|
||||
|
||||
// We advance the cursor on every Next(), so the first call
|
||||
// to next() will return lastReservedIP + 1
|
||||
@@ -168,7 +173,6 @@ func (a *IPAllocator) GetIter() (*RangeIter, error) {
|
||||
}
|
||||
} else {
|
||||
iter.rangeIdx = 0
|
||||
iter.startRange = 0
|
||||
iter.startIP = (*a.rangeset)[0].RangeStart
|
||||
}
|
||||
return &iter, nil
|
||||
@@ -204,7 +208,7 @@ func (i *RangeIter) Next() (*net.IPNet, net.IP) {
|
||||
|
||||
if i.startIP == nil {
|
||||
i.startIP = i.cur
|
||||
} else if i.rangeIdx == i.startRange && i.cur.Equal(i.startIP) {
|
||||
} else if i.cur.Equal(i.startIP) {
|
||||
// IF we've looped back to where we started, give up
|
||||
return nil, nil
|
||||
}
|
||||
|
@@ -20,15 +20,23 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
types020 "github.com/containernetworking/cni/pkg/types/020"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ip"
|
||||
)
|
||||
|
||||
// The top-level network config, just so we can get the IPAM block
|
||||
// The top-level network config - IPAM plugins are passed the full configuration
|
||||
// of the calling plugin, not just the IPAM section.
|
||||
type Net struct {
|
||||
Name string `json:"name"`
|
||||
CNIVersion string `json:"cniVersion"`
|
||||
IPAM *IPAMConfig `json:"ipam"`
|
||||
Args *struct {
|
||||
Name string `json:"name"`
|
||||
CNIVersion string `json:"cniVersion"`
|
||||
IPAM *IPAMConfig `json:"ipam"`
|
||||
RuntimeConfig struct {
|
||||
// The capability arg
|
||||
IPRanges []RangeSet `json:"ipRanges,omitempty"`
|
||||
IPs []*ip.IP `json:"ips,omitempty"`
|
||||
} `json:"runtimeConfig,omitempty"`
|
||||
Args *struct {
|
||||
A *IPAMArgs `json:"cni"`
|
||||
} `json:"args"`
|
||||
}
|
||||
@@ -44,16 +52,16 @@ type IPAMConfig struct {
|
||||
DataDir string `json:"dataDir"`
|
||||
ResolvConf string `json:"resolvConf"`
|
||||
Ranges []RangeSet `json:"ranges"`
|
||||
IPArgs []net.IP `json:"-"` // Requested IPs from CNI_ARGS and args
|
||||
IPArgs []net.IP `json:"-"` // Requested IPs from CNI_ARGS, args and capabilities
|
||||
}
|
||||
|
||||
type IPAMEnvArgs struct {
|
||||
types.CommonArgs
|
||||
IP net.IP `json:"ip,omitempty"`
|
||||
IP ip.IP `json:"ip,omitempty"`
|
||||
}
|
||||
|
||||
type IPAMArgs struct {
|
||||
IPs []net.IP `json:"ips"`
|
||||
IPs []*ip.IP `json:"ips"`
|
||||
}
|
||||
|
||||
type RangeSet []Range
|
||||
@@ -76,7 +84,7 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
return nil, "", fmt.Errorf("IPAM config missing 'ipam' key")
|
||||
}
|
||||
|
||||
// Parse custom IP from both env args *and* the top-level args config
|
||||
// parse custom IP from env args
|
||||
if envArgs != "" {
|
||||
e := IPAMEnvArgs{}
|
||||
err := types.LoadArgs(envArgs, &e)
|
||||
@@ -84,16 +92,26 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if e.IP != nil {
|
||||
n.IPAM.IPArgs = []net.IP{e.IP}
|
||||
if e.IP.ToIP() != nil {
|
||||
n.IPAM.IPArgs = []net.IP{e.IP.ToIP()}
|
||||
}
|
||||
}
|
||||
|
||||
// parse custom IPs from CNI args in network config
|
||||
if n.Args != nil && n.Args.A != nil && len(n.Args.A.IPs) != 0 {
|
||||
n.IPAM.IPArgs = append(n.IPAM.IPArgs, n.Args.A.IPs...)
|
||||
for _, i := range n.Args.A.IPs {
|
||||
n.IPAM.IPArgs = append(n.IPAM.IPArgs, i.ToIP())
|
||||
}
|
||||
}
|
||||
|
||||
for idx, _ := range n.IPAM.IPArgs {
|
||||
// parse custom IPs from runtime configuration
|
||||
if len(n.RuntimeConfig.IPs) > 0 {
|
||||
for _, i := range n.RuntimeConfig.IPs {
|
||||
n.IPAM.IPArgs = append(n.IPAM.IPArgs, i.ToIP())
|
||||
}
|
||||
}
|
||||
|
||||
for idx := range n.IPAM.IPArgs {
|
||||
if err := canonicalizeIP(&n.IPAM.IPArgs[idx]); err != nil {
|
||||
return nil, "", fmt.Errorf("cannot understand ip: %v", err)
|
||||
}
|
||||
@@ -106,6 +124,11 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
}
|
||||
n.IPAM.Range = nil
|
||||
|
||||
// If a range is supplied as a runtime config, prepend it to the Ranges
|
||||
if len(n.RuntimeConfig.IPRanges) > 0 {
|
||||
n.IPAM.Ranges = append(n.RuntimeConfig.IPRanges, n.IPAM.Ranges...)
|
||||
}
|
||||
|
||||
if len(n.IPAM.Ranges) == 0 {
|
||||
return nil, "", fmt.Errorf("no IP ranges specified")
|
||||
}
|
||||
@@ -113,7 +136,7 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
// Validate all ranges
|
||||
numV4 := 0
|
||||
numV6 := 0
|
||||
for i, _ := range n.IPAM.Ranges {
|
||||
for i := range n.IPAM.Ranges {
|
||||
if err := n.IPAM.Ranges[i].Canonicalize(); err != nil {
|
||||
return nil, "", fmt.Errorf("invalid range set %d: %s", i, err)
|
||||
}
|
||||
@@ -127,10 +150,8 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
|
||||
// CNI spec 0.2.0 and below supported only one v4 and v6 address
|
||||
if numV4 > 1 || numV6 > 1 {
|
||||
for _, v := range types020.SupportedVersions {
|
||||
if n.CNIVersion == v {
|
||||
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
|
||||
}
|
||||
if ok, _ := version.GreaterThanOrEqualTo(n.CNIVersion, "0.3.0"); !ok {
|
||||
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,12 @@ func (r *Range) Canonicalize() error {
|
||||
return fmt.Errorf("IPNet IP and Mask version mismatch")
|
||||
}
|
||||
|
||||
// Ensure Subnet IP is the network address, not some other address
|
||||
networkIP := r.Subnet.IP.Mask(r.Subnet.Mask)
|
||||
if !r.Subnet.IP.Equal(networkIP) {
|
||||
return fmt.Errorf("Network has host bits set. For a subnet mask of length %d the network address is %s", ones, networkIP.String())
|
||||
}
|
||||
|
||||
// If the gateway is nil, claim .1
|
||||
if r.Gateway == nil {
|
||||
r.Gateway = ip.NextIP(r.Subnet.IP)
|
||||
@@ -47,10 +53,6 @@ func (r *Range) Canonicalize() error {
|
||||
if err := canonicalizeIP(&r.Gateway); err != nil {
|
||||
return err
|
||||
}
|
||||
subnet := (net.IPNet)(r.Subnet)
|
||||
if !subnet.Contains(r.Gateway) {
|
||||
return fmt.Errorf("gateway %s not in network %s", r.Gateway.String(), subnet.String())
|
||||
}
|
||||
}
|
||||
|
||||
// RangeStart: If specified, make sure it's sane (inside the subnet),
|
||||
|
@@ -61,7 +61,7 @@ func (s *RangeSet) Canonicalize() error {
|
||||
}
|
||||
|
||||
fam := 0
|
||||
for i, _ := range *s {
|
||||
for i := range *s {
|
||||
if err := (*s)[i].Canonicalize(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -20,8 +20,9 @@ type Store interface {
|
||||
Lock() error
|
||||
Unlock() error
|
||||
Close() error
|
||||
Reserve(id string, ip net.IP, rangeID string) (bool, error)
|
||||
Reserve(id string, ifname string, ip net.IP, rangeID string) (bool, error)
|
||||
LastReservedIP(rangeID string) (net.IP, error)
|
||||
Release(ip net.IP) error
|
||||
ReleaseByID(id string) error
|
||||
ReleaseByID(id string, ifname string) error
|
||||
GetByID(id string, ifname string) []net.IP
|
||||
}
|
||||
|
264
vendor/github.com/coreos/go-iptables/iptables/iptables.go
generated
vendored
264
vendor/github.com/coreos/go-iptables/iptables/iptables.go
generated
vendored
@@ -47,9 +47,12 @@ func (e *Error) Error() string {
|
||||
|
||||
// IsNotExist returns true if the error is due to the chain or rule not existing
|
||||
func (e *Error) IsNotExist() bool {
|
||||
return e.ExitStatus() == 1 &&
|
||||
(e.msg == "iptables: Bad rule (does a matching rule exist in that chain?).\n" ||
|
||||
e.msg == "iptables: No chain/target/match by that name.\n")
|
||||
if e.ExitStatus() != 1 {
|
||||
return false
|
||||
}
|
||||
msgNoRuleExist := "Bad rule (does a matching rule exist in that chain?).\n"
|
||||
msgNoChainExist := "No chain/target/match by that name.\n"
|
||||
return strings.Contains(e.msg, msgNoRuleExist) || strings.Contains(e.msg, msgNoChainExist)
|
||||
}
|
||||
|
||||
// Protocol to differentiate between IPv4 and IPv6
|
||||
@@ -61,47 +64,95 @@ const (
|
||||
)
|
||||
|
||||
type IPTables struct {
|
||||
path string
|
||||
proto Protocol
|
||||
hasCheck bool
|
||||
hasWait bool
|
||||
hasRandomFully bool
|
||||
v1 int
|
||||
v2 int
|
||||
v3 int
|
||||
mode string // the underlying iptables operating mode, e.g. nf_tables
|
||||
path string
|
||||
proto Protocol
|
||||
hasCheck bool
|
||||
hasWait bool
|
||||
waitSupportSecond bool
|
||||
hasRandomFully bool
|
||||
v1 int
|
||||
v2 int
|
||||
v3 int
|
||||
mode string // the underlying iptables operating mode, e.g. nf_tables
|
||||
timeout int // time to wait for the iptables lock, default waits forever
|
||||
}
|
||||
|
||||
// New creates a new IPTables.
|
||||
// For backwards compatibility, this always uses IPv4, i.e. "iptables".
|
||||
func New() (*IPTables, error) {
|
||||
return NewWithProtocol(ProtocolIPv4)
|
||||
// Stat represents a structured statistic entry.
|
||||
type Stat struct {
|
||||
Packets uint64 `json:"pkts"`
|
||||
Bytes uint64 `json:"bytes"`
|
||||
Target string `json:"target"`
|
||||
Protocol string `json:"prot"`
|
||||
Opt string `json:"opt"`
|
||||
Input string `json:"in"`
|
||||
Output string `json:"out"`
|
||||
Source *net.IPNet `json:"source"`
|
||||
Destination *net.IPNet `json:"destination"`
|
||||
Options string `json:"options"`
|
||||
}
|
||||
|
||||
type option func(*IPTables)
|
||||
|
||||
func IPFamily(proto Protocol) option {
|
||||
return func(ipt *IPTables) {
|
||||
ipt.proto = proto
|
||||
}
|
||||
}
|
||||
|
||||
func Timeout(timeout int) option {
|
||||
return func(ipt *IPTables) {
|
||||
ipt.timeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new IPTables configured with the options passed as parameter.
|
||||
// For backwards compatibility, by default always uses IPv4 and timeout 0.
|
||||
// i.e. you can create an IPv6 IPTables using a timeout of 5 seconds passing
|
||||
// the IPFamily and Timeout options as follow:
|
||||
// ip6t := New(IPFamily(ProtocolIPv6), Timeout(5))
|
||||
func New(opts ...option) (*IPTables, error) {
|
||||
|
||||
ipt := &IPTables{
|
||||
proto: ProtocolIPv4,
|
||||
timeout: 0,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(ipt)
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(getIptablesCommand(ipt.proto))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ipt.path = path
|
||||
|
||||
vstring, err := getIptablesVersionString(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get iptables version: %v", err)
|
||||
}
|
||||
v1, v2, v3, mode, err := extractIptablesVersion(vstring)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract iptables version from [%s]: %v", vstring, err)
|
||||
}
|
||||
ipt.v1 = v1
|
||||
ipt.v2 = v2
|
||||
ipt.v3 = v3
|
||||
ipt.mode = mode
|
||||
|
||||
checkPresent, waitPresent, waitSupportSecond, randomFullyPresent := getIptablesCommandSupport(v1, v2, v3)
|
||||
ipt.hasCheck = checkPresent
|
||||
ipt.hasWait = waitPresent
|
||||
ipt.waitSupportSecond = waitSupportSecond
|
||||
ipt.hasRandomFully = randomFullyPresent
|
||||
|
||||
return ipt, nil
|
||||
}
|
||||
|
||||
// New creates a new IPTables for the given proto.
|
||||
// The proto will determine which command is used, either "iptables" or "ip6tables".
|
||||
func NewWithProtocol(proto Protocol) (*IPTables, error) {
|
||||
path, err := exec.LookPath(getIptablesCommand(proto))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vstring, err := getIptablesVersionString(path)
|
||||
v1, v2, v3, mode, err := extractIptablesVersion(vstring)
|
||||
|
||||
checkPresent, waitPresent, randomFullyPresent := getIptablesCommandSupport(v1, v2, v3)
|
||||
|
||||
ipt := IPTables{
|
||||
path: path,
|
||||
proto: proto,
|
||||
hasCheck: checkPresent,
|
||||
hasWait: waitPresent,
|
||||
hasRandomFully: randomFullyPresent,
|
||||
v1: v1,
|
||||
v2: v2,
|
||||
v3: v3,
|
||||
mode: mode,
|
||||
}
|
||||
return &ipt, nil
|
||||
return New(IPFamily(proto), Timeout(0))
|
||||
}
|
||||
|
||||
// Proto returns the protocol used by this IPTables.
|
||||
@@ -160,6 +211,14 @@ func (ipt *IPTables) Delete(table, chain string, rulespec ...string) error {
|
||||
return ipt.run(cmd...)
|
||||
}
|
||||
|
||||
func (ipt *IPTables) DeleteIfExists(table, chain string, rulespec ...string) error {
|
||||
exists, err := ipt.Exists(table, chain, rulespec...)
|
||||
if err == nil && exists {
|
||||
err = ipt.Delete(table, chain, rulespec...)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// List rules in specified table/chain
|
||||
func (ipt *IPTables) List(table, chain string) ([]string, error) {
|
||||
args := []string{"-t", table, "-S", chain}
|
||||
@@ -197,6 +256,21 @@ func (ipt *IPTables) ListChains(table string) ([]string, error) {
|
||||
return chains, nil
|
||||
}
|
||||
|
||||
// '-S' is fine with non existing rule index as long as the chain exists
|
||||
// therefore pass index 1 to reduce overhead for large chains
|
||||
func (ipt *IPTables) ChainExists(table, chain string) (bool, error) {
|
||||
err := ipt.run("-t", table, "-S", chain, "1")
|
||||
eerr, eok := err.(*Error)
|
||||
switch {
|
||||
case err == nil:
|
||||
return true, nil
|
||||
case eok && eerr.ExitStatus() == 1:
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
// Stats lists rules including the byte and packet counts
|
||||
func (ipt *IPTables) Stats(table, chain string) ([][]string, error) {
|
||||
args := []string{"-t", table, "-L", chain, "-n", "-v", "-x"}
|
||||
@@ -263,6 +337,63 @@ func (ipt *IPTables) Stats(table, chain string) ([][]string, error) {
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// ParseStat parses a single statistic row into a Stat struct. The input should
|
||||
// be a string slice that is returned from calling the Stat method.
|
||||
func (ipt *IPTables) ParseStat(stat []string) (parsed Stat, err error) {
|
||||
// For forward-compatibility, expect at least 10 fields in the stat
|
||||
if len(stat) < 10 {
|
||||
return parsed, fmt.Errorf("stat contained fewer fields than expected")
|
||||
}
|
||||
|
||||
// Convert the fields that are not plain strings
|
||||
parsed.Packets, err = strconv.ParseUint(stat[0], 0, 64)
|
||||
if err != nil {
|
||||
return parsed, fmt.Errorf(err.Error(), "could not parse packets")
|
||||
}
|
||||
parsed.Bytes, err = strconv.ParseUint(stat[1], 0, 64)
|
||||
if err != nil {
|
||||
return parsed, fmt.Errorf(err.Error(), "could not parse bytes")
|
||||
}
|
||||
_, parsed.Source, err = net.ParseCIDR(stat[7])
|
||||
if err != nil {
|
||||
return parsed, fmt.Errorf(err.Error(), "could not parse source")
|
||||
}
|
||||
_, parsed.Destination, err = net.ParseCIDR(stat[8])
|
||||
if err != nil {
|
||||
return parsed, fmt.Errorf(err.Error(), "could not parse destination")
|
||||
}
|
||||
|
||||
// Put the fields that are strings
|
||||
parsed.Target = stat[2]
|
||||
parsed.Protocol = stat[3]
|
||||
parsed.Opt = stat[4]
|
||||
parsed.Input = stat[5]
|
||||
parsed.Output = stat[6]
|
||||
parsed.Options = stat[9]
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
// StructuredStats returns statistics as structured data which may be further
|
||||
// parsed and marshaled.
|
||||
func (ipt *IPTables) StructuredStats(table, chain string) ([]Stat, error) {
|
||||
rawStats, err := ipt.Stats(table, chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
structStats := []Stat{}
|
||||
for _, rawStat := range rawStats {
|
||||
stat, err := ipt.ParseStat(rawStat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
structStats = append(structStats, stat)
|
||||
}
|
||||
|
||||
return structStats, nil
|
||||
}
|
||||
|
||||
func (ipt *IPTables) executeList(args []string) ([]string, error) {
|
||||
var stdout bytes.Buffer
|
||||
if err := ipt.runWithOutput(args, &stdout); err != nil {
|
||||
@@ -276,17 +407,6 @@ func (ipt *IPTables) executeList(args []string) ([]string, error) {
|
||||
rules = rules[:len(rules)-1]
|
||||
}
|
||||
|
||||
// nftables mode doesn't return an error code when listing a non-existent
|
||||
// chain. Patch that up.
|
||||
if len(rules) == 0 && ipt.mode == "nf_tables" {
|
||||
v := 1
|
||||
return nil, &Error{
|
||||
cmd: exec.Cmd{Args: args},
|
||||
msg: "iptables: No chain/target/match by that name.",
|
||||
exitStatus: &v,
|
||||
}
|
||||
}
|
||||
|
||||
for i, rule := range rules {
|
||||
rules[i] = filterRuleOutput(rule)
|
||||
}
|
||||
@@ -300,18 +420,13 @@ func (ipt *IPTables) NewChain(table, chain string) error {
|
||||
return ipt.run("-t", table, "-N", chain)
|
||||
}
|
||||
|
||||
const existsErr = 1
|
||||
|
||||
// ClearChain flushed (deletes all rules) in the specified table/chain.
|
||||
// If the chain does not exist, a new one will be created
|
||||
func (ipt *IPTables) ClearChain(table, chain string) error {
|
||||
err := ipt.NewChain(table, chain)
|
||||
|
||||
// the exit code for "this table already exists" is different for
|
||||
// different iptables modes
|
||||
existsErr := 1
|
||||
if ipt.mode == "nf_tables" {
|
||||
existsErr = 4
|
||||
}
|
||||
|
||||
eerr, eok := err.(*Error)
|
||||
switch {
|
||||
case err == nil:
|
||||
@@ -335,6 +450,26 @@ func (ipt *IPTables) DeleteChain(table, chain string) error {
|
||||
return ipt.run("-t", table, "-X", chain)
|
||||
}
|
||||
|
||||
func (ipt *IPTables) ClearAndDeleteChain(table, chain string) error {
|
||||
exists, err := ipt.ChainExists(table, chain)
|
||||
if err != nil || !exists {
|
||||
return err
|
||||
}
|
||||
err = ipt.run("-t", table, "-F", chain)
|
||||
if err == nil {
|
||||
err = ipt.run("-t", table, "-X", chain)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (ipt *IPTables) ClearAll() error {
|
||||
return ipt.run("-F")
|
||||
}
|
||||
|
||||
func (ipt *IPTables) DeleteAll() error {
|
||||
return ipt.run("-X")
|
||||
}
|
||||
|
||||
// ChangePolicy changes policy on chain to target
|
||||
func (ipt *IPTables) ChangePolicy(table, chain, target string) error {
|
||||
return ipt.run("-t", table, "-P", chain, target)
|
||||
@@ -362,6 +497,9 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error {
|
||||
args = append([]string{ipt.path}, args...)
|
||||
if ipt.hasWait {
|
||||
args = append(args, "--wait")
|
||||
if ipt.timeout != 0 && ipt.waitSupportSecond {
|
||||
args = append(args, strconv.Itoa(ipt.timeout))
|
||||
}
|
||||
} else {
|
||||
fmu, err := newXtablesFileLock()
|
||||
if err != nil {
|
||||
@@ -369,6 +507,7 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error {
|
||||
}
|
||||
ul, err := fmu.tryLock()
|
||||
if err != nil {
|
||||
syscall.Close(fmu.fd)
|
||||
return err
|
||||
}
|
||||
defer ul.Unlock()
|
||||
@@ -404,8 +543,8 @@ func getIptablesCommand(proto Protocol) string {
|
||||
}
|
||||
|
||||
// Checks if iptables has the "-C" and "--wait" flag
|
||||
func getIptablesCommandSupport(v1 int, v2 int, v3 int) (bool, bool, bool) {
|
||||
return iptablesHasCheckCommand(v1, v2, v3), iptablesHasWaitCommand(v1, v2, v3), iptablesHasRandomFully(v1, v2, v3)
|
||||
func getIptablesCommandSupport(v1 int, v2 int, v3 int) (bool, bool, bool, bool) {
|
||||
return iptablesHasCheckCommand(v1, v2, v3), iptablesHasWaitCommand(v1, v2, v3), iptablesWaitSupportSecond(v1, v2, v3), iptablesHasRandomFully(v1, v2, v3)
|
||||
}
|
||||
|
||||
// getIptablesVersion returns the first three components of the iptables version
|
||||
@@ -480,6 +619,17 @@ func iptablesHasWaitCommand(v1 int, v2 int, v3 int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//Checks if an iptablse version is after 1.6.0, when --wait support second
|
||||
func iptablesWaitSupportSecond(v1 int, v2 int, v3 int) bool {
|
||||
if v1 > 1 {
|
||||
return true
|
||||
}
|
||||
if v1 == 1 && v2 >= 6 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Checks if an iptables version is after 1.6.2, when --random-fully was added
|
||||
func iptablesHasRandomFully(v1 int, v2 int, v3 int) bool {
|
||||
if v1 > 1 {
|
||||
|
6
vendor/github.com/evanphx/json-patch/.gitignore
generated
vendored
Normal file
6
vendor/github.com/evanphx/json-patch/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# editor and IDE paraphernalia
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# macOS paraphernalia
|
||||
.DS_Store
|
19
vendor/github.com/evanphx/json-patch/.travis.yml
generated
vendored
19
vendor/github.com/evanphx/json-patch/.travis.yml
generated
vendored
@@ -1,19 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.14
|
||||
- 1.13
|
||||
|
||||
install:
|
||||
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||
- go get github.com/jessevdk/go-flags
|
||||
|
||||
script:
|
||||
- go get
|
||||
- go test -cover ./...
|
||||
- cd ./v5
|
||||
- go get
|
||||
- go test -cover ./...
|
||||
|
||||
notifications:
|
||||
email: false
|
19
vendor/github.com/evanphx/json-patch/README.md
generated
vendored
19
vendor/github.com/evanphx/json-patch/README.md
generated
vendored
@@ -39,6 +39,25 @@ go get -u github.com/evanphx/json-patch/v5
|
||||
which limits the total size increase in bytes caused by "copy" operations in a
|
||||
patch. It defaults to 0, which means there is no limit.
|
||||
|
||||
These global variables control the behavior of `jsonpatch.Apply`.
|
||||
|
||||
An alternative to `jsonpatch.Apply` is `jsonpatch.ApplyWithOptions` whose behavior
|
||||
is controlled by an `options` parameter of type `*jsonpatch.ApplyOptions`.
|
||||
|
||||
Structure `jsonpatch.ApplyOptions` includes the configuration options above
|
||||
and adds two new options: `AllowMissingPathOnRemove` and `EnsurePathExistsOnAdd`.
|
||||
|
||||
When `AllowMissingPathOnRemove` is set to `true`, `jsonpatch.ApplyWithOptions` will ignore
|
||||
`remove` operations whose `path` points to a non-existent location in the JSON document.
|
||||
`AllowMissingPathOnRemove` defaults to `false` which will lead to `jsonpatch.ApplyWithOptions`
|
||||
returning an error when hitting a missing `path` on `remove`.
|
||||
|
||||
When `EnsurePathExistsOnAdd` is set to `true`, `jsonpatch.ApplyWithOptions` will make sure
|
||||
that `add` operations produce all the `path` elements that are missing from the target object.
|
||||
|
||||
Use `jsonpatch.NewApplyOptions` to create an instance of `jsonpatch.ApplyOptions`
|
||||
whose values are populated from the global configuration variables.
|
||||
|
||||
## Create and apply a merge patch
|
||||
Given both an original JSON document and a modified JSON document, you can create
|
||||
a [Merge Patch](https://tools.ietf.org/html/rfc7396) document.
|
||||
|
33
vendor/github.com/evanphx/json-patch/merge.go
generated
vendored
33
vendor/github.com/evanphx/json-patch/merge.go
generated
vendored
@@ -38,7 +38,10 @@ func mergeDocs(doc, patch *partialDoc, mergeMerge bool) {
|
||||
cur, ok := (*doc)[k]
|
||||
|
||||
if !ok || cur == nil {
|
||||
pruneNulls(v)
|
||||
if !mergeMerge {
|
||||
pruneNulls(v)
|
||||
}
|
||||
|
||||
(*doc)[k] = v
|
||||
} else {
|
||||
(*doc)[k] = merge(cur, v, mergeMerge)
|
||||
@@ -79,8 +82,8 @@ func pruneAryNulls(ary *partialArray) *partialArray {
|
||||
for _, v := range *ary {
|
||||
if v != nil {
|
||||
pruneNulls(v)
|
||||
newAry = append(newAry, v)
|
||||
}
|
||||
newAry = append(newAry, v)
|
||||
}
|
||||
|
||||
*ary = newAry
|
||||
@@ -88,8 +91,8 @@ func pruneAryNulls(ary *partialArray) *partialArray {
|
||||
return ary
|
||||
}
|
||||
|
||||
var errBadJSONDoc = fmt.Errorf("Invalid JSON Document")
|
||||
var errBadJSONPatch = fmt.Errorf("Invalid JSON Patch")
|
||||
var ErrBadJSONDoc = fmt.Errorf("Invalid JSON Document")
|
||||
var ErrBadJSONPatch = fmt.Errorf("Invalid JSON Patch")
|
||||
var errBadMergeTypes = fmt.Errorf("Mismatched JSON Documents")
|
||||
|
||||
// MergeMergePatches merges two merge patches together, such that
|
||||
@@ -114,19 +117,19 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
|
||||
patchErr := json.Unmarshal(patchData, patch)
|
||||
|
||||
if _, ok := docErr.(*json.SyntaxError); ok {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
if _, ok := patchErr.(*json.SyntaxError); ok {
|
||||
return nil, errBadJSONPatch
|
||||
return nil, ErrBadJSONPatch
|
||||
}
|
||||
|
||||
if docErr == nil && *doc == nil {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
if patchErr == nil && *patch == nil {
|
||||
return nil, errBadJSONPatch
|
||||
return nil, ErrBadJSONPatch
|
||||
}
|
||||
|
||||
if docErr != nil || patchErr != nil {
|
||||
@@ -142,7 +145,7 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
|
||||
patchErr = json.Unmarshal(patchData, patchAry)
|
||||
|
||||
if patchErr != nil {
|
||||
return nil, errBadJSONPatch
|
||||
return nil, ErrBadJSONPatch
|
||||
}
|
||||
|
||||
pruneAryNulls(patchAry)
|
||||
@@ -150,7 +153,7 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
|
||||
out, patchErr := json.Marshal(patchAry)
|
||||
|
||||
if patchErr != nil {
|
||||
return nil, errBadJSONPatch
|
||||
return nil, ErrBadJSONPatch
|
||||
}
|
||||
|
||||
return out, nil
|
||||
@@ -207,12 +210,12 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
|
||||
|
||||
err := json.Unmarshal(originalJSON, &originalDoc)
|
||||
if err != nil {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
err = json.Unmarshal(modifiedJSON, &modifiedDoc)
|
||||
if err != nil {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
dest, err := getDiff(originalDoc, modifiedDoc)
|
||||
@@ -233,17 +236,17 @@ func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
|
||||
|
||||
err := json.Unmarshal(originalJSON, &originalDocs)
|
||||
if err != nil {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
err = json.Unmarshal(modifiedJSON, &modifiedDocs)
|
||||
if err != nil {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
total := len(originalDocs)
|
||||
if len(modifiedDocs) != total {
|
||||
return nil, errBadJSONDoc
|
||||
return nil, ErrBadJSONDoc
|
||||
}
|
||||
|
||||
result := []json.RawMessage{}
|
||||
|
67
vendor/github.com/evanphx/json-patch/patch.go
generated
vendored
67
vendor/github.com/evanphx/json-patch/patch.go
generated
vendored
@@ -412,6 +412,17 @@ func (d *partialArray) set(key string, val *lazyNode) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if idx < 0 {
|
||||
if !SupportNegativeIndices {
|
||||
return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||
}
|
||||
if idx < -len(*d) {
|
||||
return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||
}
|
||||
idx += len(*d)
|
||||
}
|
||||
|
||||
(*d)[idx] = val
|
||||
return nil
|
||||
}
|
||||
@@ -462,6 +473,16 @@ func (d *partialArray) get(key string) (*lazyNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if idx < 0 {
|
||||
if !SupportNegativeIndices {
|
||||
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||
}
|
||||
if idx < -len(*d) {
|
||||
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||
}
|
||||
idx += len(*d)
|
||||
}
|
||||
|
||||
if idx >= len(*d) {
|
||||
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||
}
|
||||
@@ -547,6 +568,29 @@ func (p Patch) replace(doc *container, op Operation) error {
|
||||
return errors.Wrapf(err, "replace operation failed to decode path")
|
||||
}
|
||||
|
||||
if path == "" {
|
||||
val := op.value()
|
||||
|
||||
if val.which == eRaw {
|
||||
if !val.tryDoc() {
|
||||
if !val.tryAry() {
|
||||
return errors.Wrapf(err, "replace operation value must be object or array")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch val.which {
|
||||
case eAry:
|
||||
*doc = &val.ary
|
||||
case eDoc:
|
||||
*doc = &val.doc
|
||||
case eRaw:
|
||||
return errors.Wrapf(err, "replace operation hit impossible case")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
con, key := findObject(doc, path)
|
||||
|
||||
if con == nil {
|
||||
@@ -613,6 +657,25 @@ func (p Patch) test(doc *container, op Operation) error {
|
||||
return errors.Wrapf(err, "test operation failed to decode path")
|
||||
}
|
||||
|
||||
if path == "" {
|
||||
var self lazyNode
|
||||
|
||||
switch sv := (*doc).(type) {
|
||||
case *partialDoc:
|
||||
self.doc = *sv
|
||||
self.which = eDoc
|
||||
case *partialArray:
|
||||
self.ary = *sv
|
||||
self.which = eAry
|
||||
}
|
||||
|
||||
if self.equal(op.value()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
|
||||
}
|
||||
|
||||
con, key := findObject(doc, path)
|
||||
|
||||
if con == nil {
|
||||
@@ -721,6 +784,10 @@ func (p Patch) Apply(doc []byte) ([]byte, error) {
|
||||
// ApplyIndent mutates a JSON document according to the patch, and returns the new
|
||||
// document indented.
|
||||
func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) {
|
||||
if len(doc) == 0 {
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
var pd container
|
||||
if doc[0] == '[' {
|
||||
pd = &partialArray{}
|
||||
|
29
vendor/github.com/go-logr/logr/.golangci.yaml
generated
vendored
Normal file
29
vendor/github.com/go-logr/logr/.golangci.yaml
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
run:
|
||||
timeout: 1m
|
||||
tests: true
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- asciicheck
|
||||
- deadcode
|
||||
- errcheck
|
||||
- forcetypeassert
|
||||
- gocritic
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- revive
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 10
|
6
vendor/github.com/go-logr/logr/CHANGELOG.md
generated
vendored
Normal file
6
vendor/github.com/go-logr/logr/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.0.0-rc1
|
||||
|
||||
This is the first logged release. Major changes (including breaking changes)
|
||||
have occurred since earlier tags.
|
17
vendor/github.com/go-logr/logr/CONTRIBUTING.md
generated
vendored
Normal file
17
vendor/github.com/go-logr/logr/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Contributing
|
||||
|
||||
Logr is open to pull-requests, provided they fit within the intended scope of
|
||||
the project. Specifically, this library aims to be VERY small and minimalist,
|
||||
with no external dependencies.
|
||||
|
||||
## Compatibility
|
||||
|
||||
This project intends to follow [semantic versioning](http://semver.org) and
|
||||
is very strict about compatibility. Any proposed changes MUST follow those
|
||||
rules.
|
||||
|
||||
## Performance
|
||||
|
||||
As a logging library, logr must be as light-weight as possible. Any proposed
|
||||
code change must include results of running the [benchmark](./benchmark)
|
||||
before and after the change.
|
209
vendor/github.com/go-logr/logr/README.md
generated
vendored
209
vendor/github.com/go-logr/logr/README.md
generated
vendored
@@ -1,112 +1,182 @@
|
||||
# A more minimal logging API for Go
|
||||
# A minimal logging API for Go
|
||||
|
||||
[](https://pkg.go.dev/github.com/go-logr/logr)
|
||||
|
||||
logr offers an(other) opinion on how Go programs and libraries can do logging
|
||||
without becoming coupled to a particular logging implementation. This is not
|
||||
an implementation of logging - it is an API. In fact it is two APIs with two
|
||||
different sets of users.
|
||||
|
||||
The `Logger` type is intended for application and library authors. It provides
|
||||
a relatively small API which can be used everywhere you want to emit logs. It
|
||||
defers the actual act of writing logs (to files, to stdout, or whatever) to the
|
||||
`LogSink` interface.
|
||||
|
||||
The `LogSink` interface is intended for logging library implementers. It is a
|
||||
pure interface which can be implemented by logging frameworks to provide the actual logging
|
||||
functionality.
|
||||
|
||||
This decoupling allows application and library developers to write code in
|
||||
terms of `logr.Logger` (which has very low dependency fan-out) while the
|
||||
implementation of logging is managed "up stack" (e.g. in or near `main()`.)
|
||||
Application developers can then switch out implementations as necessary.
|
||||
|
||||
Many people assert that libraries should not be logging, and as such efforts
|
||||
like this are pointless. Those people are welcome to convince the authors of
|
||||
the tens-of-thousands of libraries that *DO* write logs that they are all
|
||||
wrong. In the meantime, logr takes a more practical approach.
|
||||
|
||||
## Typical usage
|
||||
|
||||
Somewhere, early in an application's life, it will make a decision about which
|
||||
logging library (implementation) it actually wants to use. Something like:
|
||||
|
||||
```
|
||||
func main() {
|
||||
// ... other setup code ...
|
||||
|
||||
// Create the "root" logger. We have chosen the "logimpl" implementation,
|
||||
// which takes some initial parameters and returns a logr.Logger.
|
||||
logger := logimpl.New(param1, param2)
|
||||
|
||||
// ... other setup code ...
|
||||
```
|
||||
|
||||
Most apps will call into other libraries, create structures to govern the flow,
|
||||
etc. The `logr.Logger` object can be passed to these other libraries, stored
|
||||
in structs, or even used as a package-global variable, if needed. For example:
|
||||
|
||||
```
|
||||
app := createTheAppObject(logger)
|
||||
app.Run()
|
||||
```
|
||||
|
||||
Outside of this early setup, no other packages need to know about the choice of
|
||||
implementation. They write logs in terms of the `logr.Logger` that they
|
||||
received:
|
||||
|
||||
```
|
||||
type appObject struct {
|
||||
// ... other fields ...
|
||||
logger logr.Logger
|
||||
// ... other fields ...
|
||||
}
|
||||
|
||||
func (app *appObject) Run() {
|
||||
app.logger.Info("starting up", "timestamp", time.Now())
|
||||
|
||||
// ... app code ...
|
||||
```
|
||||
|
||||
## Background
|
||||
|
||||
If the Go standard library had defined an interface for logging, this project
|
||||
probably would not be needed. Alas, here we are.
|
||||
|
||||
### Inspiration
|
||||
|
||||
Before you consider this package, please read [this blog post by the
|
||||
inimitable Dave Cheney][warning-makes-no-sense]. I really appreciate what
|
||||
he has to say, and it largely aligns with my own experiences. Too many
|
||||
choices of levels means inconsistent logs.
|
||||
inimitable Dave Cheney][warning-makes-no-sense]. We really appreciate what
|
||||
he has to say, and it largely aligns with our own experiences.
|
||||
|
||||
This package offers a purely abstract interface, based on these ideas but with
|
||||
a few twists. Code can depend on just this interface and have the actual
|
||||
logging implementation be injected from callers. Ideally only `main()` knows
|
||||
what logging implementation is being used.
|
||||
|
||||
# Differences from Dave's ideas
|
||||
### Differences from Dave's ideas
|
||||
|
||||
The main differences are:
|
||||
|
||||
1) Dave basically proposes doing away with the notion of a logging API in favor
|
||||
of `fmt.Printf()`. I disagree, especially when you consider things like output
|
||||
locations, timestamps, file and line decorations, and structured logging. I
|
||||
restrict the API to just 2 types of logs: info and error.
|
||||
1. Dave basically proposes doing away with the notion of a logging API in favor
|
||||
of `fmt.Printf()`. We disagree, especially when you consider things like output
|
||||
locations, timestamps, file and line decorations, and structured logging. This
|
||||
package restricts the logging API to just 2 types of logs: info and error.
|
||||
|
||||
Info logs are things you want to tell the user which are not errors. Error
|
||||
logs are, well, errors. If your code receives an `error` from a subordinate
|
||||
function call and is logging that `error` *and not returning it*, use error
|
||||
logs.
|
||||
|
||||
2) Verbosity-levels on info logs. This gives developers a chance to indicate
|
||||
2. Verbosity-levels on info logs. This gives developers a chance to indicate
|
||||
arbitrary grades of importance for info logs, without assigning names with
|
||||
semantic meaning such as "warning", "trace", and "debug". Superficially this
|
||||
semantic meaning such as "warning", "trace", and "debug." Superficially this
|
||||
may feel very similar, but the primary difference is the lack of semantics.
|
||||
Because verbosity is a numerical value, it's safe to assume that an app running
|
||||
with higher verbosity means more (and less important) logs will be generated.
|
||||
|
||||
This is a BETA grade API.
|
||||
## Implementations (non-exhaustive)
|
||||
|
||||
There are implementations for the following logging libraries:
|
||||
|
||||
- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)
|
||||
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
|
||||
- **k8s.io/klog**: [klogr](https://git.k8s.io/klog/klogr)
|
||||
- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)
|
||||
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
|
||||
- **log** (the Go standard library logger):
|
||||
[stdr](https://github.com/go-logr/stdr)
|
||||
- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)
|
||||
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
|
||||
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
|
||||
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
|
||||
- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)
|
||||
|
||||
# FAQ
|
||||
## FAQ
|
||||
|
||||
## Conceptual
|
||||
### Conceptual
|
||||
|
||||
## Why structured logging?
|
||||
#### Why structured logging?
|
||||
|
||||
- **Structured logs are more easily queriable**: Since you've got
|
||||
- **Structured logs are more easily queryable**: Since you've got
|
||||
key-value pairs, it's much easier to query your structured logs for
|
||||
particular values by filtering on the contents of a particular key --
|
||||
think searching request logs for error codes, Kubernetes reconcilers for
|
||||
the name and namespace of the reconciled object, etc
|
||||
the name and namespace of the reconciled object, etc.
|
||||
|
||||
- **Structured logging makes it easier to have cross-referencable logs**:
|
||||
- **Structured logging makes it easier to have cross-referenceable logs**:
|
||||
Similarly to searchability, if you maintain conventions around your
|
||||
keys, it becomes easy to gather all log lines related to a particular
|
||||
concept.
|
||||
|
||||
|
||||
- **Structured logs allow better dimensions of filtering**: if you have
|
||||
structure to your logs, you've got more precise control over how much
|
||||
information is logged -- you might choose in a particular configuration
|
||||
to log certain keys but not others, only log lines where a certain key
|
||||
matches a certain value, etc, instead of just having v-levels and names
|
||||
matches a certain value, etc., instead of just having v-levels and names
|
||||
to key off of.
|
||||
|
||||
- **Structured logs better represent structured data**: sometimes, the
|
||||
data that you want to log is inherently structured (think tuple-link
|
||||
objects). Structured logs allow you to preserve that structure when
|
||||
objects.) Structured logs allow you to preserve that structure when
|
||||
outputting.
|
||||
|
||||
## Why V-levels?
|
||||
#### Why V-levels?
|
||||
|
||||
**V-levels give operators an easy way to control the chattiness of log
|
||||
operations**. V-levels provide a way for a given package to distinguish
|
||||
the relative importance or verbosity of a given log message. Then, if
|
||||
a particular logger or package is logging too many messages, the user
|
||||
of the package can simply change the v-levels for that library.
|
||||
of the package can simply change the v-levels for that library.
|
||||
|
||||
## Why not more named levels, like Warning?
|
||||
#### Why not named levels, like Info/Warning/Error?
|
||||
|
||||
Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences
|
||||
from Dave's ideas](#differences-from-daves-ideas).
|
||||
|
||||
## Why not allow format strings, too?
|
||||
#### Why not allow format strings, too?
|
||||
|
||||
**Format strings negate many of the benefits of structured logs**:
|
||||
|
||||
- They're not easily searchable without resorting to fuzzy searching,
|
||||
regular expressions, etc
|
||||
regular expressions, etc.
|
||||
|
||||
- They don't store structured data well, since contents are flattened into
|
||||
a string
|
||||
a string.
|
||||
|
||||
- They're not cross-referencable
|
||||
- They're not cross-referenceable.
|
||||
|
||||
- They don't compress easily, since the message is not constant
|
||||
- They don't compress easily, since the message is not constant.
|
||||
|
||||
(unless you turn positional parameters into key-value pairs with numerical
|
||||
(Unless you turn positional parameters into key-value pairs with numerical
|
||||
keys, at which point you've gotten key-value logging with meaningless
|
||||
keys)
|
||||
keys.)
|
||||
|
||||
## Practical
|
||||
### Practical
|
||||
|
||||
## Why key-value pairs, and not a map?
|
||||
#### Why key-value pairs, and not a map?
|
||||
|
||||
Key-value pairs are *much* easier to optimize, especially around
|
||||
allocations. Zap (a structured logger that inspired logr's interface) has
|
||||
@@ -117,26 +187,26 @@ While the interface ends up being a little less obvious, you get
|
||||
potentially better performance, plus avoid making users type
|
||||
`map[string]string{}` every time they want to log.
|
||||
|
||||
## What if my V-levels differ between libraries?
|
||||
#### What if my V-levels differ between libraries?
|
||||
|
||||
That's fine. Control your V-levels on a per-logger basis, and use the
|
||||
`WithName` function to pass different loggers to different libraries.
|
||||
`WithName` method to pass different loggers to different libraries.
|
||||
|
||||
Generally, you should take care to ensure that you have relatively
|
||||
consistent V-levels within a given logger, however, as this makes deciding
|
||||
on what verbosity of logs to request easier.
|
||||
|
||||
## But I *really* want to use a format string!
|
||||
#### But I really want to use a format string!
|
||||
|
||||
That's not actually a question. Assuming your question is "how do
|
||||
I convert my mental model of logging with format strings to logging with
|
||||
constant messages":
|
||||
|
||||
1. figure out what the error actually is, as you'd write in a TL;DR style,
|
||||
and use that as a message
|
||||
1. Figure out what the error actually is, as you'd write in a TL;DR style,
|
||||
and use that as a message.
|
||||
|
||||
2. For every place you'd write a format specifier, look to the word before
|
||||
it, and add that as a key value pair
|
||||
it, and add that as a key value pair.
|
||||
|
||||
For instance, consider the following examples (all taken from spots in the
|
||||
Kubernetes codebase):
|
||||
@@ -150,34 +220,59 @@ Kubernetes codebase):
|
||||
response when requesting url", "attempt", retries, "after
|
||||
seconds", seconds, "url", url)`
|
||||
|
||||
If you *really* must use a format string, place it as a key value, and
|
||||
call `fmt.Sprintf` yourself -- for instance, `log.Printf("unable to
|
||||
If you *really* must use a format string, use it in a key's value, and
|
||||
call `fmt.Sprintf` yourself. For instance: `log.Printf("unable to
|
||||
reflect over type %T")` becomes `logger.Info("unable to reflect over
|
||||
type", "type", fmt.Sprintf("%T"))`. In general though, the cases where
|
||||
this is necessary should be few and far between.
|
||||
|
||||
## How do I choose my V-levels?
|
||||
#### How do I choose my V-levels?
|
||||
|
||||
This is basically the only hard constraint: increase V-levels to denote
|
||||
more verbose or more debug-y logs.
|
||||
|
||||
Otherwise, you can start out with `0` as "you always want to see this",
|
||||
`1` as "common logging that you might *possibly* want to turn off", and
|
||||
`10` as "I would like to performance-test your log collection stack".
|
||||
`10` as "I would like to performance-test your log collection stack."
|
||||
|
||||
Then gradually choose levels in between as you need them, working your way
|
||||
down from 10 (for debug and trace style logs) and up from 1 (for chattier
|
||||
info-type logs).
|
||||
info-type logs.)
|
||||
|
||||
## How do I choose my keys
|
||||
#### How do I choose my keys?
|
||||
|
||||
- make your keys human-readable
|
||||
- constant keys are generally a good idea
|
||||
- be consistent across your codebase
|
||||
- keys should naturally match parts of the message string
|
||||
Keys are fairly flexible, and can hold more or less any string
|
||||
value. For best compatibility with implementations and consistency
|
||||
with existing code in other projects, there are a few conventions you
|
||||
should consider.
|
||||
|
||||
- Make your keys human-readable.
|
||||
- Constant keys are generally a good idea.
|
||||
- Be consistent across your codebase.
|
||||
- Keys should naturally match parts of the message string.
|
||||
- Use lower case for simple keys and
|
||||
[lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for
|
||||
more complex ones. Kubernetes is one example of a project that has
|
||||
[adopted that
|
||||
convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).
|
||||
|
||||
While key names are mostly unrestricted (and spaces are acceptable),
|
||||
it's generally a good idea to stick to printable ascii characters, or at
|
||||
least match the general character set of your log lines.
|
||||
|
||||
#### Why should keys be constant values?
|
||||
|
||||
The point of structured logging is to make later log processing easier. Your
|
||||
keys are, effectively, the schema of each log message. If you use different
|
||||
keys across instances of the same log line, you will make your structured logs
|
||||
much harder to use. `Sprintf()` is for values, not for keys!
|
||||
|
||||
#### Why is this not a pure interface?
|
||||
|
||||
The Logger type is implemented as a struct in order to allow the Go compiler to
|
||||
optimize things like high-V `Info` logs that are not triggered. Not all of
|
||||
these implementations are implemented yet, but this structure was suggested as
|
||||
a way to ensure they *can* be implemented. All of the real work is behind the
|
||||
`LogSink` interface.
|
||||
|
||||
[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||
|
37
vendor/github.com/go-logr/logr/discard.go
generated
vendored
37
vendor/github.com/go-logr/logr/discard.go
generated
vendored
@@ -16,36 +16,39 @@ limitations under the License.
|
||||
|
||||
package logr
|
||||
|
||||
// Discard returns a valid Logger that discards all messages logged to it.
|
||||
// It can be used whenever the caller is not interested in the logs.
|
||||
// Discard returns a Logger that discards all messages logged to it. It can be
|
||||
// used whenever the caller is not interested in the logs. Logger instances
|
||||
// produced by this function always compare as equal.
|
||||
func Discard() Logger {
|
||||
return DiscardLogger{}
|
||||
return Logger{
|
||||
level: 0,
|
||||
sink: discardLogSink{},
|
||||
}
|
||||
}
|
||||
|
||||
// DiscardLogger is a Logger that discards all messages.
|
||||
type DiscardLogger struct{}
|
||||
// discardLogSink is a LogSink that discards all messages.
|
||||
type discardLogSink struct{}
|
||||
|
||||
func (l DiscardLogger) Enabled() bool {
|
||||
// Verify that it actually implements the interface
|
||||
var _ LogSink = discardLogSink{}
|
||||
|
||||
func (l discardLogSink) Init(RuntimeInfo) {
|
||||
}
|
||||
|
||||
func (l discardLogSink) Enabled(int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (l DiscardLogger) Info(msg string, keysAndValues ...interface{}) {
|
||||
func (l discardLogSink) Info(int, string, ...interface{}) {
|
||||
}
|
||||
|
||||
func (l DiscardLogger) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||
func (l discardLogSink) Error(error, string, ...interface{}) {
|
||||
}
|
||||
|
||||
func (l DiscardLogger) V(level int) Logger {
|
||||
func (l discardLogSink) WithValues(...interface{}) LogSink {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l DiscardLogger) WithValues(keysAndValues ...interface{}) Logger {
|
||||
func (l discardLogSink) WithName(string) LogSink {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l DiscardLogger) WithName(name string) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
// Verify that it actually implements the interface
|
||||
var _ Logger = DiscardLogger{}
|
||||
|
544
vendor/github.com/go-logr/logr/logr.go
generated
vendored
544
vendor/github.com/go-logr/logr/logr.go
generated
vendored
@@ -16,83 +16,101 @@ limitations under the License.
|
||||
|
||||
// This design derives from Dave Cheney's blog:
|
||||
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||
//
|
||||
// This is a BETA grade API. Until there is a significant 2nd implementation,
|
||||
// I don't really know how it will change.
|
||||
|
||||
// Package logr defines abstract interfaces for logging. Packages can depend on
|
||||
// these interfaces and callers can implement logging in whatever way is
|
||||
// appropriate.
|
||||
// Package logr defines a general-purpose logging API and abstract interfaces
|
||||
// to back that API. Packages in the Go ecosystem can depend on this package,
|
||||
// while callers can implement logging with whatever backend is appropriate.
|
||||
//
|
||||
// Usage
|
||||
//
|
||||
// Logging is done using a Logger. Loggers can have name prefixes and named
|
||||
// values attached, so that all log messages logged with that Logger have some
|
||||
// base context associated.
|
||||
// Logging is done using a Logger instance. Logger is a concrete type with
|
||||
// methods, which defers the actual logging to a LogSink interface. The main
|
||||
// methods of Logger are Info() and Error(). Arguments to Info() and Error()
|
||||
// are key/value pairs rather than printf-style formatted strings, emphasizing
|
||||
// "structured logging".
|
||||
//
|
||||
// The term "key" is used to refer to the name associated with a particular
|
||||
// value, to disambiguate it from the general Logger name.
|
||||
// With Go's standard log package, we might write:
|
||||
// log.Printf("setting target value %s", targetValue)
|
||||
//
|
||||
// For instance, suppose we're trying to reconcile the state of an object, and
|
||||
// we want to log that we've made some decision.
|
||||
// With logr's structured logging, we'd write:
|
||||
// logger.Info("setting target", "value", targetValue)
|
||||
//
|
||||
// With the traditional log package, we might write:
|
||||
// Errors are much the same. Instead of:
|
||||
// log.Printf("failed to open the pod bay door for user %s: %v", user, err)
|
||||
//
|
||||
// We'd write:
|
||||
// logger.Error(err, "failed to open the pod bay door", "user", user)
|
||||
//
|
||||
// Info() and Error() are very similar, but they are separate methods so that
|
||||
// LogSink implementations can choose to do things like attach additional
|
||||
// information (such as stack traces) on calls to Error().
|
||||
//
|
||||
// Verbosity
|
||||
//
|
||||
// Often we want to log information only when the application in "verbose
|
||||
// mode". To write log lines that are more verbose, Logger has a V() method.
|
||||
// The higher the V-level of a log line, the less critical it is considered.
|
||||
// Log-lines with V-levels that are not enabled (as per the LogSink) will not
|
||||
// be written. Level V(0) is the default, and logger.V(0).Info() has the same
|
||||
// meaning as logger.Info(). Negative V-levels have the same meaning as V(0).
|
||||
//
|
||||
// Where we might have written:
|
||||
// if flVerbose >= 2 {
|
||||
// log.Printf("an unusual thing happened")
|
||||
// }
|
||||
//
|
||||
// We can write:
|
||||
// logger.V(2).Info("an unusual thing happened")
|
||||
//
|
||||
// Logger Names
|
||||
//
|
||||
// Logger instances can have name strings so that all messages logged through
|
||||
// that instance have additional context. For example, you might want to add
|
||||
// a subsystem name:
|
||||
//
|
||||
// logger.WithName("compactor").Info("started", "time", time.Now())
|
||||
//
|
||||
// The WithName() method returns a new Logger, which can be passed to
|
||||
// constructors or other functions for further use. Repeated use of WithName()
|
||||
// will accumulate name "segments". These name segments will be joined in some
|
||||
// way by the LogSink implementation. It is strongly recommended that name
|
||||
// segments contain simple identifiers (letters, digits, and hyphen), and do
|
||||
// not contain characters that could muddle the log output or confuse the
|
||||
// joining operation (e.g. whitespace, commas, periods, slashes, brackets,
|
||||
// quotes, etc).
|
||||
//
|
||||
// Saved Values
|
||||
//
|
||||
// Logger instances can store any number of key/value pairs, which will be
|
||||
// logged alongside all messages logged through that instance. For example,
|
||||
// you might want to create a Logger instance per managed object:
|
||||
//
|
||||
// With the standard log package, we might write:
|
||||
// log.Printf("decided to set field foo to value %q for object %s/%s",
|
||||
// targetValue, object.Namespace, object.Name)
|
||||
//
|
||||
// With logr's structured logging, we'd write:
|
||||
// // elsewhere in the file, set up the logger to log with the prefix of
|
||||
// // "reconcilers", and the named value target-type=Foo, for extra context.
|
||||
// log := mainLogger.WithName("reconcilers").WithValues("target-type", "Foo")
|
||||
// With logr we'd write:
|
||||
// // Elsewhere: set up the logger to log the object name.
|
||||
// obj.logger = mainLogger.WithValues(
|
||||
// "name", obj.name, "namespace", obj.namespace)
|
||||
//
|
||||
// // later on...
|
||||
// log.Info("setting foo on object", "value", targetValue, "object", object)
|
||||
// obj.logger.Info("setting foo", "value", targetValue)
|
||||
//
|
||||
// Depending on our logging implementation, we could then make logging decisions
|
||||
// based on field values (like only logging such events for objects in a certain
|
||||
// namespace), or copy the structured information into a structured log store.
|
||||
// Best Practices
|
||||
//
|
||||
// For logging errors, Logger has a method called Error. Suppose we wanted to
|
||||
// log an error while reconciling. With the traditional log package, we might
|
||||
// write:
|
||||
// log.Errorf("unable to reconcile object %s/%s: %v", object.Namespace, object.Name, err)
|
||||
//
|
||||
// With logr, we'd instead write:
|
||||
// // assuming the above setup for log
|
||||
// log.Error(err, "unable to reconcile object", "object", object)
|
||||
//
|
||||
// This functions similarly to:
|
||||
// log.Info("unable to reconcile object", "error", err, "object", object)
|
||||
//
|
||||
// However, it ensures that a standard key for the error value ("error") is used
|
||||
// across all error logging. Furthermore, certain implementations may choose to
|
||||
// attach additional information (such as stack traces) on calls to Error, so
|
||||
// it's preferred to use Error to log errors.
|
||||
//
|
||||
// Parts of a log line
|
||||
//
|
||||
// Each log message from a Logger has four types of context:
|
||||
// logger name, log verbosity, log message, and the named values.
|
||||
//
|
||||
// The Logger name consists of a series of name "segments" added by successive
|
||||
// calls to WithName. These name segments will be joined in some way by the
|
||||
// underlying implementation. It is strongly recommended that name segments
|
||||
// contain simple identifiers (letters, digits, and hyphen), and do not contain
|
||||
// characters that could muddle the log output or confuse the joining operation
|
||||
// (e.g. whitespace, commas, periods, slashes, brackets, quotes, etc).
|
||||
//
|
||||
// Log verbosity represents how little a log matters. Level zero, the default,
|
||||
// matters most. Increasing levels matter less and less. Try to avoid lots of
|
||||
// different verbosity levels, and instead provide useful keys, logger names,
|
||||
// and log messages for users to filter on. It's illegal to pass a log level
|
||||
// below zero.
|
||||
// Logger has very few hard rules, with the goal that LogSink implementations
|
||||
// might have a lot of freedom to differentiate. There are, however, some
|
||||
// things to consider.
|
||||
//
|
||||
// The log message consists of a constant message attached to the log line.
|
||||
// This should generally be a simple description of what's occurring, and should
|
||||
// never be a format string.
|
||||
// never be a format string. Variable information can then be attached using
|
||||
// named values.
|
||||
//
|
||||
// Variable information can then be attached using named values (key/value
|
||||
// pairs). Keys are arbitrary strings, while values may be any Go value.
|
||||
// Keys are arbitrary strings, but should generally be constant values. Values
|
||||
// may be any Go value, but how the value is formatted is determined by the
|
||||
// LogSink implementation.
|
||||
//
|
||||
// Key Naming Conventions
|
||||
//
|
||||
@@ -102,6 +120,7 @@ limitations under the License.
|
||||
// * be constant (not dependent on input data)
|
||||
// * contain only printable characters
|
||||
// * not contain whitespace or punctuation
|
||||
// * use lower case for simple keys and lowerCamelCase for more complex ones
|
||||
//
|
||||
// These guidelines help ensure that log data is processed properly regardless
|
||||
// of the log implementation. For example, log implementations will try to
|
||||
@@ -110,21 +129,22 @@ limitations under the License.
|
||||
// While users are generally free to use key names of their choice, it's
|
||||
// generally best to avoid using the following keys, as they're frequently used
|
||||
// by implementations:
|
||||
//
|
||||
// * `"caller"`: the calling information (file/line) of a particular log line.
|
||||
// * `"error"`: the underlying error value in the `Error` method.
|
||||
// * `"level"`: the log level.
|
||||
// * `"logger"`: the name of the associated logger.
|
||||
// * `"msg"`: the log message.
|
||||
// * `"stacktrace"`: the stack trace associated with a particular log line or
|
||||
// error (often from the `Error` message).
|
||||
// * `"ts"`: the timestamp for a log line.
|
||||
// * "caller": the calling information (file/line) of a particular log line
|
||||
// * "error": the underlying error value in the `Error` method
|
||||
// * "level": the log level
|
||||
// * "logger": the name of the associated logger
|
||||
// * "msg": the log message
|
||||
// * "stacktrace": the stack trace associated with a particular log line or
|
||||
// error (often from the `Error` message)
|
||||
// * "ts": the timestamp for a log line
|
||||
//
|
||||
// Implementations are encouraged to make use of these keys to represent the
|
||||
// above concepts, when necessary (for example, in a pure-JSON output form, it
|
||||
// would be necessary to represent at least message and timestamp as ordinary
|
||||
// named values).
|
||||
//
|
||||
// Break Glass
|
||||
//
|
||||
// Implementations may choose to give callers access to the underlying
|
||||
// logging implementation. The recommended pattern for this is:
|
||||
// // Underlier exposes access to the underlying logging implementation.
|
||||
@@ -134,81 +154,220 @@ limitations under the License.
|
||||
// type Underlier interface {
|
||||
// GetUnderlying() <underlying-type>
|
||||
// }
|
||||
//
|
||||
// Logger grants access to the sink to enable type assertions like this:
|
||||
// func DoSomethingWithImpl(log logr.Logger) {
|
||||
// if underlier, ok := log.GetSink()(impl.Underlier) {
|
||||
// implLogger := underlier.GetUnderlying()
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Custom `With*` functions can be implemented by copying the complete
|
||||
// Logger struct and replacing the sink in the copy:
|
||||
// // WithFooBar changes the foobar parameter in the log sink and returns a
|
||||
// // new logger with that modified sink. It does nothing for loggers where
|
||||
// // the sink doesn't support that parameter.
|
||||
// func WithFoobar(log logr.Logger, foobar int) logr.Logger {
|
||||
// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok {
|
||||
// log = log.WithSink(foobarLogSink.WithFooBar(foobar))
|
||||
// }
|
||||
// return log
|
||||
// }
|
||||
//
|
||||
// Don't use New to construct a new Logger with a LogSink retrieved from an
|
||||
// existing Logger. Source code attribution might not work correctly and
|
||||
// unexported fields in Logger get lost.
|
||||
//
|
||||
// Beware that the same LogSink instance may be shared by different logger
|
||||
// instances. Calling functions that modify the LogSink will affect all of
|
||||
// those.
|
||||
package logr
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// TODO: consider adding back in format strings if they're really needed
|
||||
// TODO: consider other bits of zap/zapcore functionality like ObjectMarshaller (for arbitrary objects)
|
||||
// TODO: consider other bits of glog functionality like Flush, OutputStats
|
||||
|
||||
// Logger represents the ability to log messages, both errors and not.
|
||||
type Logger interface {
|
||||
// Enabled tests whether this Logger is enabled. For example, commandline
|
||||
// flags might be used to set the logging verbosity and disable some info
|
||||
// logs.
|
||||
Enabled() bool
|
||||
|
||||
// Info logs a non-error message with the given key/value pairs as context.
|
||||
//
|
||||
// The msg argument should be used to add some constant description to
|
||||
// the log line. The key/value pairs can then be used to add additional
|
||||
// variable information. The key/value pairs should alternate string
|
||||
// keys and arbitrary values.
|
||||
Info(msg string, keysAndValues ...interface{})
|
||||
|
||||
// Error logs an error, with the given message and key/value pairs as context.
|
||||
// It functions similarly to calling Info with the "error" named value, but may
|
||||
// have unique behavior, and should be preferred for logging errors (see the
|
||||
// package documentations for more information).
|
||||
//
|
||||
// The msg field should be used to add context to any underlying error,
|
||||
// while the err field should be used to attach the actual error that
|
||||
// triggered this log line, if present.
|
||||
Error(err error, msg string, keysAndValues ...interface{})
|
||||
|
||||
// V returns an Logger value for a specific verbosity level, relative to
|
||||
// this Logger. In other words, V values are additive. V higher verbosity
|
||||
// level means a log message is less important. It's illegal to pass a log
|
||||
// level less than zero.
|
||||
V(level int) Logger
|
||||
|
||||
// WithValues adds some key-value pairs of context to a logger.
|
||||
// See Info for documentation on how key/value pairs work.
|
||||
WithValues(keysAndValues ...interface{}) Logger
|
||||
|
||||
// WithName adds a new element to the logger's name.
|
||||
// Successive calls with WithName continue to append
|
||||
// suffixes to the logger's name. It's strongly recommended
|
||||
// that name segments contain only letters, digits, and hyphens
|
||||
// (see the package documentation for more information).
|
||||
WithName(name string) Logger
|
||||
// New returns a new Logger instance. This is primarily used by libraries
|
||||
// implementing LogSink, rather than end users.
|
||||
func New(sink LogSink) Logger {
|
||||
logger := Logger{}
|
||||
logger.setSink(sink)
|
||||
sink.Init(runtimeInfo)
|
||||
return logger
|
||||
}
|
||||
|
||||
// InfoLogger provides compatibility with code that relies on the v0.1.0
|
||||
// interface.
|
||||
//
|
||||
// Deprecated: InfoLogger is an artifact of early versions of this API. New
|
||||
// users should never use it and existing users should use Logger instead. This
|
||||
// will be removed in a future release.
|
||||
type InfoLogger = Logger
|
||||
// setSink stores the sink and updates any related fields. It mutates the
|
||||
// logger and thus is only safe to use for loggers that are not currently being
|
||||
// used concurrently.
|
||||
func (l *Logger) setSink(sink LogSink) {
|
||||
l.sink = sink
|
||||
}
|
||||
|
||||
// GetSink returns the stored sink.
|
||||
func (l Logger) GetSink() LogSink {
|
||||
return l.sink
|
||||
}
|
||||
|
||||
// WithSink returns a copy of the logger with the new sink.
|
||||
func (l Logger) WithSink(sink LogSink) Logger {
|
||||
l.setSink(sink)
|
||||
return l
|
||||
}
|
||||
|
||||
// Logger is an interface to an abstract logging implementation. This is a
|
||||
// concrete type for performance reasons, but all the real work is passed on to
|
||||
// a LogSink. Implementations of LogSink should provide their own constructors
|
||||
// that return Logger, not LogSink.
|
||||
//
|
||||
// The underlying sink can be accessed through GetSink and be modified through
|
||||
// WithSink. This enables the implementation of custom extensions (see "Break
|
||||
// Glass" in the package documentation). Normally the sink should be used only
|
||||
// indirectly.
|
||||
type Logger struct {
|
||||
sink LogSink
|
||||
level int
|
||||
}
|
||||
|
||||
// Enabled tests whether this Logger is enabled. For example, commandline
|
||||
// flags might be used to set the logging verbosity and disable some info logs.
|
||||
func (l Logger) Enabled() bool {
|
||||
return l.sink.Enabled(l.level)
|
||||
}
|
||||
|
||||
// Info logs a non-error message with the given key/value pairs as context.
|
||||
//
|
||||
// The msg argument should be used to add some constant description to the log
|
||||
// line. The key/value pairs can then be used to add additional variable
|
||||
// information. The key/value pairs must alternate string keys and arbitrary
|
||||
// values.
|
||||
func (l Logger) Info(msg string, keysAndValues ...interface{}) {
|
||||
if l.Enabled() {
|
||||
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||
withHelper.GetCallStackHelper()()
|
||||
}
|
||||
l.sink.Info(l.level, msg, keysAndValues...)
|
||||
}
|
||||
}
|
||||
|
||||
// Error logs an error, with the given message and key/value pairs as context.
|
||||
// It functions similarly to Info, but may have unique behavior, and should be
|
||||
// preferred for logging errors (see the package documentations for more
|
||||
// information).
|
||||
//
|
||||
// The msg argument should be used to add context to any underlying error,
|
||||
// while the err argument should be used to attach the actual error that
|
||||
// triggered this log line, if present.
|
||||
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||
withHelper.GetCallStackHelper()()
|
||||
}
|
||||
l.sink.Error(err, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// V returns a new Logger instance for a specific verbosity level, relative to
|
||||
// this Logger. In other words, V-levels are additive. A higher verbosity
|
||||
// level means a log message is less important. Negative V-levels are treated
|
||||
// as 0.
|
||||
func (l Logger) V(level int) Logger {
|
||||
if level < 0 {
|
||||
level = 0
|
||||
}
|
||||
l.level += level
|
||||
return l
|
||||
}
|
||||
|
||||
// WithValues returns a new Logger instance with additional key/value pairs.
|
||||
// See Info for documentation on how key/value pairs work.
|
||||
func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
|
||||
l.setSink(l.sink.WithValues(keysAndValues...))
|
||||
return l
|
||||
}
|
||||
|
||||
// WithName returns a new Logger instance with the specified name element added
|
||||
// to the Logger's name. Successive calls with WithName append additional
|
||||
// suffixes to the Logger's name. It's strongly recommended that name segments
|
||||
// contain only letters, digits, and hyphens (see the package documentation for
|
||||
// more information).
|
||||
func (l Logger) WithName(name string) Logger {
|
||||
l.setSink(l.sink.WithName(name))
|
||||
return l
|
||||
}
|
||||
|
||||
// WithCallDepth returns a Logger instance that offsets the call stack by the
|
||||
// specified number of frames when logging call site information, if possible.
|
||||
// This is useful for users who have helper functions between the "real" call
|
||||
// site and the actual calls to Logger methods. If depth is 0 the attribution
|
||||
// should be to the direct caller of this function. If depth is 1 the
|
||||
// attribution should skip 1 call frame, and so on. Successive calls to this
|
||||
// are additive.
|
||||
//
|
||||
// If the underlying log implementation supports a WithCallDepth(int) method,
|
||||
// it will be called and the result returned. If the implementation does not
|
||||
// support CallDepthLogSink, the original Logger will be returned.
|
||||
//
|
||||
// To skip one level, WithCallStackHelper() should be used instead of
|
||||
// WithCallDepth(1) because it works with implementions that support the
|
||||
// CallDepthLogSink and/or CallStackHelperLogSink interfaces.
|
||||
func (l Logger) WithCallDepth(depth int) Logger {
|
||||
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
|
||||
l.setSink(withCallDepth.WithCallDepth(depth))
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// WithCallStackHelper returns a new Logger instance that skips the direct
|
||||
// caller when logging call site information, if possible. This is useful for
|
||||
// users who have helper functions between the "real" call site and the actual
|
||||
// calls to Logger methods and want to support loggers which depend on marking
|
||||
// each individual helper function, like loggers based on testing.T.
|
||||
//
|
||||
// In addition to using that new logger instance, callers also must call the
|
||||
// returned function.
|
||||
//
|
||||
// If the underlying log implementation supports a WithCallDepth(int) method,
|
||||
// WithCallDepth(1) will be called to produce a new logger. If it supports a
|
||||
// WithCallStackHelper() method, that will be also called. If the
|
||||
// implementation does not support either of these, the original Logger will be
|
||||
// returned.
|
||||
func (l Logger) WithCallStackHelper() (func(), Logger) {
|
||||
var helper func()
|
||||
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
|
||||
l.setSink(withCallDepth.WithCallDepth(1))
|
||||
}
|
||||
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||
helper = withHelper.GetCallStackHelper()
|
||||
} else {
|
||||
helper = func() {}
|
||||
}
|
||||
return helper, l
|
||||
}
|
||||
|
||||
// contextKey is how we find Loggers in a context.Context.
|
||||
type contextKey struct{}
|
||||
|
||||
// FromContext returns a Logger constructed from ctx or nil if no
|
||||
// logger details are found.
|
||||
func FromContext(ctx context.Context) Logger {
|
||||
// FromContext returns a Logger from ctx or an error if no Logger is found.
|
||||
func FromContext(ctx context.Context) (Logger, error) {
|
||||
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||
return v
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return nil
|
||||
return Logger{}, notFoundError{}
|
||||
}
|
||||
|
||||
// FromContextOrDiscard returns a Logger constructed from ctx or a Logger
|
||||
// that discards all messages if no logger details are found.
|
||||
// notFoundError exists to carry an IsNotFound method.
|
||||
type notFoundError struct{}
|
||||
|
||||
func (notFoundError) Error() string {
|
||||
return "no logr.Logger was present"
|
||||
}
|
||||
|
||||
func (notFoundError) IsNotFound() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this
|
||||
// returns a Logger that discards all log messages.
|
||||
func FromContextOrDiscard(ctx context.Context) Logger {
|
||||
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||
return v
|
||||
@@ -217,12 +376,59 @@ func FromContextOrDiscard(ctx context.Context) Logger {
|
||||
return Discard()
|
||||
}
|
||||
|
||||
// NewContext returns a new context derived from ctx that embeds the Logger.
|
||||
func NewContext(ctx context.Context, l Logger) context.Context {
|
||||
return context.WithValue(ctx, contextKey{}, l)
|
||||
// NewContext returns a new Context, derived from ctx, which carries the
|
||||
// provided Logger.
|
||||
func NewContext(ctx context.Context, logger Logger) context.Context {
|
||||
return context.WithValue(ctx, contextKey{}, logger)
|
||||
}
|
||||
|
||||
// CallDepthLogger represents a Logger that knows how to climb the call stack
|
||||
// RuntimeInfo holds information that the logr "core" library knows which
|
||||
// LogSinks might want to know.
|
||||
type RuntimeInfo struct {
|
||||
// CallDepth is the number of call frames the logr library adds between the
|
||||
// end-user and the LogSink. LogSink implementations which choose to print
|
||||
// the original logging site (e.g. file & line) should climb this many
|
||||
// additional frames to find it.
|
||||
CallDepth int
|
||||
}
|
||||
|
||||
// runtimeInfo is a static global. It must not be changed at run time.
|
||||
var runtimeInfo = RuntimeInfo{
|
||||
CallDepth: 1,
|
||||
}
|
||||
|
||||
// LogSink represents a logging implementation. End-users will generally not
|
||||
// interact with this type.
|
||||
type LogSink interface {
|
||||
// Init receives optional information about the logr library for LogSink
|
||||
// implementations that need it.
|
||||
Init(info RuntimeInfo)
|
||||
|
||||
// Enabled tests whether this LogSink is enabled at the specified V-level.
|
||||
// For example, commandline flags might be used to set the logging
|
||||
// verbosity and disable some info logs.
|
||||
Enabled(level int) bool
|
||||
|
||||
// Info logs a non-error message with the given key/value pairs as context.
|
||||
// The level argument is provided for optional logging. This method will
|
||||
// only be called when Enabled(level) is true. See Logger.Info for more
|
||||
// details.
|
||||
Info(level int, msg string, keysAndValues ...interface{})
|
||||
|
||||
// Error logs an error, with the given message and key/value pairs as
|
||||
// context. See Logger.Error for more details.
|
||||
Error(err error, msg string, keysAndValues ...interface{})
|
||||
|
||||
// WithValues returns a new LogSink with additional key/value pairs. See
|
||||
// Logger.WithValues for more details.
|
||||
WithValues(keysAndValues ...interface{}) LogSink
|
||||
|
||||
// WithName returns a new LogSink with the specified name appended. See
|
||||
// Logger.WithName for more details.
|
||||
WithName(name string) LogSink
|
||||
}
|
||||
|
||||
// CallDepthLogSink represents a Logger that knows how to climb the call stack
|
||||
// to identify the original call site and can offset the depth by a specified
|
||||
// number of frames. This is useful for users who have helper functions
|
||||
// between the "real" call site and the actual calls to Logger methods.
|
||||
@@ -232,35 +438,59 @@ func NewContext(ctx context.Context, l Logger) context.Context {
|
||||
//
|
||||
// This is an optional interface and implementations are not required to
|
||||
// support it.
|
||||
type CallDepthLogger interface {
|
||||
Logger
|
||||
|
||||
// WithCallDepth returns a Logger that will offset the call stack by the
|
||||
// specified number of frames when logging call site information. If depth
|
||||
// is 0 the attribution should be to the direct caller of this method. If
|
||||
// depth is 1 the attribution should skip 1 call frame, and so on.
|
||||
type CallDepthLogSink interface {
|
||||
// WithCallDepth returns a LogSink that will offset the call
|
||||
// stack by the specified number of frames when logging call
|
||||
// site information.
|
||||
//
|
||||
// If depth is 0, the LogSink should skip exactly the number
|
||||
// of call frames defined in RuntimeInfo.CallDepth when Info
|
||||
// or Error are called, i.e. the attribution should be to the
|
||||
// direct caller of Logger.Info or Logger.Error.
|
||||
//
|
||||
// If depth is 1 the attribution should skip 1 call frame, and so on.
|
||||
// Successive calls to this are additive.
|
||||
WithCallDepth(depth int) Logger
|
||||
WithCallDepth(depth int) LogSink
|
||||
}
|
||||
|
||||
// WithCallDepth returns a Logger that will offset the call stack by the
|
||||
// specified number of frames when logging call site information, if possible.
|
||||
// This is useful for users who have helper functions between the "real" call
|
||||
// site and the actual calls to Logger methods. If depth is 0 the attribution
|
||||
// should be to the direct caller of this function. If depth is 1 the
|
||||
// attribution should skip 1 call frame, and so on. Successive calls to this
|
||||
// are additive.
|
||||
// CallStackHelperLogSink represents a Logger that knows how to climb
|
||||
// the call stack to identify the original call site and can skip
|
||||
// intermediate helper functions if they mark themselves as
|
||||
// helper. Go's testing package uses that approach.
|
||||
//
|
||||
// If the underlying log implementation supports the CallDepthLogger interface,
|
||||
// the WithCallDepth method will be called and the result returned. If the
|
||||
// implementation does not support CallDepthLogger, the original Logger will be
|
||||
// returned.
|
||||
// This is useful for users who have helper functions between the
|
||||
// "real" call site and the actual calls to Logger methods.
|
||||
// Implementations that log information about the call site (such as
|
||||
// file, function, or line) would otherwise log information about the
|
||||
// intermediate helper functions.
|
||||
//
|
||||
// Callers which care about whether this was supported or not should test for
|
||||
// CallDepthLogger support themselves.
|
||||
func WithCallDepth(logger Logger, depth int) Logger {
|
||||
if decorator, ok := logger.(CallDepthLogger); ok {
|
||||
return decorator.WithCallDepth(depth)
|
||||
}
|
||||
return logger
|
||||
// This is an optional interface and implementations are not required
|
||||
// to support it. Implementations that choose to support this must not
|
||||
// simply implement it as WithCallDepth(1), because
|
||||
// Logger.WithCallStackHelper will call both methods if they are
|
||||
// present. This should only be implemented for LogSinks that actually
|
||||
// need it, as with testing.T.
|
||||
type CallStackHelperLogSink interface {
|
||||
// GetCallStackHelper returns a function that must be called
|
||||
// to mark the direct caller as helper function when logging
|
||||
// call site information.
|
||||
GetCallStackHelper() func()
|
||||
}
|
||||
|
||||
// Marshaler is an optional interface that logged values may choose to
|
||||
// implement. Loggers with structured output, such as JSON, should
|
||||
// log the object return by the MarshalLog method instead of the
|
||||
// original value.
|
||||
type Marshaler interface {
|
||||
// MarshalLog can be used to:
|
||||
// - ensure that structs are not logged as strings when the original
|
||||
// value has a String method: return a different type without a
|
||||
// String method
|
||||
// - select which fields of a complex type should get logged:
|
||||
// return a simpler struct with fewer fields
|
||||
// - log unexported fields: return a different struct
|
||||
// with exported fields
|
||||
//
|
||||
// It may return any value of any type.
|
||||
MarshalLog() interface{}
|
||||
}
|
||||
|
1
vendor/github.com/gobuffalo/flect/plural_rules.go
generated
vendored
1
vendor/github.com/gobuffalo/flect/plural_rules.go
generated
vendored
@@ -199,6 +199,7 @@ var singularToPluralSuffixList = []singularToPluralSuffix{
|
||||
{"shoe", "shoes"},
|
||||
{"stis", "stes"},
|
||||
{"tive", "tives"},
|
||||
{"vice", "vices"},
|
||||
{"wife", "wives"},
|
||||
{"afe", "aves"},
|
||||
{"bfe", "bves"},
|
||||
|
3
vendor/github.com/googleapis/gnostic/compiler/README.md
generated
vendored
3
vendor/github.com/googleapis/gnostic/compiler/README.md
generated
vendored
@@ -1,3 +1,4 @@
|
||||
# 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.
|
||||
|
20
vendor/github.com/googleapis/gnostic/compiler/context.go
generated
vendored
20
vendor/github.com/googleapis/gnostic/compiler/context.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -14,30 +14,36 @@
|
||||
|
||||
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, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
|
||||
return &Context{Name: name, Parent: parent, ExtensionHandlers: extensionHandlers}
|
||||
func NewContextWithExtensions(name string, node *yaml.Node, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {
|
||||
return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: extensionHandlers}
|
||||
}
|
||||
|
||||
// NewContext returns a new object representing the compiler state
|
||||
func NewContext(name string, parent *Context) *Context {
|
||||
func NewContext(name string, node *yaml.Node, parent *Context) *Context {
|
||||
if parent != nil {
|
||||
return &Context{Name: name, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}
|
||||
return &Context{Name: name, Node: node, 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 {
|
||||
return context.Parent.Description() + "." + context.Name
|
||||
name = context.Parent.Description() + "." + name
|
||||
}
|
||||
return context.Name
|
||||
return name
|
||||
}
|
||||
|
15
vendor/github.com/googleapis/gnostic/compiler/error.go
generated
vendored
15
vendor/github.com/googleapis/gnostic/compiler/error.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package compiler
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Error represents compiler errors and their location in the document.
|
||||
type Error struct {
|
||||
Context *Context
|
||||
@@ -25,12 +27,19 @@ 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 "ERROR " + err.Message
|
||||
return err.Message
|
||||
}
|
||||
return "ERROR " + err.Context.Description() + " " + err.Message
|
||||
return err.locationDescription() + " " + err.Message
|
||||
}
|
||||
|
||||
// ErrorGroup is a container for groups of Error values.
|
||||
|
101
vendor/github.com/googleapis/gnostic/compiler/extension-handler.go
generated
vendored
101
vendor/github.com/googleapis/gnostic/compiler/extension-handler.go
generated
vendored
@@ -1,101 +0,0 @@
|
||||
// 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
|
||||
}
|
85
vendor/github.com/googleapis/gnostic/compiler/extensions.go
generated
vendored
Normal file
85
vendor/github.com/googleapis/gnostic/compiler/extensions.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// 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
|
||||
}
|
347
vendor/github.com/googleapis/gnostic/compiler/helpers.go
generated
vendored
347
vendor/github.com/googleapis/gnostic/compiler/helpers.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -16,56 +16,63 @@ 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.MapSlice if possible.
|
||||
func UnpackMap(in interface{}) (yaml.MapSlice, bool) {
|
||||
m, ok := in.(yaml.MapSlice)
|
||||
if ok {
|
||||
return m, true
|
||||
// UnpackMap gets a *yaml.Node if possible.
|
||||
func UnpackMap(in *yaml.Node) (*yaml.Node, bool) {
|
||||
if in == nil {
|
||||
return nil, false
|
||||
}
|
||||
// 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
|
||||
return in, true
|
||||
}
|
||||
|
||||
// SortedKeysForMap returns the sorted keys of a yaml.MapSlice.
|
||||
func SortedKeysForMap(m yaml.MapSlice) []string {
|
||||
// SortedKeysForMap returns the sorted keys of a yamlv2.MapSlice.
|
||||
func SortedKeysForMap(m *yaml.Node) []string {
|
||||
keys := make([]string, 0)
|
||||
for _, item := range m {
|
||||
keys = append(keys, item.Key.(string))
|
||||
if m.Kind == yaml.MappingNode {
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
keys = append(keys, m.Content[i].Value)
|
||||
}
|
||||
}
|
||||
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
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
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]
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -83,8 +90,118 @@ 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.MapSlice, requiredKeys []string) []string {
|
||||
func MissingKeysInMap(m *yaml.Node, requiredKeys []string) []string {
|
||||
missingKeys := make([]string, 0)
|
||||
for _, k := range requiredKeys {
|
||||
if !MapHasKey(m, k) {
|
||||
@@ -95,64 +212,109 @@ func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
func InvalidKeysInMap(m *yaml.Node, 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 {
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
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
|
||||
// NewNullNode creates a new Null node.
|
||||
func NewNullNode() *yaml.Node {
|
||||
node := &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!null",
|
||||
}
|
||||
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
|
||||
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),
|
||||
}
|
||||
description += fmt.Sprintf("%s%+v\n", indent, in)
|
||||
return description
|
||||
}
|
||||
|
||||
// PluralProperties returns the string "properties" pluralized.
|
||||
@@ -195,3 +357,40 @@ 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)
|
||||
}
|
||||
}
|
||||
|
2
vendor/github.com/googleapis/gnostic/compiler/main.go
generated
vendored
2
vendor/github.com/googleapis/gnostic/compiler/main.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
|
118
vendor/github.com/googleapis/gnostic/compiler/reader.go
generated
vendored
118
vendor/github.com/googleapis/gnostic/compiler/reader.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@@ -23,18 +22,30 @@ import (
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var fileCache map[string][]byte
|
||||
var infoCache map[string]interface{}
|
||||
var count int64
|
||||
|
||||
var verboseReader = false
|
||||
|
||||
var fileCache map[string][]byte
|
||||
var infoCache map[string]*yaml.Node
|
||||
|
||||
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
|
||||
|
||||
func initializeFileCache() {
|
||||
if fileCache == nil {
|
||||
fileCache = make(map[string][]byte, 0)
|
||||
@@ -43,27 +54,42 @@ func initializeFileCache() {
|
||||
|
||||
func initializeInfoCache() {
|
||||
if infoCache == nil {
|
||||
infoCache = make(map[string]interface{}, 0)
|
||||
infoCache = make(map[string]*yaml.Node, 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
|
||||
}
|
||||
@@ -71,7 +97,10 @@ func RemoveFromFileCache(fileurl string) {
|
||||
delete(fileCache, fileurl)
|
||||
}
|
||||
|
||||
// RemoveFromInfoCache removes an entry from the info cache.
|
||||
func RemoveFromInfoCache(filename string) {
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
if !infoCacheEnable {
|
||||
return
|
||||
}
|
||||
@@ -79,21 +108,31 @@ func RemoveFromInfoCache(filename string) {
|
||||
delete(infoCache, filename)
|
||||
}
|
||||
|
||||
func GetInfoCache() map[string]interface{} {
|
||||
// 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() {
|
||||
infoCache = make(map[string]interface{})
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
infoCache = make(map[string]*yaml.Node)
|
||||
}
|
||||
|
||||
// ClearCaches clears all caches.
|
||||
func ClearCaches() {
|
||||
ClearFileCache()
|
||||
ClearInfoCache()
|
||||
@@ -101,6 +140,12 @@ func ClearCaches() {
|
||||
|
||||
// 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 {
|
||||
@@ -121,7 +166,7 @@ func FetchFile(fileurl string) ([]byte, error) {
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != 200 {
|
||||
return nil, errors.New(fmt.Sprintf("Error downloading %s: %s", fileurl, response.Status))
|
||||
return nil, fmt.Errorf("Error downloading %s: %s", fileurl, response.Status)
|
||||
}
|
||||
bytes, err = ioutil.ReadAll(response.Body)
|
||||
if fileCacheEnable && err == nil {
|
||||
@@ -132,11 +177,17 @@ 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
|
||||
}
|
||||
@@ -150,8 +201,14 @@ func ReadBytesForFile(filename string) ([]byte, error) {
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
// ReadInfoFromBytes unmarshals a file as a yaml.MapSlice.
|
||||
func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
|
||||
// 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) {
|
||||
initializeInfoCache()
|
||||
if infoCacheEnable {
|
||||
cachedInfo, ok := infoCache[filename]
|
||||
@@ -165,19 +222,23 @@ func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) {
|
||||
log.Printf("Reading info for file %s", filename)
|
||||
}
|
||||
}
|
||||
var info yaml.MapSlice
|
||||
var info yaml.Node
|
||||
err := yaml.Unmarshal(bytes, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if infoCacheEnable && len(filename) > 0 {
|
||||
infoCache[filename] = info
|
||||
infoCache[filename] = &info
|
||||
}
|
||||
return info, nil
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref.
|
||||
func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
|
||||
func ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) {
|
||||
fileCacheMutex.Lock()
|
||||
defer fileCacheMutex.Unlock()
|
||||
infoCacheMutex.Lock()
|
||||
defer infoCacheMutex.Unlock()
|
||||
initializeInfoCache()
|
||||
if infoCacheEnable {
|
||||
info, ok := infoCache[ref]
|
||||
@@ -191,7 +252,6 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
|
||||
log.Printf("Reading info for ref %s#%s", basefile, ref)
|
||||
}
|
||||
}
|
||||
count = count + 1
|
||||
basedir, _ := filepath.Split(basefile)
|
||||
parts := strings.Split(ref, "#")
|
||||
var filename string
|
||||
@@ -204,24 +264,30 @@ func ReadInfoForRef(basefile string, ref string) (interface{}, error) {
|
||||
} else {
|
||||
filename = basefile
|
||||
}
|
||||
bytes, err := ReadBytesForFile(filename)
|
||||
bytes, err := readBytesForFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, err := ReadInfoFromBytes(filename, bytes)
|
||||
info, err := readInfoFromBytes(filename, bytes)
|
||||
if info != nil && info.Kind == yaml.DocumentNode {
|
||||
info = info.Content[0]
|
||||
}
|
||||
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, ok := info.(yaml.MapSlice)
|
||||
if ok {
|
||||
m := info
|
||||
if true {
|
||||
found := false
|
||||
for _, section := range m {
|
||||
if section.Key == key {
|
||||
info = section.Value
|
||||
for i := 0; i < len(m.Content); i += 2 {
|
||||
if m.Content[i].Value == key {
|
||||
info = m.Content[i+1]
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
12
vendor/github.com/googleapis/gnostic/extensions/README.md
generated
vendored
12
vendor/github.com/googleapis/gnostic/extensions/README.md
generated
vendored
@@ -1,5 +1,13 @@
|
||||
# Extensions
|
||||
|
||||
This directory contains support code for building Gnostic extensions and associated examples.
|
||||
**Extension Support is experimental.**
|
||||
|
||||
Extensions are used to compile vendor or specification extensions into protocol buffer structures.
|
||||
This directory contains support code for building Gnostic extensio handlers and
|
||||
associated examples.
|
||||
|
||||
Extension handlers can be used to compile vendor or specification extensions
|
||||
into protocol buffer structures.
|
||||
|
||||
Like plugins, extension handlers are built as separate executables. Extension
|
||||
bodies are written to extension handlers as serialized
|
||||
ExtensionHandlerRequests.
|
||||
|
549
vendor/github.com/googleapis/gnostic/extensions/extension.pb.go
generated
vendored
549
vendor/github.com/googleapis/gnostic/extensions/extension.pb.go
generated
vendored
@@ -1,148 +1,181 @@
|
||||
// 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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.15.5
|
||||
// source: extensions/extension.proto
|
||||
|
||||
package openapiextension_v1
|
||||
package gnostic_extension_v1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
any "github.com/golang/protobuf/ptypes/any"
|
||||
math "math"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// The version number of OpenAPI compiler.
|
||||
// The version number of Gnostic.
|
||||
type Version struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
|
||||
Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
|
||||
Patch int32 `protobuf:"varint,3,opt,name=patch,proto3" json:"patch,omitempty"`
|
||||
// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
|
||||
// be empty for mainline stable releases.
|
||||
Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Version) Reset() { *m = Version{} }
|
||||
func (m *Version) String() string { return proto.CompactTextString(m) }
|
||||
func (*Version) ProtoMessage() {}
|
||||
func (x *Version) Reset() {
|
||||
*x = Version{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Version) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Version) ProtoMessage() {}
|
||||
|
||||
func (x *Version) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Version.ProtoReflect.Descriptor instead.
|
||||
func (*Version) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{0}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (m *Version) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Version.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Version.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Version) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Version.Merge(m, src)
|
||||
}
|
||||
func (m *Version) XXX_Size() int {
|
||||
return xxx_messageInfo_Version.Size(m)
|
||||
}
|
||||
func (m *Version) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Version.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Version proto.InternalMessageInfo
|
||||
|
||||
func (m *Version) GetMajor() int32 {
|
||||
if m != nil {
|
||||
return m.Major
|
||||
func (x *Version) GetMajor() int32 {
|
||||
if x != nil {
|
||||
return x.Major
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Version) GetMinor() int32 {
|
||||
if m != nil {
|
||||
return m.Minor
|
||||
func (x *Version) GetMinor() int32 {
|
||||
if x != nil {
|
||||
return x.Minor
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Version) GetPatch() int32 {
|
||||
if m != nil {
|
||||
return m.Patch
|
||||
func (x *Version) GetPatch() int32 {
|
||||
if x != nil {
|
||||
return x.Patch
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Version) GetSuffix() string {
|
||||
if m != nil {
|
||||
return m.Suffix
|
||||
func (x *Version) GetSuffix() string {
|
||||
if x != nil {
|
||||
return x.Suffix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// An encoded Request is written to the ExtensionHandler's stdin.
|
||||
type ExtensionHandlerRequest struct {
|
||||
// The OpenAPI descriptions that were explicitly listed on the command line.
|
||||
// The specifications will appear in the order they are specified to gnostic.
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The extension to process.
|
||||
Wrapper *Wrapper `protobuf:"bytes,1,opt,name=wrapper,proto3" json:"wrapper,omitempty"`
|
||||
// The version number of openapi compiler.
|
||||
CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion,proto3" json:"compiler_version,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
// The version number of Gnostic.
|
||||
CompilerVersion *Version `protobuf:"bytes,2,opt,name=compiler_version,json=compilerVersion,proto3" json:"compiler_version,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerRequest) Reset() { *m = ExtensionHandlerRequest{} }
|
||||
func (m *ExtensionHandlerRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExtensionHandlerRequest) ProtoMessage() {}
|
||||
func (x *ExtensionHandlerRequest) Reset() {
|
||||
*x = ExtensionHandlerRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExtensionHandlerRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExtensionHandlerRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExtensionHandlerRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExtensionHandlerRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ExtensionHandlerRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{1}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExtensionHandlerRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExtensionHandlerRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExtensionHandlerRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ExtensionHandlerRequest.Size(m)
|
||||
}
|
||||
func (m *ExtensionHandlerRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExtensionHandlerRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExtensionHandlerRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ExtensionHandlerRequest) GetWrapper() *Wrapper {
|
||||
if m != nil {
|
||||
return m.Wrapper
|
||||
func (x *ExtensionHandlerRequest) GetWrapper() *Wrapper {
|
||||
if x != nil {
|
||||
return x.Wrapper
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerRequest) GetCompilerVersion() *Version {
|
||||
if m != nil {
|
||||
return m.CompilerVersion
|
||||
func (x *ExtensionHandlerRequest) GetCompilerVersion() *Version {
|
||||
if x != nil {
|
||||
return x.CompilerVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The extensions writes an encoded ExtensionHandlerResponse to stdout.
|
||||
type ExtensionHandlerResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// true if the extension is handled by the extension handler; false otherwise
|
||||
Handled bool `protobuf:"varint,1,opt,name=handled,proto3" json:"handled,omitempty"`
|
||||
// Error message. If non-empty, the extension handling failed.
|
||||
// Error message(s). If non-empty, the extension handling failed.
|
||||
// The extension handler process should exit with status code zero
|
||||
// even if it reports an error in this way.
|
||||
//
|
||||
@@ -151,150 +184,278 @@ type ExtensionHandlerResponse struct {
|
||||
// itself -- such as the input Document being unparseable -- should be
|
||||
// reported by writing a message to stderr and exiting with a non-zero
|
||||
// status code.
|
||||
Error []string `protobuf:"bytes,2,rep,name=error,proto3" json:"error,omitempty"`
|
||||
Errors []string `protobuf:"bytes,2,rep,name=errors,proto3" json:"errors,omitempty"`
|
||||
// text output
|
||||
Value *any.Any `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Value *anypb.Any `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) Reset() { *m = ExtensionHandlerResponse{} }
|
||||
func (m *ExtensionHandlerResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExtensionHandlerResponse) ProtoMessage() {}
|
||||
func (x *ExtensionHandlerResponse) Reset() {
|
||||
*x = ExtensionHandlerResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExtensionHandlerResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExtensionHandlerResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ExtensionHandlerResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExtensionHandlerResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ExtensionHandlerResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{2}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExtensionHandlerResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExtensionHandlerResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExtensionHandlerResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ExtensionHandlerResponse.Size(m)
|
||||
}
|
||||
func (m *ExtensionHandlerResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExtensionHandlerResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExtensionHandlerResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ExtensionHandlerResponse) GetHandled() bool {
|
||||
if m != nil {
|
||||
return m.Handled
|
||||
func (x *ExtensionHandlerResponse) GetHandled() bool {
|
||||
if x != nil {
|
||||
return x.Handled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) GetError() []string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
func (x *ExtensionHandlerResponse) GetErrors() []string {
|
||||
if x != nil {
|
||||
return x.Errors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExtensionHandlerResponse) GetValue() *any.Any {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
func (x *ExtensionHandlerResponse) GetValue() *anypb.Any {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Wrapper struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// version of the OpenAPI specification in which this extension was written.
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// Name of the extension
|
||||
// Name of the extension.
|
||||
ExtensionName string `protobuf:"bytes,2,opt,name=extension_name,json=extensionName,proto3" json:"extension_name,omitempty"`
|
||||
// Must be a valid yaml for the proto
|
||||
Yaml string `protobuf:"bytes,3,opt,name=yaml,proto3" json:"yaml,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
// YAML-formatted extension value.
|
||||
Yaml string `protobuf:"bytes,3,opt,name=yaml,proto3" json:"yaml,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Wrapper) Reset() { *m = Wrapper{} }
|
||||
func (m *Wrapper) String() string { return proto.CompactTextString(m) }
|
||||
func (*Wrapper) ProtoMessage() {}
|
||||
func (x *Wrapper) Reset() {
|
||||
*x = Wrapper{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_extensions_extension_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Wrapper) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Wrapper) ProtoMessage() {}
|
||||
|
||||
func (x *Wrapper) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_extensions_extension_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Wrapper.ProtoReflect.Descriptor instead.
|
||||
func (*Wrapper) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_661e47e790f76671, []int{3}
|
||||
return file_extensions_extension_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (m *Wrapper) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Wrapper.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Wrapper) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Wrapper.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Wrapper) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Wrapper.Merge(m, src)
|
||||
}
|
||||
func (m *Wrapper) XXX_Size() int {
|
||||
return xxx_messageInfo_Wrapper.Size(m)
|
||||
}
|
||||
func (m *Wrapper) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Wrapper.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Wrapper proto.InternalMessageInfo
|
||||
|
||||
func (m *Wrapper) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
func (x *Wrapper) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Wrapper) GetExtensionName() string {
|
||||
if m != nil {
|
||||
return m.ExtensionName
|
||||
func (x *Wrapper) GetExtensionName() string {
|
||||
if x != nil {
|
||||
return x.ExtensionName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Wrapper) GetYaml() string {
|
||||
if m != nil {
|
||||
return m.Yaml
|
||||
func (x *Wrapper) GetYaml() string {
|
||||
if x != nil {
|
||||
return x.Yaml
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Version)(nil), "openapiextension.v1.Version")
|
||||
proto.RegisterType((*ExtensionHandlerRequest)(nil), "openapiextension.v1.ExtensionHandlerRequest")
|
||||
proto.RegisterType((*ExtensionHandlerResponse)(nil), "openapiextension.v1.ExtensionHandlerResponse")
|
||||
proto.RegisterType((*Wrapper)(nil), "openapiextension.v1.Wrapper")
|
||||
var File_extensions_extension_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_extensions_extension_proto_rawDesc = []byte{
|
||||
0x0a, 0x1a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x78, 0x74,
|
||||
0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6e,
|
||||
0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e,
|
||||
0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x63, 0x0a,
|
||||
0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f,
|
||||
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d,
|
||||
0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75,
|
||||
0x66, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66,
|
||||
0x69, 0x78, 0x22, 0x9c, 0x01, 0x0a, 0x17, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37,
|
||||
0x0a, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1d, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x07,
|
||||
0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x69,
|
||||
0x6c, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65,
|
||||
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x22, 0x78, 0x0a, 0x18, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61,
|
||||
0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
|
||||
0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12,
|
||||
0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5e, 0x0a, 0x07, 0x57,
|
||||
0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x42, 0x4d, 0x0a, 0x0e, 0x6f,
|
||||
0x72, 0x67, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x47,
|
||||
0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50,
|
||||
0x01, 0x5a, 0x21, 0x2e, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3b,
|
||||
0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x5f, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x47, 0x4e, 0x58, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("extensions/extension.proto", fileDescriptor_661e47e790f76671) }
|
||||
var (
|
||||
file_extensions_extension_proto_rawDescOnce sync.Once
|
||||
file_extensions_extension_proto_rawDescData = file_extensions_extension_proto_rawDesc
|
||||
)
|
||||
|
||||
var fileDescriptor_661e47e790f76671 = []byte{
|
||||
// 362 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xeb, 0x40,
|
||||
0x18, 0x85, 0x49, 0xbf, 0x72, 0x33, 0x97, 0xdb, 0x2b, 0x63, 0xd1, 0x58, 0x5c, 0x94, 0x80, 0x50,
|
||||
0x44, 0xa6, 0x54, 0xc1, 0x7d, 0x0b, 0x45, 0xdd, 0xd8, 0x32, 0x8b, 0xba, 0xb3, 0x4c, 0xd3, 0xb7,
|
||||
0x69, 0x24, 0x99, 0x19, 0x27, 0x1f, 0xb6, 0x7f, 0xc5, 0xa5, 0xbf, 0x54, 0x32, 0x93, 0xc4, 0x85,
|
||||
0xba, 0x9b, 0xf3, 0x70, 0xda, 0xf7, 0x9c, 0x13, 0xd4, 0x87, 0x7d, 0x0a, 0x3c, 0x09, 0x05, 0x4f,
|
||||
0x46, 0xf5, 0x93, 0x48, 0x25, 0x52, 0x81, 0x8f, 0x85, 0x04, 0xce, 0x64, 0xf8, 0xc5, 0xf3, 0x71,
|
||||
0xff, 0x2c, 0x10, 0x22, 0x88, 0x60, 0xa4, 0x2d, 0xeb, 0x6c, 0x3b, 0x62, 0xfc, 0x60, 0xfc, 0x9e,
|
||||
0x8f, 0xec, 0x25, 0xa8, 0xc2, 0x88, 0x7b, 0xa8, 0x1d, 0xb3, 0x17, 0xa1, 0x5c, 0x6b, 0x60, 0x0d,
|
||||
0xdb, 0xd4, 0x08, 0x4d, 0x43, 0x2e, 0x94, 0xdb, 0x28, 0x69, 0x21, 0x0a, 0x2a, 0x59, 0xea, 0xef,
|
||||
0xdc, 0xa6, 0xa1, 0x5a, 0xe0, 0x13, 0xd4, 0x49, 0xb2, 0xed, 0x36, 0xdc, 0xbb, 0xad, 0x81, 0x35,
|
||||
0x74, 0x68, 0xa9, 0xbc, 0x77, 0x0b, 0x9d, 0xce, 0xaa, 0x40, 0xf7, 0x8c, 0x6f, 0x22, 0x50, 0x14,
|
||||
0x5e, 0x33, 0x48, 0x52, 0x7c, 0x8b, 0xec, 0x37, 0xc5, 0xa4, 0x04, 0x73, 0xf7, 0xef, 0xf5, 0x39,
|
||||
0xf9, 0xa1, 0x02, 0x79, 0x32, 0x1e, 0x5a, 0x99, 0xf1, 0x1d, 0x3a, 0xf2, 0x45, 0x2c, 0xc3, 0x08,
|
||||
0xd4, 0x2a, 0x37, 0x0d, 0x74, 0x98, 0xdf, 0xfe, 0xa0, 0x6c, 0x49, 0xff, 0x57, 0xbf, 0x2a, 0x81,
|
||||
0x97, 0x23, 0xf7, 0x7b, 0xb6, 0x44, 0x0a, 0x9e, 0x00, 0x76, 0x91, 0xbd, 0xd3, 0x68, 0xa3, 0xc3,
|
||||
0xfd, 0xa1, 0x95, 0x2c, 0x06, 0x00, 0xa5, 0xf4, 0x2c, 0xcd, 0xa1, 0x43, 0x8d, 0xc0, 0x97, 0xa8,
|
||||
0x9d, 0xb3, 0x28, 0x83, 0x32, 0x49, 0x8f, 0x98, 0xe1, 0x49, 0x35, 0x3c, 0x99, 0xf0, 0x03, 0x35,
|
||||
0x16, 0xef, 0x19, 0xd9, 0x65, 0xa9, 0xe2, 0x4c, 0x55, 0xc1, 0xd2, 0xc3, 0x55, 0x12, 0x5f, 0xa0,
|
||||
0x6e, 0xdd, 0x62, 0xc5, 0x59, 0x0c, 0xfa, 0x33, 0x38, 0xf4, 0x5f, 0x4d, 0x1f, 0x59, 0x0c, 0x18,
|
||||
0xa3, 0xd6, 0x81, 0xc5, 0x91, 0x3e, 0xeb, 0x50, 0xfd, 0x9e, 0x5e, 0xa1, 0xae, 0x50, 0x01, 0x09,
|
||||
0xb8, 0x48, 0xd2, 0xd0, 0x27, 0xf9, 0x78, 0x8a, 0xe7, 0x12, 0xf8, 0x64, 0xf1, 0x50, 0xd7, 0x5d,
|
||||
0x8e, 0x17, 0xd6, 0x47, 0xa3, 0x39, 0x9f, 0xcc, 0xd6, 0x1d, 0x1d, 0xf1, 0xe6, 0x33, 0x00, 0x00,
|
||||
0xff, 0xff, 0xeb, 0xf3, 0xfa, 0x65, 0x5c, 0x02, 0x00, 0x00,
|
||||
func file_extensions_extension_proto_rawDescGZIP() []byte {
|
||||
file_extensions_extension_proto_rawDescOnce.Do(func() {
|
||||
file_extensions_extension_proto_rawDescData = protoimpl.X.CompressGZIP(file_extensions_extension_proto_rawDescData)
|
||||
})
|
||||
return file_extensions_extension_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_extensions_extension_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_extensions_extension_proto_goTypes = []interface{}{
|
||||
(*Version)(nil), // 0: gnostic.extension.v1.Version
|
||||
(*ExtensionHandlerRequest)(nil), // 1: gnostic.extension.v1.ExtensionHandlerRequest
|
||||
(*ExtensionHandlerResponse)(nil), // 2: gnostic.extension.v1.ExtensionHandlerResponse
|
||||
(*Wrapper)(nil), // 3: gnostic.extension.v1.Wrapper
|
||||
(*anypb.Any)(nil), // 4: google.protobuf.Any
|
||||
}
|
||||
var file_extensions_extension_proto_depIdxs = []int32{
|
||||
3, // 0: gnostic.extension.v1.ExtensionHandlerRequest.wrapper:type_name -> gnostic.extension.v1.Wrapper
|
||||
0, // 1: gnostic.extension.v1.ExtensionHandlerRequest.compiler_version:type_name -> gnostic.extension.v1.Version
|
||||
4, // 2: gnostic.extension.v1.ExtensionHandlerResponse.value:type_name -> google.protobuf.Any
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_extensions_extension_proto_init() }
|
||||
func file_extensions_extension_proto_init() {
|
||||
if File_extensions_extension_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_extensions_extension_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Version); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_extension_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExtensionHandlerRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_extension_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExtensionHandlerResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_extensions_extension_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Wrapper); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_extensions_extension_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_extensions_extension_proto_goTypes,
|
||||
DependencyIndexes: file_extensions_extension_proto_depIdxs,
|
||||
MessageInfos: file_extensions_extension_proto_msgTypes,
|
||||
}.Build()
|
||||
File_extensions_extension_proto = out.File
|
||||
file_extensions_extension_proto_rawDesc = nil
|
||||
file_extensions_extension_proto_goTypes = nil
|
||||
file_extensions_extension_proto_depIdxs = nil
|
||||
}
|
||||
|
30
vendor/github.com/googleapis/gnostic/extensions/extension.proto
generated
vendored
30
vendor/github.com/googleapis/gnostic/extensions/extension.proto
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -14,8 +14,9 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package gnostic.extension.v1;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
package openapiextension.v1;
|
||||
|
||||
// This option lets the proto compiler generate Java code inside the package
|
||||
// name (see below) instead of inside an outer class. It creates a simpler
|
||||
@@ -26,7 +27,7 @@ option java_multiple_files = true;
|
||||
// The Java outer classname should be the filename in UpperCamelCase. This
|
||||
// class is only used to hold proto descriptor, so developers don't need to
|
||||
// work with it directly.
|
||||
option java_outer_classname = "OpenAPIExtensionV1";
|
||||
option java_outer_classname = "GnosticExtension";
|
||||
|
||||
// The Java package name must be proto package name with proper prefix.
|
||||
option java_package = "org.gnostic.v1";
|
||||
@@ -37,9 +38,13 @@ option java_package = "org.gnostic.v1";
|
||||
// hopefully unique enough to not conflict with things that may come along in
|
||||
// the future. 'GPB' is reserved for the protocol buffer implementation itself.
|
||||
//
|
||||
option objc_class_prefix = "OAE"; // "OpenAPI Extension"
|
||||
// "Gnostic Extension"
|
||||
option objc_class_prefix = "GNX";
|
||||
|
||||
// The version number of OpenAPI compiler.
|
||||
// The Go package name.
|
||||
option go_package = "./extensions;gnostic_extension_v1";
|
||||
|
||||
// The version number of Gnostic.
|
||||
message Version {
|
||||
int32 major = 1;
|
||||
int32 minor = 2;
|
||||
@@ -52,12 +57,11 @@ message Version {
|
||||
// An encoded Request is written to the ExtensionHandler's stdin.
|
||||
message ExtensionHandlerRequest {
|
||||
|
||||
// The OpenAPI descriptions that were explicitly listed on the command line.
|
||||
// The specifications will appear in the order they are specified to gnostic.
|
||||
// The extension to process.
|
||||
Wrapper wrapper = 1;
|
||||
|
||||
// The version number of openapi compiler.
|
||||
Version compiler_version = 3;
|
||||
// The version number of Gnostic.
|
||||
Version compiler_version = 2;
|
||||
}
|
||||
|
||||
// The extensions writes an encoded ExtensionHandlerResponse to stdout.
|
||||
@@ -66,7 +70,7 @@ message ExtensionHandlerResponse {
|
||||
// true if the extension is handled by the extension handler; false otherwise
|
||||
bool handled = 1;
|
||||
|
||||
// Error message. If non-empty, the extension handling failed.
|
||||
// Error message(s). If non-empty, the extension handling failed.
|
||||
// The extension handler process should exit with status code zero
|
||||
// even if it reports an error in this way.
|
||||
//
|
||||
@@ -75,7 +79,7 @@ message ExtensionHandlerResponse {
|
||||
// itself -- such as the input Document being unparseable -- should be
|
||||
// reported by writing a message to stderr and exiting with a non-zero
|
||||
// status code.
|
||||
repeated string error = 2;
|
||||
repeated string errors = 2;
|
||||
|
||||
// text output
|
||||
google.protobuf.Any value = 3;
|
||||
@@ -85,9 +89,9 @@ message Wrapper {
|
||||
// version of the OpenAPI specification in which this extension was written.
|
||||
string version = 1;
|
||||
|
||||
// Name of the extension
|
||||
// Name of the extension.
|
||||
string extension_name = 2;
|
||||
|
||||
// Must be a valid yaml for the proto
|
||||
// YAML-formatted extension value.
|
||||
string yaml = 3;
|
||||
}
|
||||
|
68
vendor/github.com/googleapis/gnostic/extensions/extensions.go
generated
vendored
68
vendor/github.com/googleapis/gnostic/extensions/extensions.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -12,71 +12,53 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openapiextension_v1
|
||||
package gnostic_extension_v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
type documentHandler func(version string, extensionName string, document string)
|
||||
type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error)
|
||||
|
||||
func forInputYamlFromOpenapic(handler documentHandler) {
|
||||
// Main implements the main program of an extension handler.
|
||||
func Main(handler extensionHandler) {
|
||||
// unpack the request
|
||||
data, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Println("File error:", err.Error())
|
||||
log.Println("File error:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
fmt.Println("No input data.")
|
||||
log.Println("No input data.")
|
||||
os.Exit(1)
|
||||
}
|
||||
request := &ExtensionHandlerRequest{}
|
||||
err = proto.Unmarshal(data, request)
|
||||
if err != nil {
|
||||
fmt.Println("Input error:", err.Error())
|
||||
log.Println("Input error:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
handler(request.Wrapper.Version, request.Wrapper.ExtensionName, request.Wrapper.Yaml)
|
||||
}
|
||||
|
||||
// ProcessExtension calles the handler for a specified extension.
|
||||
func ProcessExtension(handleExtension extensionHandler) {
|
||||
response := &ExtensionHandlerResponse{}
|
||||
forInputYamlFromOpenapic(
|
||||
func(version string, extensionName string, yamlInput string) {
|
||||
var newObject proto.Message
|
||||
var err error
|
||||
|
||||
handled, newObject, err := handleExtension(extensionName, yamlInput)
|
||||
if !handled {
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// If we reach here, then the extension is handled
|
||||
response.Handled = true
|
||||
if err != nil {
|
||||
response.Error = append(response.Error, err.Error())
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
os.Exit(0)
|
||||
}
|
||||
response.Value, err = ptypes.MarshalAny(newObject)
|
||||
if err != nil {
|
||||
response.Error = append(response.Error, err.Error())
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
os.Exit(0)
|
||||
}
|
||||
})
|
||||
|
||||
// call the handler
|
||||
handled, output, err := handler(request.Wrapper.ExtensionName, request.Wrapper.Yaml)
|
||||
// respond with the output of the handler
|
||||
response := &ExtensionHandlerResponse{
|
||||
Handled: false, // default assumption
|
||||
Errors: make([]string, 0),
|
||||
}
|
||||
if err != nil {
|
||||
response.Errors = append(response.Errors, err.Error())
|
||||
} else if handled {
|
||||
response.Handled = true
|
||||
response.Value, err = ptypes.MarshalAny(output)
|
||||
if err != nil {
|
||||
response.Errors = append(response.Errors, err.Error())
|
||||
}
|
||||
}
|
||||
responseBytes, _ := proto.Marshal(response)
|
||||
os.Stdout.Write(responseBytes)
|
||||
}
|
||||
|
4
vendor/github.com/googleapis/gnostic/jsonschema/README.md
generated
vendored
Normal file
4
vendor/github.com/googleapis/gnostic/jsonschema/README.md
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# jsonschema
|
||||
|
||||
This directory contains code for reading, writing, and manipulating JSON
|
||||
schemas.
|
84
vendor/github.com/googleapis/gnostic/jsonschema/base.go
generated
vendored
Normal file
84
vendor/github.com/googleapis/gnostic/jsonschema/base.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED.
|
||||
|
||||
package jsonschema
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
func baseSchemaBytes() ([]byte, error){
|
||||
return base64.StdEncoding.DecodeString(
|
||||
`ewogICAgImlkIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIyIsCiAgICAi
|
||||
JHNjaGVtYSI6ICJodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMiLAogICAgImRl
|
||||
c2NyaXB0aW9uIjogIkNvcmUgc2NoZW1hIG1ldGEtc2NoZW1hIiwKICAgICJkZWZpbml0aW9ucyI6IHsK
|
||||
ICAgICAgICAic2NoZW1hQXJyYXkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAg
|
||||
ICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjIiB9CiAg
|
||||
ICAgICAgfSwKICAgICAgICAicG9zaXRpdmVJbnRlZ2VyIjogewogICAgICAgICAgICAidHlwZSI6ICJp
|
||||
bnRlZ2VyIiwKICAgICAgICAgICAgIm1pbmltdW0iOiAwCiAgICAgICAgfSwKICAgICAgICAicG9zaXRp
|
||||
dmVJbnRlZ2VyRGVmYXVsdDAiOiB7CiAgICAgICAgICAgICJhbGxPZiI6IFsgeyAiJHJlZiI6ICIjL2Rl
|
||||
ZmluaXRpb25zL3Bvc2l0aXZlSW50ZWdlciIgfSwgeyAiZGVmYXVsdCI6IDAgfSBdCiAgICAgICAgfSwK
|
||||
ICAgICAgICAic2ltcGxlVHlwZXMiOiB7CiAgICAgICAgICAgICJlbnVtIjogWyAiYXJyYXkiLCAiYm9v
|
||||
bGVhbiIsICJpbnRlZ2VyIiwgIm51bGwiLCAibnVtYmVyIiwgIm9iamVjdCIsICJzdHJpbmciIF0KICAg
|
||||
ICAgICB9LAogICAgICAgICJzdHJpbmdBcnJheSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiYXJyYXki
|
||||
LAogICAgICAgICAgICAiaXRlbXMiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgIm1p
|
||||
bkl0ZW1zIjogMSwKICAgICAgICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0KICAgIH0s
|
||||
CiAgICAidHlwZSI6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImlkIjogewog
|
||||
ICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAg
|
||||
ICAgICB9LAogICAgICAgICIkc2NoZW1hIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAog
|
||||
ICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICB9LAogICAgICAgICJ0aXRsZSI6IHsKICAg
|
||||
ICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImRlc2NyaXB0aW9uIjog
|
||||
ewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgfSwKICAgICAgICAiZGVmYXVsdCI6
|
||||
IHt9LAogICAgICAgICJtdWx0aXBsZU9mIjogewogICAgICAgICAgICAidHlwZSI6ICJudW1iZXIiLAog
|
||||
ICAgICAgICAgICAibWluaW11bSI6IDAsCiAgICAgICAgICAgICJleGNsdXNpdmVNaW5pbXVtIjogdHJ1
|
||||
ZQogICAgICAgIH0sCiAgICAgICAgIm1heGltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJl
|
||||
ciIKICAgICAgICB9LAogICAgICAgICJleGNsdXNpdmVNYXhpbXVtIjogewogICAgICAgICAgICAidHlw
|
||||
ZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAg
|
||||
ICAgIm1pbmltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJlciIKICAgICAgICB9LAogICAg
|
||||
ICAgICJleGNsdXNpdmVNaW5pbXVtIjogewogICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAg
|
||||
ICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgIm1heExlbmd0aCI6IHsg
|
||||
IiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pbkxlbmd0
|
||||
aCI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAg
|
||||
ICAgICAicGF0dGVybiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAg
|
||||
ImZvcm1hdCI6ICJyZWdleCIKICAgICAgICB9LAogICAgICAgICJhZGRpdGlvbmFsSXRlbXMiOiB7CiAg
|
||||
ICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgInR5cGUiOiAiYm9vbGVhbiIgfSwK
|
||||
ICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAi
|
||||
ZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICJhbnlP
|
||||
ZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgICAgIHsgIiRy
|
||||
ZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIgfQogICAgICAgICAgICBdLAogICAgICAgICAg
|
||||
ICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAibWF4SXRlbXMiOiB7ICIkcmVmIjogIiMv
|
||||
ZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyIiB9LAogICAgICAgICJtaW5JdGVtcyI6IHsgIiRyZWYi
|
||||
OiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAgICAgICAidW5pcXVl
|
||||
SXRlbXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAiZGVmYXVs
|
||||
dCI6IGZhbHNlCiAgICAgICAgfSwKICAgICAgICAibWF4UHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIy9k
|
||||
ZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pblByb3BlcnRpZXMiOiB7ICIk
|
||||
cmVmIjogIiMvZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyRGVmYXVsdDAiIH0sCiAgICAgICAgInJl
|
||||
cXVpcmVkIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3N0cmluZ0FycmF5IiB9LAogICAgICAgICJh
|
||||
ZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAg
|
||||
ICAgeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjIiB9CiAg
|
||||
ICAgICAgICAgIF0sCiAgICAgICAgICAgICJkZWZhdWx0Ijoge30KICAgICAgICB9LAogICAgICAgICJk
|
||||
ZWZpbml0aW9ucyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImFk
|
||||
ZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9LAogICAgICAgICAgICAiZGVmYXVsdCI6
|
||||
IHt9CiAgICAgICAgfSwKICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAi
|
||||
b2JqZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9
|
||||
LAogICAgICAgICAgICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAicGF0dGVyblByb3Bl
|
||||
cnRpZXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJhZGRpdGlv
|
||||
bmFsUHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgImRlZmF1bHQiOiB7fQog
|
||||
ICAgICAgIH0sCiAgICAgICAgImRlcGVuZGVuY2llcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2Jq
|
||||
ZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAg
|
||||
ImFueU9mIjogWwogICAgICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAg
|
||||
ICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc3RyaW5nQXJyYXkiIH0KICAgICAgICAgICAg
|
||||
ICAgIF0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImVudW0iOiB7CiAgICAgICAgICAg
|
||||
ICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgInVu
|
||||
aXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICJh
|
||||
bnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zaW1wbGVUeXBl
|
||||
cyIgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIs
|
||||
CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NpbXBs
|
||||
ZVR5cGVzIiB9LAogICAgICAgICAgICAgICAgICAgICJtaW5JdGVtcyI6IDEsCiAgICAgICAgICAgICAg
|
||||
ICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAg
|
||||
ICAgICAgfSwKICAgICAgICAiYWxsT2YiOiB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc2NoZW1hQXJy
|
||||
YXkiIH0sCiAgICAgICAgImFueU9mIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NjaGVtYUFycmF5
|
||||
IiB9LAogICAgICAgICJvbmVPZiI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIg
|
||||
fSwKICAgICAgICAibm90IjogeyAiJHJlZiI6ICIjIiB9CiAgICB9LAogICAgImRlcGVuZGVuY2llcyI6
|
||||
IHsKICAgICAgICAiZXhjbHVzaXZlTWF4aW11bSI6IFsgIm1heGltdW0iIF0sCiAgICAgICAgImV4Y2x1
|
||||
c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}
|
229
vendor/github.com/googleapis/gnostic/jsonschema/display.go
generated
vendored
Normal file
229
vendor/github.com/googleapis/gnostic/jsonschema/display.go
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
// 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"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//
|
||||
// DISPLAY
|
||||
// The following methods display Schemas.
|
||||
//
|
||||
|
||||
// Description returns a string representation of a string or string array.
|
||||
func (s *StringOrStringArray) Description() string {
|
||||
if s.String != nil {
|
||||
return *s.String
|
||||
}
|
||||
if s.StringArray != nil {
|
||||
return strings.Join(*s.StringArray, ", ")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Returns a string representation of a Schema.
|
||||
func (schema *Schema) String() string {
|
||||
return schema.describeSchema("")
|
||||
}
|
||||
|
||||
// Helper: Returns a string representation of a Schema indented by a specified string.
|
||||
func (schema *Schema) describeSchema(indent string) string {
|
||||
result := ""
|
||||
if schema.Schema != nil {
|
||||
result += indent + "$schema: " + *(schema.Schema) + "\n"
|
||||
}
|
||||
if schema.ID != nil {
|
||||
result += indent + "id: " + *(schema.ID) + "\n"
|
||||
}
|
||||
if schema.MultipleOf != nil {
|
||||
result += indent + fmt.Sprintf("multipleOf: %+v\n", *(schema.MultipleOf))
|
||||
}
|
||||
if schema.Maximum != nil {
|
||||
result += indent + fmt.Sprintf("maximum: %+v\n", *(schema.Maximum))
|
||||
}
|
||||
if schema.ExclusiveMaximum != nil {
|
||||
result += indent + fmt.Sprintf("exclusiveMaximum: %+v\n", *(schema.ExclusiveMaximum))
|
||||
}
|
||||
if schema.Minimum != nil {
|
||||
result += indent + fmt.Sprintf("minimum: %+v\n", *(schema.Minimum))
|
||||
}
|
||||
if schema.ExclusiveMinimum != nil {
|
||||
result += indent + fmt.Sprintf("exclusiveMinimum: %+v\n", *(schema.ExclusiveMinimum))
|
||||
}
|
||||
if schema.MaxLength != nil {
|
||||
result += indent + fmt.Sprintf("maxLength: %+v\n", *(schema.MaxLength))
|
||||
}
|
||||
if schema.MinLength != nil {
|
||||
result += indent + fmt.Sprintf("minLength: %+v\n", *(schema.MinLength))
|
||||
}
|
||||
if schema.Pattern != nil {
|
||||
result += indent + fmt.Sprintf("pattern: %+v\n", *(schema.Pattern))
|
||||
}
|
||||
if schema.AdditionalItems != nil {
|
||||
s := schema.AdditionalItems.Schema
|
||||
if s != nil {
|
||||
result += indent + "additionalItems:\n"
|
||||
result += s.describeSchema(indent + " ")
|
||||
} else {
|
||||
b := *(schema.AdditionalItems.Boolean)
|
||||
result += indent + fmt.Sprintf("additionalItems: %+v\n", b)
|
||||
}
|
||||
}
|
||||
if schema.Items != nil {
|
||||
result += indent + "items:\n"
|
||||
items := schema.Items
|
||||
if items.SchemaArray != nil {
|
||||
for i, s := range *(items.SchemaArray) {
|
||||
result += indent + " " + fmt.Sprintf("%d", i) + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
} else if items.Schema != nil {
|
||||
result += items.Schema.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.MaxItems != nil {
|
||||
result += indent + fmt.Sprintf("maxItems: %+v\n", *(schema.MaxItems))
|
||||
}
|
||||
if schema.MinItems != nil {
|
||||
result += indent + fmt.Sprintf("minItems: %+v\n", *(schema.MinItems))
|
||||
}
|
||||
if schema.UniqueItems != nil {
|
||||
result += indent + fmt.Sprintf("uniqueItems: %+v\n", *(schema.UniqueItems))
|
||||
}
|
||||
if schema.MaxProperties != nil {
|
||||
result += indent + fmt.Sprintf("maxProperties: %+v\n", *(schema.MaxProperties))
|
||||
}
|
||||
if schema.MinProperties != nil {
|
||||
result += indent + fmt.Sprintf("minProperties: %+v\n", *(schema.MinProperties))
|
||||
}
|
||||
if schema.Required != nil {
|
||||
result += indent + fmt.Sprintf("required: %+v\n", *(schema.Required))
|
||||
}
|
||||
if schema.AdditionalProperties != nil {
|
||||
s := schema.AdditionalProperties.Schema
|
||||
if s != nil {
|
||||
result += indent + "additionalProperties:\n"
|
||||
result += s.describeSchema(indent + " ")
|
||||
} else {
|
||||
b := *(schema.AdditionalProperties.Boolean)
|
||||
result += indent + fmt.Sprintf("additionalProperties: %+v\n", b)
|
||||
}
|
||||
}
|
||||
if schema.Properties != nil {
|
||||
result += indent + "properties:\n"
|
||||
for _, pair := range *(schema.Properties) {
|
||||
name := pair.Name
|
||||
s := pair.Value
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.PatternProperties != nil {
|
||||
result += indent + "patternProperties:\n"
|
||||
for _, pair := range *(schema.PatternProperties) {
|
||||
name := pair.Name
|
||||
s := pair.Value
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.Dependencies != nil {
|
||||
result += indent + "dependencies:\n"
|
||||
for _, pair := range *(schema.Dependencies) {
|
||||
name := pair.Name
|
||||
schemaOrStringArray := pair.Value
|
||||
s := schemaOrStringArray.Schema
|
||||
if s != nil {
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
} else {
|
||||
a := schemaOrStringArray.StringArray
|
||||
if a != nil {
|
||||
result += indent + " " + name + ":\n"
|
||||
for _, s2 := range *a {
|
||||
result += indent + " " + " " + s2 + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if schema.Enumeration != nil {
|
||||
result += indent + "enumeration:\n"
|
||||
for _, value := range *(schema.Enumeration) {
|
||||
if value.String != nil {
|
||||
result += indent + " " + fmt.Sprintf("%+v\n", *value.String)
|
||||
} else {
|
||||
result += indent + " " + fmt.Sprintf("%+v\n", *value.Bool)
|
||||
}
|
||||
}
|
||||
}
|
||||
if schema.Type != nil {
|
||||
result += indent + fmt.Sprintf("type: %+v\n", schema.Type.Description())
|
||||
}
|
||||
if schema.AllOf != nil {
|
||||
result += indent + "allOf:\n"
|
||||
for _, s := range *(schema.AllOf) {
|
||||
result += s.describeSchema(indent + " ")
|
||||
result += indent + "-\n"
|
||||
}
|
||||
}
|
||||
if schema.AnyOf != nil {
|
||||
result += indent + "anyOf:\n"
|
||||
for _, s := range *(schema.AnyOf) {
|
||||
result += s.describeSchema(indent + " ")
|
||||
result += indent + "-\n"
|
||||
}
|
||||
}
|
||||
if schema.OneOf != nil {
|
||||
result += indent + "oneOf:\n"
|
||||
for _, s := range *(schema.OneOf) {
|
||||
result += s.describeSchema(indent + " ")
|
||||
result += indent + "-\n"
|
||||
}
|
||||
}
|
||||
if schema.Not != nil {
|
||||
result += indent + "not:\n"
|
||||
result += schema.Not.describeSchema(indent + " ")
|
||||
}
|
||||
if schema.Definitions != nil {
|
||||
result += indent + "definitions:\n"
|
||||
for _, pair := range *(schema.Definitions) {
|
||||
name := pair.Name
|
||||
s := pair.Value
|
||||
result += indent + " " + name + ":\n"
|
||||
result += s.describeSchema(indent + " " + " ")
|
||||
}
|
||||
}
|
||||
if schema.Title != nil {
|
||||
result += indent + "title: " + *(schema.Title) + "\n"
|
||||
}
|
||||
if schema.Description != nil {
|
||||
result += indent + "description: " + *(schema.Description) + "\n"
|
||||
}
|
||||
if schema.Default != nil {
|
||||
result += indent + "default:\n"
|
||||
result += indent + fmt.Sprintf(" %+v\n", *(schema.Default))
|
||||
}
|
||||
if schema.Format != nil {
|
||||
result += indent + "format: " + *(schema.Format) + "\n"
|
||||
}
|
||||
if schema.Ref != nil {
|
||||
result += indent + "$ref: " + *(schema.Ref) + "\n"
|
||||
}
|
||||
return result
|
||||
}
|
228
vendor/github.com/googleapis/gnostic/jsonschema/models.go
generated
vendored
Normal file
228
vendor/github.com/googleapis/gnostic/jsonschema/models.go
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
// 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 supports the reading, writing, and manipulation
|
||||
// of JSON Schemas.
|
||||
package jsonschema
|
||||
|
||||
import "gopkg.in/yaml.v3"
|
||||
|
||||
// The Schema struct models a JSON Schema and, because schemas are
|
||||
// defined hierarchically, contains many references to itself.
|
||||
// All fields are pointers and are nil if the associated values
|
||||
// are not specified.
|
||||
type Schema struct {
|
||||
Schema *string // $schema
|
||||
ID *string // id keyword used for $ref resolution scope
|
||||
Ref *string // $ref, i.e. JSON Pointers
|
||||
|
||||
// http://json-schema.org/latest/json-schema-validation.html
|
||||
// 5.1. Validation keywords for numeric instances (number and integer)
|
||||
MultipleOf *SchemaNumber
|
||||
Maximum *SchemaNumber
|
||||
ExclusiveMaximum *bool
|
||||
Minimum *SchemaNumber
|
||||
ExclusiveMinimum *bool
|
||||
|
||||
// 5.2. Validation keywords for strings
|
||||
MaxLength *int64
|
||||
MinLength *int64
|
||||
Pattern *string
|
||||
|
||||
// 5.3. Validation keywords for arrays
|
||||
AdditionalItems *SchemaOrBoolean
|
||||
Items *SchemaOrSchemaArray
|
||||
MaxItems *int64
|
||||
MinItems *int64
|
||||
UniqueItems *bool
|
||||
|
||||
// 5.4. Validation keywords for objects
|
||||
MaxProperties *int64
|
||||
MinProperties *int64
|
||||
Required *[]string
|
||||
AdditionalProperties *SchemaOrBoolean
|
||||
Properties *[]*NamedSchema
|
||||
PatternProperties *[]*NamedSchema
|
||||
Dependencies *[]*NamedSchemaOrStringArray
|
||||
|
||||
// 5.5. Validation keywords for any instance type
|
||||
Enumeration *[]SchemaEnumValue
|
||||
Type *StringOrStringArray
|
||||
AllOf *[]*Schema
|
||||
AnyOf *[]*Schema
|
||||
OneOf *[]*Schema
|
||||
Not *Schema
|
||||
Definitions *[]*NamedSchema
|
||||
|
||||
// 6. Metadata keywords
|
||||
Title *string
|
||||
Description *string
|
||||
Default *yaml.Node
|
||||
|
||||
// 7. Semantic validation with "format"
|
||||
Format *string
|
||||
}
|
||||
|
||||
// These helper structs represent "combination" types that generally can
|
||||
// have values of one type or another. All are used to represent parts
|
||||
// of Schemas.
|
||||
|
||||
// SchemaNumber represents a value that can be either an Integer or a Float.
|
||||
type SchemaNumber struct {
|
||||
Integer *int64
|
||||
Float *float64
|
||||
}
|
||||
|
||||
// NewSchemaNumberWithInteger creates and returns a new object
|
||||
func NewSchemaNumberWithInteger(i int64) *SchemaNumber {
|
||||
result := &SchemaNumber{}
|
||||
result.Integer = &i
|
||||
return result
|
||||
}
|
||||
|
||||
// NewSchemaNumberWithFloat creates and returns a new object
|
||||
func NewSchemaNumberWithFloat(f float64) *SchemaNumber {
|
||||
result := &SchemaNumber{}
|
||||
result.Float = &f
|
||||
return result
|
||||
}
|
||||
|
||||
// SchemaOrBoolean represents a value that can be either a Schema or a Boolean.
|
||||
type SchemaOrBoolean struct {
|
||||
Schema *Schema
|
||||
Boolean *bool
|
||||
}
|
||||
|
||||
// NewSchemaOrBooleanWithSchema creates and returns a new object
|
||||
func NewSchemaOrBooleanWithSchema(s *Schema) *SchemaOrBoolean {
|
||||
result := &SchemaOrBoolean{}
|
||||
result.Schema = s
|
||||
return result
|
||||
}
|
||||
|
||||
// NewSchemaOrBooleanWithBoolean creates and returns a new object
|
||||
func NewSchemaOrBooleanWithBoolean(b bool) *SchemaOrBoolean {
|
||||
result := &SchemaOrBoolean{}
|
||||
result.Boolean = &b
|
||||
return result
|
||||
}
|
||||
|
||||
// StringOrStringArray represents a value that can be either
|
||||
// a String or an Array of Strings.
|
||||
type StringOrStringArray struct {
|
||||
String *string
|
||||
StringArray *[]string
|
||||
}
|
||||
|
||||
// NewStringOrStringArrayWithString creates and returns a new object
|
||||
func NewStringOrStringArrayWithString(s string) *StringOrStringArray {
|
||||
result := &StringOrStringArray{}
|
||||
result.String = &s
|
||||
return result
|
||||
}
|
||||
|
||||
// NewStringOrStringArrayWithStringArray creates and returns a new object
|
||||
func NewStringOrStringArrayWithStringArray(a []string) *StringOrStringArray {
|
||||
result := &StringOrStringArray{}
|
||||
result.StringArray = &a
|
||||
return result
|
||||
}
|
||||
|
||||
// SchemaOrStringArray represents a value that can be either
|
||||
// a Schema or an Array of Strings.
|
||||
type SchemaOrStringArray struct {
|
||||
Schema *Schema
|
||||
StringArray *[]string
|
||||
}
|
||||
|
||||
// SchemaOrSchemaArray represents a value that can be either
|
||||
// a Schema or an Array of Schemas.
|
||||
type SchemaOrSchemaArray struct {
|
||||
Schema *Schema
|
||||
SchemaArray *[]*Schema
|
||||
}
|
||||
|
||||
// NewSchemaOrSchemaArrayWithSchema creates and returns a new object
|
||||
func NewSchemaOrSchemaArrayWithSchema(s *Schema) *SchemaOrSchemaArray {
|
||||
result := &SchemaOrSchemaArray{}
|
||||
result.Schema = s
|
||||
return result
|
||||
}
|
||||
|
||||
// NewSchemaOrSchemaArrayWithSchemaArray creates and returns a new object
|
||||
func NewSchemaOrSchemaArrayWithSchemaArray(a []*Schema) *SchemaOrSchemaArray {
|
||||
result := &SchemaOrSchemaArray{}
|
||||
result.SchemaArray = &a
|
||||
return result
|
||||
}
|
||||
|
||||
// SchemaEnumValue represents a value that can be part of an
|
||||
// enumeration in a Schema.
|
||||
type SchemaEnumValue struct {
|
||||
String *string
|
||||
Bool *bool
|
||||
}
|
||||
|
||||
// NamedSchema is a name-value pair that is used to emulate maps
|
||||
// with ordered keys.
|
||||
type NamedSchema struct {
|
||||
Name string
|
||||
Value *Schema
|
||||
}
|
||||
|
||||
// NewNamedSchema creates and returns a new object
|
||||
func NewNamedSchema(name string, value *Schema) *NamedSchema {
|
||||
return &NamedSchema{Name: name, Value: value}
|
||||
}
|
||||
|
||||
// NamedSchemaOrStringArray is a name-value pair that is used
|
||||
// to emulate maps with ordered keys.
|
||||
type NamedSchemaOrStringArray struct {
|
||||
Name string
|
||||
Value *SchemaOrStringArray
|
||||
}
|
||||
|
||||
// Access named subschemas by name
|
||||
|
||||
func namedSchemaArrayElementWithName(array *[]*NamedSchema, name string) *Schema {
|
||||
if array == nil {
|
||||
return nil
|
||||
}
|
||||
for _, pair := range *array {
|
||||
if pair.Name == name {
|
||||
return pair.Value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PropertyWithName returns the selected element.
|
||||
func (s *Schema) PropertyWithName(name string) *Schema {
|
||||
return namedSchemaArrayElementWithName(s.Properties, name)
|
||||
}
|
||||
|
||||
// PatternPropertyWithName returns the selected element.
|
||||
func (s *Schema) PatternPropertyWithName(name string) *Schema {
|
||||
return namedSchemaArrayElementWithName(s.PatternProperties, name)
|
||||
}
|
||||
|
||||
// DefinitionWithName returns the selected element.
|
||||
func (s *Schema) DefinitionWithName(name string) *Schema {
|
||||
return namedSchemaArrayElementWithName(s.Definitions, name)
|
||||
}
|
||||
|
||||
// AddProperty adds a named property.
|
||||
func (s *Schema) AddProperty(name string, property *Schema) {
|
||||
*s.Properties = append(*s.Properties, NewNamedSchema(name, property))
|
||||
}
|
394
vendor/github.com/googleapis/gnostic/jsonschema/operations.go
generated
vendored
Normal file
394
vendor/github.com/googleapis/gnostic/jsonschema/operations.go
generated
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
442
vendor/github.com/googleapis/gnostic/jsonschema/reader.go
generated
vendored
Normal file
442
vendor/github.com/googleapis/gnostic/jsonschema/reader.go
generated
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
// 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.
|
||||
|
||||
//go:generate go run generate-base.go
|
||||
|
||||
package jsonschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// This is a global map of all known Schemas.
|
||||
// It is initialized when the first Schema is created and inserted.
|
||||
var schemas map[string]*Schema
|
||||
|
||||
// NewBaseSchema builds a schema object from an embedded json representation.
|
||||
func NewBaseSchema() (schema *Schema, err error) {
|
||||
b, err := baseSchemaBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var node yaml.Node
|
||||
err = yaml.Unmarshal(b, &node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewSchemaFromObject(&node), nil
|
||||
}
|
||||
|
||||
// NewSchemaFromFile reads a schema from a file.
|
||||
// Currently this assumes that schemas are stored in the source distribution of this project.
|
||||
func NewSchemaFromFile(filename string) (schema *Schema, err error) {
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var node yaml.Node
|
||||
err = yaml.Unmarshal(file, &node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewSchemaFromObject(&node), nil
|
||||
}
|
||||
|
||||
// NewSchemaFromObject constructs a schema from a parsed JSON object.
|
||||
// Due to the complexity of the schema representation, this is a
|
||||
// custom reader and not the standard Go JSON reader (encoding/json).
|
||||
func NewSchemaFromObject(jsonData *yaml.Node) *Schema {
|
||||
switch jsonData.Kind {
|
||||
case yaml.DocumentNode:
|
||||
return NewSchemaFromObject(jsonData.Content[0])
|
||||
case yaml.MappingNode:
|
||||
schema := &Schema{}
|
||||
|
||||
for i := 0; i < len(jsonData.Content); i += 2 {
|
||||
k := jsonData.Content[i].Value
|
||||
v := jsonData.Content[i+1]
|
||||
|
||||
switch k {
|
||||
case "$schema":
|
||||
schema.Schema = schema.stringValue(v)
|
||||
case "id":
|
||||
schema.ID = schema.stringValue(v)
|
||||
|
||||
case "multipleOf":
|
||||
schema.MultipleOf = schema.numberValue(v)
|
||||
case "maximum":
|
||||
schema.Maximum = schema.numberValue(v)
|
||||
case "exclusiveMaximum":
|
||||
schema.ExclusiveMaximum = schema.boolValue(v)
|
||||
case "minimum":
|
||||
schema.Minimum = schema.numberValue(v)
|
||||
case "exclusiveMinimum":
|
||||
schema.ExclusiveMinimum = schema.boolValue(v)
|
||||
|
||||
case "maxLength":
|
||||
schema.MaxLength = schema.intValue(v)
|
||||
case "minLength":
|
||||
schema.MinLength = schema.intValue(v)
|
||||
case "pattern":
|
||||
schema.Pattern = schema.stringValue(v)
|
||||
|
||||
case "additionalItems":
|
||||
schema.AdditionalItems = schema.schemaOrBooleanValue(v)
|
||||
case "items":
|
||||
schema.Items = schema.schemaOrSchemaArrayValue(v)
|
||||
case "maxItems":
|
||||
schema.MaxItems = schema.intValue(v)
|
||||
case "minItems":
|
||||
schema.MinItems = schema.intValue(v)
|
||||
case "uniqueItems":
|
||||
schema.UniqueItems = schema.boolValue(v)
|
||||
|
||||
case "maxProperties":
|
||||
schema.MaxProperties = schema.intValue(v)
|
||||
case "minProperties":
|
||||
schema.MinProperties = schema.intValue(v)
|
||||
case "required":
|
||||
schema.Required = schema.arrayOfStringsValue(v)
|
||||
case "additionalProperties":
|
||||
schema.AdditionalProperties = schema.schemaOrBooleanValue(v)
|
||||
case "properties":
|
||||
schema.Properties = schema.mapOfSchemasValue(v)
|
||||
case "patternProperties":
|
||||
schema.PatternProperties = schema.mapOfSchemasValue(v)
|
||||
case "dependencies":
|
||||
schema.Dependencies = schema.mapOfSchemasOrStringArraysValue(v)
|
||||
|
||||
case "enum":
|
||||
schema.Enumeration = schema.arrayOfEnumValuesValue(v)
|
||||
|
||||
case "type":
|
||||
schema.Type = schema.stringOrStringArrayValue(v)
|
||||
case "allOf":
|
||||
schema.AllOf = schema.arrayOfSchemasValue(v)
|
||||
case "anyOf":
|
||||
schema.AnyOf = schema.arrayOfSchemasValue(v)
|
||||
case "oneOf":
|
||||
schema.OneOf = schema.arrayOfSchemasValue(v)
|
||||
case "not":
|
||||
schema.Not = NewSchemaFromObject(v)
|
||||
case "definitions":
|
||||
schema.Definitions = schema.mapOfSchemasValue(v)
|
||||
|
||||
case "title":
|
||||
schema.Title = schema.stringValue(v)
|
||||
case "description":
|
||||
schema.Description = schema.stringValue(v)
|
||||
|
||||
case "default":
|
||||
schema.Default = v
|
||||
|
||||
case "format":
|
||||
schema.Format = schema.stringValue(v)
|
||||
case "$ref":
|
||||
schema.Ref = schema.stringValue(v)
|
||||
default:
|
||||
fmt.Printf("UNSUPPORTED (%s)\n", k)
|
||||
}
|
||||
}
|
||||
|
||||
// insert schema in global map
|
||||
if schema.ID != nil {
|
||||
if schemas == nil {
|
||||
schemas = make(map[string]*Schema, 0)
|
||||
}
|
||||
schemas[*(schema.ID)] = schema
|
||||
}
|
||||
return schema
|
||||
|
||||
default:
|
||||
fmt.Printf("schemaValue: unexpected node %+v\n", jsonData)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// BUILDERS
|
||||
// The following methods build elements of Schemas from interface{} values.
|
||||
// Each returns nil if it is unable to build the desired element.
|
||||
//
|
||||
|
||||
// Gets the string value of an interface{} value if possible.
|
||||
func (schema *Schema) stringValue(v *yaml.Node) *string {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
return &v.Value
|
||||
default:
|
||||
fmt.Printf("stringValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets the numeric value of an interface{} value if possible.
|
||||
func (schema *Schema) numberValue(v *yaml.Node) *SchemaNumber {
|
||||
number := &SchemaNumber{}
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v.Tag {
|
||||
case "!!float":
|
||||
v2, _ := strconv.ParseFloat(v.Value, 64)
|
||||
number.Float = &v2
|
||||
return number
|
||||
case "!!int":
|
||||
v2, _ := strconv.ParseInt(v.Value, 10, 64)
|
||||
number.Integer = &v2
|
||||
return number
|
||||
default:
|
||||
fmt.Printf("stringValue: unexpected node %+v\n", v)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("stringValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets the integer value of an interface{} value if possible.
|
||||
func (schema *Schema) intValue(v *yaml.Node) *int64 {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v.Tag {
|
||||
case "!!float":
|
||||
v2, _ := strconv.ParseFloat(v.Value, 64)
|
||||
v3 := int64(v2)
|
||||
return &v3
|
||||
case "!!int":
|
||||
v2, _ := strconv.ParseInt(v.Value, 10, 64)
|
||||
return &v2
|
||||
default:
|
||||
fmt.Printf("intValue: unexpected node %+v\n", v)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("intValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets the bool value of an interface{} value if possible.
|
||||
func (schema *Schema) boolValue(v *yaml.Node) *bool {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v.Tag {
|
||||
case "!!bool":
|
||||
v2, _ := strconv.ParseBool(v.Value)
|
||||
return &v2
|
||||
default:
|
||||
fmt.Printf("boolValue: unexpected node %+v\n", v)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("boolValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets a map of Schemas from an interface{} value if possible.
|
||||
func (schema *Schema) mapOfSchemasValue(v *yaml.Node) *[]*NamedSchema {
|
||||
switch v.Kind {
|
||||
case yaml.MappingNode:
|
||||
m := make([]*NamedSchema, 0)
|
||||
for i := 0; i < len(v.Content); i += 2 {
|
||||
k2 := v.Content[i].Value
|
||||
v2 := v.Content[i+1]
|
||||
pair := &NamedSchema{Name: k2, Value: NewSchemaFromObject(v2)}
|
||||
m = append(m, pair)
|
||||
}
|
||||
return &m
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets an array of Schemas from an interface{} value if possible.
|
||||
func (schema *Schema) arrayOfSchemasValue(v *yaml.Node) *[]*Schema {
|
||||
switch v.Kind {
|
||||
case yaml.SequenceNode:
|
||||
m := make([]*Schema, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.MappingNode:
|
||||
s := NewSchemaFromObject(v2)
|
||||
m = append(m, s)
|
||||
default:
|
||||
fmt.Printf("arrayOfSchemasValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
return &m
|
||||
case yaml.MappingNode:
|
||||
m := make([]*Schema, 0)
|
||||
s := NewSchemaFromObject(v)
|
||||
m = append(m, s)
|
||||
return &m
|
||||
default:
|
||||
fmt.Printf("arrayOfSchemasValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets a Schema or an array of Schemas from an interface{} value if possible.
|
||||
func (schema *Schema) schemaOrSchemaArrayValue(v *yaml.Node) *SchemaOrSchemaArray {
|
||||
switch v.Kind {
|
||||
case yaml.SequenceNode:
|
||||
m := make([]*Schema, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.MappingNode:
|
||||
s := NewSchemaFromObject(v2)
|
||||
m = append(m, s)
|
||||
default:
|
||||
fmt.Printf("schemaOrSchemaArrayValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
return &SchemaOrSchemaArray{SchemaArray: &m}
|
||||
case yaml.MappingNode:
|
||||
s := NewSchemaFromObject(v)
|
||||
return &SchemaOrSchemaArray{Schema: s}
|
||||
default:
|
||||
fmt.Printf("schemaOrSchemaArrayValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets an array of strings from an interface{} value if possible.
|
||||
func (schema *Schema) arrayOfStringsValue(v *yaml.Node) *[]string {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a := []string{v.Value}
|
||||
return &a
|
||||
case yaml.SequenceNode:
|
||||
a := make([]string, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a = append(a, v2.Value)
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
return &a
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets a string or an array of strings from an interface{} value if possible.
|
||||
func (schema *Schema) stringOrStringArrayValue(v *yaml.Node) *StringOrStringArray {
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
s := &StringOrStringArray{}
|
||||
s.String = &v.Value
|
||||
return s
|
||||
case yaml.SequenceNode:
|
||||
a := make([]string, 0)
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a = append(a, v2.Value)
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
s := &StringOrStringArray{}
|
||||
s.StringArray = &a
|
||||
return s
|
||||
default:
|
||||
fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Gets an array of enum values from an interface{} value if possible.
|
||||
func (schema *Schema) arrayOfEnumValuesValue(v *yaml.Node) *[]SchemaEnumValue {
|
||||
a := make([]SchemaEnumValue, 0)
|
||||
switch v.Kind {
|
||||
case yaml.SequenceNode:
|
||||
for _, v2 := range v.Content {
|
||||
switch v2.Kind {
|
||||
case yaml.ScalarNode:
|
||||
switch v2.Tag {
|
||||
case "!!str":
|
||||
a = append(a, SchemaEnumValue{String: &v2.Value})
|
||||
case "!!bool":
|
||||
v3, _ := strconv.ParseBool(v2.Value)
|
||||
a = append(a, SchemaEnumValue{Bool: &v3})
|
||||
default:
|
||||
fmt.Printf("arrayOfEnumValuesValue: unexpected type %s\n", v2.Tag)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("arrayOfEnumValuesValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
default:
|
||||
fmt.Printf("arrayOfEnumValuesValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
// Gets a map of schemas or string arrays from an interface{} value if possible.
|
||||
func (schema *Schema) mapOfSchemasOrStringArraysValue(v *yaml.Node) *[]*NamedSchemaOrStringArray {
|
||||
m := make([]*NamedSchemaOrStringArray, 0)
|
||||
switch v.Kind {
|
||||
case yaml.MappingNode:
|
||||
for i := 0; i < len(v.Content); i += 2 {
|
||||
k2 := v.Content[i].Value
|
||||
v2 := v.Content[i+1]
|
||||
switch v2.Kind {
|
||||
case yaml.SequenceNode:
|
||||
a := make([]string, 0)
|
||||
for _, v3 := range v2.Content {
|
||||
switch v3.Kind {
|
||||
case yaml.ScalarNode:
|
||||
a = append(a, v3.Value)
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v3)
|
||||
}
|
||||
}
|
||||
s := &SchemaOrStringArray{}
|
||||
s.StringArray = &a
|
||||
pair := &NamedSchemaOrStringArray{Name: k2, Value: s}
|
||||
m = append(m, pair)
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v2)
|
||||
}
|
||||
}
|
||||
default:
|
||||
fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return &m
|
||||
}
|
||||
|
||||
// Gets a schema or a boolean value from an interface{} value if possible.
|
||||
func (schema *Schema) schemaOrBooleanValue(v *yaml.Node) *SchemaOrBoolean {
|
||||
schemaOrBoolean := &SchemaOrBoolean{}
|
||||
switch v.Kind {
|
||||
case yaml.ScalarNode:
|
||||
v2, _ := strconv.ParseBool(v.Value)
|
||||
schemaOrBoolean.Boolean = &v2
|
||||
case yaml.MappingNode:
|
||||
schemaOrBoolean.Schema = NewSchemaFromObject(v)
|
||||
default:
|
||||
fmt.Printf("schemaOrBooleanValue: unexpected node %+v\n", v)
|
||||
}
|
||||
return schemaOrBoolean
|
||||
}
|
150
vendor/github.com/googleapis/gnostic/jsonschema/schema.json
generated
vendored
Normal file
150
vendor/github.com/googleapis/gnostic/jsonschema/schema.json
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"id": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#" }
|
||||
},
|
||||
"positiveInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"positiveIntegerDefault0": {
|
||||
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": {},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"exclusiveMinimum": true
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxLength": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
{ "type": "boolean" },
|
||||
{ "$ref": "#" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/schemaArray" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"maxItems": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
|
||||
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
||||
"required": { "$ref": "#/definitions/stringArray" },
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "type": "boolean" },
|
||||
{ "$ref": "#" }
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/stringArray" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/simpleTypes" },
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/simpleTypes" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"allOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"not": { "$ref": "#" }
|
||||
},
|
||||
"dependencies": {
|
||||
"exclusiveMaximum": [ "maximum" ],
|
||||
"exclusiveMinimum": [ "minimum" ]
|
||||
},
|
||||
"default": {}
|
||||
}
|
369
vendor/github.com/googleapis/gnostic/jsonschema/writer.go
generated
vendored
Normal file
369
vendor/github.com/googleapis/gnostic/jsonschema/writer.go
generated
vendored
Normal file
@@ -0,0 +1,369 @@
|
||||
// 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"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const indentation = " "
|
||||
|
||||
func renderMappingNode(node *yaml.Node, indent string) (result string) {
|
||||
result = "{\n"
|
||||
innerIndent := indent + indentation
|
||||
for i := 0; i < len(node.Content); i += 2 {
|
||||
// first print the key
|
||||
key := node.Content[i].Value
|
||||
result += fmt.Sprintf("%s\"%+v\": ", innerIndent, key)
|
||||
// then the value
|
||||
value := node.Content[i+1]
|
||||
switch value.Kind {
|
||||
case yaml.ScalarNode:
|
||||
result += "\"" + value.Value + "\""
|
||||
case yaml.MappingNode:
|
||||
result += renderMappingNode(value, innerIndent)
|
||||
case yaml.SequenceNode:
|
||||
result += renderSequenceNode(value, innerIndent)
|
||||
default:
|
||||
result += fmt.Sprintf("???MapItem(Key:%+v, Value:%T)", value, value)
|
||||
}
|
||||
if i < len(node.Content)-2 {
|
||||
result += ","
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
|
||||
result += indent + "}"
|
||||
return result
|
||||
}
|
||||
|
||||
func renderSequenceNode(node *yaml.Node, indent string) (result string) {
|
||||
result = "[\n"
|
||||
innerIndent := indent + indentation
|
||||
for i := 0; i < len(node.Content); i++ {
|
||||
item := node.Content[i]
|
||||
switch item.Kind {
|
||||
case yaml.ScalarNode:
|
||||
result += innerIndent + "\"" + item.Value + "\""
|
||||
case yaml.MappingNode:
|
||||
result += innerIndent + renderMappingNode(item, innerIndent) + ""
|
||||
default:
|
||||
result += innerIndent + fmt.Sprintf("???ArrayItem(%+v)", item)
|
||||
}
|
||||
if i < len(node.Content)-1 {
|
||||
result += ","
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
result += indent + "]"
|
||||
return result
|
||||
}
|
||||
|
||||
func renderStringArray(array []string, indent string) (result string) {
|
||||
result = "[\n"
|
||||
innerIndent := indent + indentation
|
||||
for i, item := range array {
|
||||
result += innerIndent + "\"" + item + "\""
|
||||
if i < len(array)-1 {
|
||||
result += ","
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
result += indent + "]"
|
||||
return result
|
||||
}
|
||||
|
||||
// Render renders a yaml.Node as JSON
|
||||
func Render(node *yaml.Node) string {
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
if len(node.Content) == 1 {
|
||||
return Render(node.Content[0])
|
||||
}
|
||||
} else if node.Kind == yaml.MappingNode {
|
||||
return renderMappingNode(node, "") + "\n"
|
||||
} else if node.Kind == yaml.SequenceNode {
|
||||
return renderSequenceNode(node, "") + "\n"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (object *SchemaNumber) nodeValue() *yaml.Node {
|
||||
if object.Integer != nil {
|
||||
return nodeForInt64(*object.Integer)
|
||||
} else if object.Float != nil {
|
||||
return nodeForFloat64(*object.Float)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaOrBoolean) nodeValue() *yaml.Node {
|
||||
if object.Schema != nil {
|
||||
return object.Schema.nodeValue()
|
||||
} else if object.Boolean != nil {
|
||||
return nodeForBoolean(*object.Boolean)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForStringArray(array []string) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, item := range array {
|
||||
content = append(content, nodeForString(item))
|
||||
}
|
||||
return nodeForSequence(content)
|
||||
}
|
||||
|
||||
func nodeForSchemaArray(array []*Schema) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, item := range array {
|
||||
content = append(content, item.nodeValue())
|
||||
}
|
||||
return nodeForSequence(content)
|
||||
}
|
||||
|
||||
func (object *StringOrStringArray) nodeValue() *yaml.Node {
|
||||
if object.String != nil {
|
||||
return nodeForString(*object.String)
|
||||
} else if object.StringArray != nil {
|
||||
return nodeForStringArray(*(object.StringArray))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaOrStringArray) nodeValue() *yaml.Node {
|
||||
if object.Schema != nil {
|
||||
return object.Schema.nodeValue()
|
||||
} else if object.StringArray != nil {
|
||||
return nodeForStringArray(*(object.StringArray))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaOrSchemaArray) nodeValue() *yaml.Node {
|
||||
if object.Schema != nil {
|
||||
return object.Schema.nodeValue()
|
||||
} else if object.SchemaArray != nil {
|
||||
return nodeForSchemaArray(*(object.SchemaArray))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (object *SchemaEnumValue) nodeValue() *yaml.Node {
|
||||
if object.String != nil {
|
||||
return nodeForString(*object.String)
|
||||
} else if object.Bool != nil {
|
||||
return nodeForBoolean(*object.Bool)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForNamedSchemaArray(array *[]*NamedSchema) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, pair := range *(array) {
|
||||
content = appendPair(content, pair.Name, pair.Value.nodeValue())
|
||||
}
|
||||
return nodeForMapping(content)
|
||||
}
|
||||
|
||||
func nodeForNamedSchemaOrStringArray(array *[]*NamedSchemaOrStringArray) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, pair := range *(array) {
|
||||
content = appendPair(content, pair.Name, pair.Value.nodeValue())
|
||||
}
|
||||
return nodeForMapping(content)
|
||||
}
|
||||
|
||||
func nodeForSchemaEnumArray(array *[]SchemaEnumValue) *yaml.Node {
|
||||
content := make([]*yaml.Node, 0)
|
||||
for _, item := range *array {
|
||||
content = append(content, item.nodeValue())
|
||||
}
|
||||
return nodeForSequence(content)
|
||||
}
|
||||
|
||||
func nodeForMapping(content []*yaml.Node) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.MappingNode,
|
||||
Content: content,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForSequence(content []*yaml.Node) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.SequenceNode,
|
||||
Content: content,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForString(value string) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!str",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForBoolean(value bool) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!bool",
|
||||
Value: fmt.Sprintf("%t", value),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForInt64(value int64) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!int",
|
||||
Value: fmt.Sprintf("%d", value),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeForFloat64(value float64) *yaml.Node {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!float",
|
||||
Value: fmt.Sprintf("%f", value),
|
||||
}
|
||||
}
|
||||
|
||||
func appendPair(nodes []*yaml.Node, name string, value *yaml.Node) []*yaml.Node {
|
||||
nodes = append(nodes, nodeForString(name))
|
||||
nodes = append(nodes, value)
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (schema *Schema) nodeValue() *yaml.Node {
|
||||
n := &yaml.Node{Kind: yaml.MappingNode}
|
||||
content := make([]*yaml.Node, 0)
|
||||
if schema.Title != nil {
|
||||
content = appendPair(content, "title", nodeForString(*schema.Title))
|
||||
}
|
||||
if schema.ID != nil {
|
||||
content = appendPair(content, "id", nodeForString(*schema.ID))
|
||||
}
|
||||
if schema.Schema != nil {
|
||||
content = appendPair(content, "$schema", nodeForString(*schema.Schema))
|
||||
}
|
||||
if schema.Type != nil {
|
||||
content = appendPair(content, "type", schema.Type.nodeValue())
|
||||
}
|
||||
if schema.Items != nil {
|
||||
content = appendPair(content, "items", schema.Items.nodeValue())
|
||||
}
|
||||
if schema.Description != nil {
|
||||
content = appendPair(content, "description", nodeForString(*schema.Description))
|
||||
}
|
||||
if schema.Required != nil {
|
||||
content = appendPair(content, "required", nodeForStringArray(*schema.Required))
|
||||
}
|
||||
if schema.AdditionalProperties != nil {
|
||||
content = appendPair(content, "additionalProperties", schema.AdditionalProperties.nodeValue())
|
||||
}
|
||||
if schema.PatternProperties != nil {
|
||||
content = appendPair(content, "patternProperties", nodeForNamedSchemaArray(schema.PatternProperties))
|
||||
}
|
||||
if schema.Properties != nil {
|
||||
content = appendPair(content, "properties", nodeForNamedSchemaArray(schema.Properties))
|
||||
}
|
||||
if schema.Dependencies != nil {
|
||||
content = appendPair(content, "dependencies", nodeForNamedSchemaOrStringArray(schema.Dependencies))
|
||||
}
|
||||
if schema.Ref != nil {
|
||||
content = appendPair(content, "$ref", nodeForString(*schema.Ref))
|
||||
}
|
||||
if schema.MultipleOf != nil {
|
||||
content = appendPair(content, "multipleOf", schema.MultipleOf.nodeValue())
|
||||
}
|
||||
if schema.Maximum != nil {
|
||||
content = appendPair(content, "maximum", schema.Maximum.nodeValue())
|
||||
}
|
||||
if schema.ExclusiveMaximum != nil {
|
||||
content = appendPair(content, "exclusiveMaximum", nodeForBoolean(*schema.ExclusiveMaximum))
|
||||
}
|
||||
if schema.Minimum != nil {
|
||||
content = appendPair(content, "minimum", schema.Minimum.nodeValue())
|
||||
}
|
||||
if schema.ExclusiveMinimum != nil {
|
||||
content = appendPair(content, "exclusiveMinimum", nodeForBoolean(*schema.ExclusiveMinimum))
|
||||
}
|
||||
if schema.MaxLength != nil {
|
||||
content = appendPair(content, "maxLength", nodeForInt64(*schema.MaxLength))
|
||||
}
|
||||
if schema.MinLength != nil {
|
||||
content = appendPair(content, "minLength", nodeForInt64(*schema.MinLength))
|
||||
}
|
||||
if schema.Pattern != nil {
|
||||
content = appendPair(content, "pattern", nodeForString(*schema.Pattern))
|
||||
}
|
||||
if schema.AdditionalItems != nil {
|
||||
content = appendPair(content, "additionalItems", schema.AdditionalItems.nodeValue())
|
||||
}
|
||||
if schema.MaxItems != nil {
|
||||
content = appendPair(content, "maxItems", nodeForInt64(*schema.MaxItems))
|
||||
}
|
||||
if schema.MinItems != nil {
|
||||
content = appendPair(content, "minItems", nodeForInt64(*schema.MinItems))
|
||||
}
|
||||
if schema.UniqueItems != nil {
|
||||
content = appendPair(content, "uniqueItems", nodeForBoolean(*schema.UniqueItems))
|
||||
}
|
||||
if schema.MaxProperties != nil {
|
||||
content = appendPair(content, "maxProperties", nodeForInt64(*schema.MaxProperties))
|
||||
}
|
||||
if schema.MinProperties != nil {
|
||||
content = appendPair(content, "minProperties", nodeForInt64(*schema.MinProperties))
|
||||
}
|
||||
if schema.Enumeration != nil {
|
||||
content = appendPair(content, "enum", nodeForSchemaEnumArray(schema.Enumeration))
|
||||
}
|
||||
if schema.AllOf != nil {
|
||||
content = appendPair(content, "allOf", nodeForSchemaArray(*schema.AllOf))
|
||||
}
|
||||
if schema.AnyOf != nil {
|
||||
content = appendPair(content, "anyOf", nodeForSchemaArray(*schema.AnyOf))
|
||||
}
|
||||
if schema.OneOf != nil {
|
||||
content = appendPair(content, "oneOf", nodeForSchemaArray(*schema.OneOf))
|
||||
}
|
||||
if schema.Not != nil {
|
||||
content = appendPair(content, "not", schema.Not.nodeValue())
|
||||
}
|
||||
if schema.Definitions != nil {
|
||||
content = appendPair(content, "definitions", nodeForNamedSchemaArray(schema.Definitions))
|
||||
}
|
||||
if schema.Default != nil {
|
||||
// m = append(m, yaml.MapItem{Key: "default", Value: *schema.Default})
|
||||
}
|
||||
if schema.Format != nil {
|
||||
content = appendPair(content, "format", nodeForString(*schema.Format))
|
||||
}
|
||||
n.Content = content
|
||||
return n
|
||||
}
|
||||
|
||||
// JSONString returns a json representation of a schema.
|
||||
func (schema *Schema) JSONString() string {
|
||||
node := schema.nodeValue()
|
||||
return Render(node)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user